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 23 static 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 */ 31 void __clk_init_enabled(struct clk *clk) 32 { 33 clk->enabled = 1; 34 clk->clk_ops->enable(clk); 35 } 36 37 void __clk_init_disabled(struct clk *clk) 38 { 39 clk->enabled = 0; 40 clk->clk_ops->disable(clk); 41 } 42 43 static void __clk_enable0(struct clk *clk) 44 { 45 __raw_writeb(clk->slot, MCFPM_PPMCR0); 46 } 47 48 static void __clk_disable0(struct clk *clk) 49 { 50 __raw_writeb(clk->slot, MCFPM_PPMSR0); 51 } 52 53 struct clk_ops clk_ops0 = { 54 .enable = __clk_enable0, 55 .disable = __clk_disable0, 56 }; 57 58 #ifdef MCFPM_PPMCR1 59 static void __clk_enable1(struct clk *clk) 60 { 61 __raw_writeb(clk->slot, MCFPM_PPMCR1); 62 } 63 64 static void __clk_disable1(struct clk *clk) 65 { 66 __raw_writeb(clk->slot, MCFPM_PPMSR1); 67 } 68 69 struct clk_ops clk_ops1 = { 70 .enable = __clk_enable1, 71 .disable = __clk_disable1, 72 }; 73 #endif /* MCFPM_PPMCR1 */ 74 #endif /* MCFPM_PPMCR0 */ 75 76 int clk_enable(struct clk *clk) 77 { 78 unsigned long flags; 79 80 if (!clk) 81 return -EINVAL; 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 } 90 EXPORT_SYMBOL(clk_enable); 91 92 void 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 } 104 EXPORT_SYMBOL(clk_disable); 105 106 unsigned long clk_get_rate(struct clk *clk) 107 { 108 if (!clk) 109 return 0; 110 111 return clk->rate; 112 } 113 EXPORT_SYMBOL(clk_get_rate); 114 115 /* dummy functions, should not be called */ 116 long clk_round_rate(struct clk *clk, unsigned long rate) 117 { 118 WARN_ON(clk); 119 return 0; 120 } 121 EXPORT_SYMBOL(clk_round_rate); 122 123 int clk_set_rate(struct clk *clk, unsigned long rate) 124 { 125 WARN_ON(clk); 126 return 0; 127 } 128 EXPORT_SYMBOL(clk_set_rate); 129 130 int clk_set_parent(struct clk *clk, struct clk *parent) 131 { 132 WARN_ON(clk); 133 return 0; 134 } 135 EXPORT_SYMBOL(clk_set_parent); 136 137 struct clk *clk_get_parent(struct clk *clk) 138 { 139 WARN_ON(clk); 140 return NULL; 141 } 142 EXPORT_SYMBOL(clk_get_parent); 143 144 /***************************************************************************/ 145