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