clk.c (2854B)
1// SPDX-License-Identifier: GPL-2.0 2/***************************************************************************/ 3 4/* 5 * clk.c -- general ColdFire CPU kernel clk handling 6 * 7 * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) 8 */ 9 10/***************************************************************************/ 11 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/platform_device.h> 15#include <linux/mutex.h> 16#include <linux/clk.h> 17#include <linux/io.h> 18#include <linux/err.h> 19#include <asm/coldfire.h> 20#include <asm/mcfsim.h> 21#include <asm/mcfclk.h> 22 23static DEFINE_SPINLOCK(clk_lock); 24 25#ifdef MCFPM_PPMCR0 26/* 27 * For more advanced ColdFire parts that have clocks that can be enabled 28 * we supply enable/disable functions. These must properly define their 29 * clocks in their platform specific code. 30 */ 31void __clk_init_enabled(struct clk *clk) 32{ 33 clk->enabled = 1; 34 clk->clk_ops->enable(clk); 35} 36 37void __clk_init_disabled(struct clk *clk) 38{ 39 clk->enabled = 0; 40 clk->clk_ops->disable(clk); 41} 42 43static void __clk_enable0(struct clk *clk) 44{ 45 __raw_writeb(clk->slot, MCFPM_PPMCR0); 46} 47 48static void __clk_disable0(struct clk *clk) 49{ 50 __raw_writeb(clk->slot, MCFPM_PPMSR0); 51} 52 53struct clk_ops clk_ops0 = { 54 .enable = __clk_enable0, 55 .disable = __clk_disable0, 56}; 57 58#ifdef MCFPM_PPMCR1 59static void __clk_enable1(struct clk *clk) 60{ 61 __raw_writeb(clk->slot, MCFPM_PPMCR1); 62} 63 64static void __clk_disable1(struct clk *clk) 65{ 66 __raw_writeb(clk->slot, MCFPM_PPMSR1); 67} 68 69struct clk_ops clk_ops1 = { 70 .enable = __clk_enable1, 71 .disable = __clk_disable1, 72}; 73#endif /* MCFPM_PPMCR1 */ 74#endif /* MCFPM_PPMCR0 */ 75 76int clk_enable(struct clk *clk) 77{ 78 unsigned long flags; 79 80 if (!clk) 81 return 0; 82 83 spin_lock_irqsave(&clk_lock, flags); 84 if ((clk->enabled++ == 0) && clk->clk_ops) 85 clk->clk_ops->enable(clk); 86 spin_unlock_irqrestore(&clk_lock, flags); 87 88 return 0; 89} 90EXPORT_SYMBOL(clk_enable); 91 92void clk_disable(struct clk *clk) 93{ 94 unsigned long flags; 95 96 if (!clk) 97 return; 98 99 spin_lock_irqsave(&clk_lock, flags); 100 if ((--clk->enabled == 0) && clk->clk_ops) 101 clk->clk_ops->disable(clk); 102 spin_unlock_irqrestore(&clk_lock, flags); 103} 104EXPORT_SYMBOL(clk_disable); 105 106unsigned long clk_get_rate(struct clk *clk) 107{ 108 if (!clk) 109 return 0; 110 111 return clk->rate; 112} 113EXPORT_SYMBOL(clk_get_rate); 114 115/* dummy functions, should not be called */ 116long clk_round_rate(struct clk *clk, unsigned long rate) 117{ 118 WARN_ON(clk); 119 return 0; 120} 121EXPORT_SYMBOL(clk_round_rate); 122 123int clk_set_rate(struct clk *clk, unsigned long rate) 124{ 125 WARN_ON(clk); 126 return 0; 127} 128EXPORT_SYMBOL(clk_set_rate); 129 130int clk_set_parent(struct clk *clk, struct clk *parent) 131{ 132 WARN_ON(clk); 133 return 0; 134} 135EXPORT_SYMBOL(clk_set_parent); 136 137struct clk *clk_get_parent(struct clk *clk) 138{ 139 WARN_ON(clk); 140 return NULL; 141} 142EXPORT_SYMBOL(clk_get_parent); 143 144/***************************************************************************/