diff options
| author | Chao Xie <chao.xie@marvell.com> | 2012-08-19 22:55:11 -0400 |
|---|---|---|
| committer | Mike Turquette <mturquette@linaro.org> | 2012-08-28 17:14:14 -0400 |
| commit | 6b63f023184e34b404b96bb9a8c4ac6692ff3fbd (patch) | |
| tree | 1ad367ccdd9dcf6a87d2e30a32b910865ac14f52 /drivers | |
| parent | f9a6aa4303bd15bbdb24d9fe374e4e6850298460 (diff) | |
clk: mmp: add mmp specific clocks
add mmp specific clocks including apbc cloks, apmu clocks,
and pll2, fraction clocks
Signed-off-by: Chao Xie <xiechao.mail@gmail.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/clk/Makefile | 3 | ||||
| -rw-r--r-- | drivers/clk/mmp/Makefile | 5 | ||||
| -rw-r--r-- | drivers/clk/mmp/clk-apbc.c | 152 | ||||
| -rw-r--r-- | drivers/clk/mmp/clk-apmu.c | 97 | ||||
| -rw-r--r-- | drivers/clk/mmp/clk-frac.c | 153 | ||||
| -rw-r--r-- | drivers/clk/mmp/clk.h | 35 |
6 files changed, 445 insertions, 0 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index e30376c4ff5d..fa5e1d210b84 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
| @@ -11,6 +11,9 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/ | |||
| 11 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 11 | obj-$(CONFIG_ARCH_U300) += clk-u300.o |
| 12 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ | 12 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ |
| 13 | obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o | 13 | obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o |
| 14 | ifeq ($(CONFIG_COMMON_CLK), y) | ||
| 15 | obj-$(CONFIG_ARCH_MMP) += mmp/ | ||
| 16 | endif | ||
| 14 | 17 | ||
| 15 | # Chip specific | 18 | # Chip specific |
| 16 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | 19 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o |
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile new file mode 100644 index 000000000000..b5bc88cc8967 --- /dev/null +++ b/drivers/clk/mmp/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for mmp specific clk | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y += clk-apbc.o clk-apmu.o clk-frac.o | ||
diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c new file mode 100644 index 000000000000..d14120eaa71f --- /dev/null +++ b/drivers/clk/mmp/clk-apbc.c | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /* | ||
| 2 | * mmp APB clock operation source file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Marvell | ||
| 5 | * Chao Xie <xiechao.mail@gmail.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | |||
| 19 | #include "clk.h" | ||
| 20 | |||
| 21 | /* Common APB clock register bit definitions */ | ||
| 22 | #define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */ | ||
| 23 | #define APBC_FNCLK (1 << 1) /* Functional Clock Enable */ | ||
| 24 | #define APBC_RST (1 << 2) /* Reset Generation */ | ||
| 25 | #define APBC_POWER (1 << 7) /* Reset Generation */ | ||
| 26 | |||
| 27 | #define to_clk_apbc(hw) container_of(hw, struct clk_apbc, hw) | ||
| 28 | struct clk_apbc { | ||
| 29 | struct clk_hw hw; | ||
| 30 | void __iomem *base; | ||
| 31 | unsigned int delay; | ||
| 32 | unsigned int flags; | ||
| 33 | spinlock_t *lock; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int clk_apbc_prepare(struct clk_hw *hw) | ||
| 37 | { | ||
| 38 | struct clk_apbc *apbc = to_clk_apbc(hw); | ||
| 39 | unsigned int data; | ||
| 40 | unsigned long flags = 0; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * It may share same register as MUX clock, | ||
| 44 | * and it will impact FNCLK enable. Spinlock is needed | ||
| 45 | */ | ||
| 46 | if (apbc->lock) | ||
| 47 | spin_lock_irqsave(apbc->lock, flags); | ||
| 48 | |||
| 49 | data = readl_relaxed(apbc->base); | ||
| 50 | if (apbc->flags & APBC_POWER_CTRL) | ||
| 51 | data |= APBC_POWER; | ||
| 52 | data |= APBC_FNCLK; | ||
| 53 | writel_relaxed(data, apbc->base); | ||
| 54 | |||
| 55 | if (apbc->lock) | ||
| 56 | spin_unlock_irqrestore(apbc->lock, flags); | ||
| 57 | |||
| 58 | udelay(apbc->delay); | ||
| 59 | |||
| 60 | if (apbc->lock) | ||
| 61 | spin_lock_irqsave(apbc->lock, flags); | ||
| 62 | |||
| 63 | data = readl_relaxed(apbc->base); | ||
| 64 | data |= APBC_APBCLK; | ||
| 65 | writel_relaxed(data, apbc->base); | ||
| 66 | |||
| 67 | if (apbc->lock) | ||
| 68 | spin_unlock_irqrestore(apbc->lock, flags); | ||
| 69 | |||
| 70 | udelay(apbc->delay); | ||
| 71 | |||
| 72 | if (!(apbc->flags & APBC_NO_BUS_CTRL)) { | ||
| 73 | if (apbc->lock) | ||
| 74 | spin_lock_irqsave(apbc->lock, flags); | ||
| 75 | |||
| 76 | data = readl_relaxed(apbc->base); | ||
| 77 | data &= ~APBC_RST; | ||
| 78 | writel_relaxed(data, apbc->base); | ||
| 79 | |||
| 80 | if (apbc->lock) | ||
| 81 | spin_unlock_irqrestore(apbc->lock, flags); | ||
| 82 | } | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | static void clk_apbc_unprepare(struct clk_hw *hw) | ||
| 88 | { | ||
| 89 | struct clk_apbc *apbc = to_clk_apbc(hw); | ||
| 90 | unsigned long data; | ||
| 91 | unsigned long flags = 0; | ||
| 92 | |||
| 93 | if (apbc->lock) | ||
| 94 | spin_lock_irqsave(apbc->lock, flags); | ||
| 95 | |||
| 96 | data = readl_relaxed(apbc->base); | ||
| 97 | if (apbc->flags & APBC_POWER_CTRL) | ||
| 98 | data &= ~APBC_POWER; | ||
| 99 | data &= ~APBC_FNCLK; | ||
| 100 | writel_relaxed(data, apbc->base); | ||
| 101 | |||
| 102 | if (apbc->lock) | ||
| 103 | spin_unlock_irqrestore(apbc->lock, flags); | ||
| 104 | |||
| 105 | udelay(10); | ||
| 106 | |||
| 107 | if (apbc->lock) | ||
| 108 | spin_lock_irqsave(apbc->lock, flags); | ||
| 109 | |||
| 110 | data = readl_relaxed(apbc->base); | ||
| 111 | data &= ~APBC_APBCLK; | ||
| 112 | writel_relaxed(data, apbc->base); | ||
| 113 | |||
| 114 | if (apbc->lock) | ||
| 115 | spin_unlock_irqrestore(apbc->lock, flags); | ||
| 116 | } | ||
| 117 | |||
| 118 | struct clk_ops clk_apbc_ops = { | ||
| 119 | .prepare = clk_apbc_prepare, | ||
| 120 | .unprepare = clk_apbc_unprepare, | ||
| 121 | }; | ||
| 122 | |||
| 123 | struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name, | ||
| 124 | void __iomem *base, unsigned int delay, | ||
| 125 | unsigned int apbc_flags, spinlock_t *lock) | ||
| 126 | { | ||
| 127 | struct clk_apbc *apbc; | ||
| 128 | struct clk *clk; | ||
| 129 | struct clk_init_data init; | ||
| 130 | |||
| 131 | apbc = kzalloc(sizeof(*apbc), GFP_KERNEL); | ||
| 132 | if (!apbc) | ||
| 133 | return NULL; | ||
| 134 | |||
| 135 | init.name = name; | ||
| 136 | init.ops = &clk_apbc_ops; | ||
| 137 | init.flags = CLK_SET_RATE_PARENT; | ||
| 138 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
| 139 | init.num_parents = (parent_name ? 1 : 0); | ||
| 140 | |||
| 141 | apbc->base = base; | ||
| 142 | apbc->delay = delay; | ||
| 143 | apbc->flags = apbc_flags; | ||
| 144 | apbc->lock = lock; | ||
| 145 | apbc->hw.init = &init; | ||
| 146 | |||
| 147 | clk = clk_register(NULL, &apbc->hw); | ||
| 148 | if (IS_ERR(clk)) | ||
| 149 | kfree(apbc); | ||
| 150 | |||
| 151 | return clk; | ||
| 152 | } | ||
diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c new file mode 100644 index 000000000000..abe182b2377f --- /dev/null +++ b/drivers/clk/mmp/clk-apmu.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* | ||
| 2 | * mmp AXI peripharal clock operation source file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Marvell | ||
| 5 | * Chao Xie <xiechao.mail@gmail.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | |||
| 19 | #include "clk.h" | ||
| 20 | |||
| 21 | #define to_clk_apmu(clk) (container_of(clk, struct clk_apmu, clk)) | ||
| 22 | struct clk_apmu { | ||
| 23 | struct clk_hw hw; | ||
| 24 | void __iomem *base; | ||
| 25 | u32 rst_mask; | ||
| 26 | u32 enable_mask; | ||
| 27 | spinlock_t *lock; | ||
| 28 | }; | ||
| 29 | |||
| 30 | static int clk_apmu_enable(struct clk_hw *hw) | ||
| 31 | { | ||
| 32 | struct clk_apmu *apmu = to_clk_apmu(hw); | ||
| 33 | unsigned long data; | ||
| 34 | unsigned long flags = 0; | ||
| 35 | |||
| 36 | if (apmu->lock) | ||
| 37 | spin_lock_irqsave(apmu->lock, flags); | ||
| 38 | |||
| 39 | data = readl_relaxed(apmu->base) | apmu->enable_mask; | ||
| 40 | writel_relaxed(data, apmu->base); | ||
| 41 | |||
| 42 | if (apmu->lock) | ||
| 43 | spin_unlock_irqrestore(apmu->lock, flags); | ||
| 44 | |||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | static void clk_apmu_disable(struct clk_hw *hw) | ||
| 49 | { | ||
| 50 | struct clk_apmu *apmu = to_clk_apmu(hw); | ||
| 51 | unsigned long data; | ||
| 52 | unsigned long flags = 0; | ||
| 53 | |||
| 54 | if (apmu->lock) | ||
| 55 | spin_lock_irqsave(apmu->lock, flags); | ||
| 56 | |||
| 57 | data = readl_relaxed(apmu->base) & ~apmu->enable_mask; | ||
| 58 | writel_relaxed(data, apmu->base); | ||
| 59 | |||
| 60 | if (apmu->lock) | ||
| 61 | spin_unlock_irqrestore(apmu->lock, flags); | ||
| 62 | } | ||
| 63 | |||
| 64 | struct clk_ops clk_apmu_ops = { | ||
| 65 | .enable = clk_apmu_enable, | ||
| 66 | .disable = clk_apmu_disable, | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name, | ||
| 70 | void __iomem *base, u32 enable_mask, spinlock_t *lock) | ||
| 71 | { | ||
| 72 | struct clk_apmu *apmu; | ||
| 73 | struct clk *clk; | ||
| 74 | struct clk_init_data init; | ||
| 75 | |||
| 76 | apmu = kzalloc(sizeof(*apmu), GFP_KERNEL); | ||
| 77 | if (!apmu) | ||
| 78 | return NULL; | ||
| 79 | |||
| 80 | init.name = name; | ||
| 81 | init.ops = &clk_apmu_ops; | ||
| 82 | init.flags = CLK_SET_RATE_PARENT; | ||
| 83 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
| 84 | init.num_parents = (parent_name ? 1 : 0); | ||
| 85 | |||
| 86 | apmu->base = base; | ||
| 87 | apmu->enable_mask = enable_mask; | ||
| 88 | apmu->lock = lock; | ||
| 89 | apmu->hw.init = &init; | ||
| 90 | |||
| 91 | clk = clk_register(NULL, &apmu->hw); | ||
| 92 | |||
| 93 | if (IS_ERR(clk)) | ||
| 94 | kfree(apmu); | ||
| 95 | |||
| 96 | return clk; | ||
| 97 | } | ||
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c new file mode 100644 index 000000000000..80c1dd15d15c --- /dev/null +++ b/drivers/clk/mmp/clk-frac.c | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /* | ||
| 2 | * mmp factor clock operation source file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Marvell | ||
| 5 | * Chao Xie <xiechao.mail@gmail.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/clk-provider.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | |||
| 17 | #include "clk.h" | ||
| 18 | /* | ||
| 19 | * It is M/N clock | ||
| 20 | * | ||
| 21 | * Fout from synthesizer can be given from two equations: | ||
| 22 | * numerator/denominator = Fin / (Fout * factor) | ||
| 23 | */ | ||
| 24 | |||
| 25 | #define to_clk_factor(hw) container_of(hw, struct clk_factor, hw) | ||
| 26 | struct clk_factor { | ||
| 27 | struct clk_hw hw; | ||
| 28 | void __iomem *base; | ||
| 29 | struct clk_factor_masks *masks; | ||
| 30 | struct clk_factor_tbl *ftbl; | ||
| 31 | unsigned int ftbl_cnt; | ||
| 32 | }; | ||
| 33 | |||
| 34 | static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, | ||
| 35 | unsigned long *prate) | ||
| 36 | { | ||
| 37 | struct clk_factor *factor = to_clk_factor(hw); | ||
| 38 | unsigned long rate = 0, prev_rate; | ||
| 39 | int i; | ||
| 40 | |||
| 41 | for (i = 0; i < factor->ftbl_cnt; i++) { | ||
| 42 | prev_rate = rate; | ||
| 43 | rate = (((*prate / 10000) * factor->ftbl[i].num) / | ||
| 44 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | ||
| 45 | if (rate > drate) | ||
| 46 | break; | ||
| 47 | } | ||
| 48 | if (i == 0) | ||
| 49 | return rate; | ||
| 50 | else | ||
| 51 | return prev_rate; | ||
| 52 | } | ||
| 53 | |||
| 54 | static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, | ||
| 55 | unsigned long parent_rate) | ||
| 56 | { | ||
| 57 | struct clk_factor *factor = to_clk_factor(hw); | ||
| 58 | struct clk_factor_masks *masks = factor->masks; | ||
| 59 | unsigned int val, num, den; | ||
| 60 | |||
| 61 | val = readl_relaxed(factor->base); | ||
| 62 | |||
| 63 | /* calculate numerator */ | ||
| 64 | num = (val >> masks->num_shift) & masks->num_mask; | ||
| 65 | |||
| 66 | /* calculate denominator */ | ||
| 67 | den = (val >> masks->den_shift) & masks->num_mask; | ||
| 68 | |||
| 69 | if (!den) | ||
| 70 | return 0; | ||
| 71 | |||
| 72 | return (((parent_rate / 10000) * den) / | ||
| 73 | (num * factor->masks->factor)) * 10000; | ||
| 74 | } | ||
| 75 | |||
| 76 | /* Configures new clock rate*/ | ||
| 77 | static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | ||
| 78 | unsigned long prate) | ||
| 79 | { | ||
| 80 | struct clk_factor *factor = to_clk_factor(hw); | ||
| 81 | struct clk_factor_masks *masks = factor->masks; | ||
| 82 | int i; | ||
| 83 | unsigned long val; | ||
| 84 | unsigned long prev_rate, rate = 0; | ||
| 85 | |||
| 86 | for (i = 0; i < factor->ftbl_cnt; i++) { | ||
| 87 | prev_rate = rate; | ||
| 88 | rate = (((prate / 10000) * factor->ftbl[i].num) / | ||
| 89 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | ||
| 90 | if (rate > drate) | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | if (i > 0) | ||
| 94 | i--; | ||
| 95 | |||
| 96 | val = readl_relaxed(factor->base); | ||
| 97 | |||
| 98 | val &= ~(masks->num_mask << masks->num_shift); | ||
| 99 | val |= (factor->ftbl[i].num & masks->num_mask) << masks->num_shift; | ||
| 100 | |||
| 101 | val &= ~(masks->den_mask << masks->den_shift); | ||
| 102 | val |= (factor->ftbl[i].den & masks->den_mask) << masks->den_shift; | ||
| 103 | |||
| 104 | writel_relaxed(val, factor->base); | ||
| 105 | |||
| 106 | return 0; | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct clk_ops clk_factor_ops = { | ||
| 110 | .recalc_rate = clk_factor_recalc_rate, | ||
| 111 | .round_rate = clk_factor_round_rate, | ||
| 112 | .set_rate = clk_factor_set_rate, | ||
| 113 | }; | ||
| 114 | |||
| 115 | struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, | ||
| 116 | unsigned long flags, void __iomem *base, | ||
| 117 | struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl, | ||
| 118 | unsigned int ftbl_cnt) | ||
| 119 | { | ||
| 120 | struct clk_factor *factor; | ||
| 121 | struct clk_init_data init; | ||
| 122 | struct clk *clk; | ||
| 123 | |||
| 124 | if (!masks) { | ||
| 125 | pr_err("%s: must pass a clk_factor_mask\n", __func__); | ||
| 126 | return ERR_PTR(-EINVAL); | ||
| 127 | } | ||
| 128 | |||
| 129 | factor = kzalloc(sizeof(*factor), GFP_KERNEL); | ||
| 130 | if (!factor) { | ||
| 131 | pr_err("%s: could not allocate factor clk\n", __func__); | ||
| 132 | return ERR_PTR(-ENOMEM); | ||
| 133 | } | ||
| 134 | |||
| 135 | /* struct clk_aux assignments */ | ||
| 136 | factor->base = base; | ||
| 137 | factor->masks = masks; | ||
| 138 | factor->ftbl = ftbl; | ||
| 139 | factor->ftbl_cnt = ftbl_cnt; | ||
| 140 | factor->hw.init = &init; | ||
| 141 | |||
| 142 | init.name = name; | ||
| 143 | init.ops = &clk_factor_ops; | ||
| 144 | init.flags = flags; | ||
| 145 | init.parent_names = &parent_name; | ||
| 146 | init.num_parents = 1; | ||
| 147 | |||
| 148 | clk = clk_register(NULL, &factor->hw); | ||
| 149 | if (IS_ERR_OR_NULL(clk)) | ||
| 150 | kfree(factor); | ||
| 151 | |||
| 152 | return clk; | ||
| 153 | } | ||
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h new file mode 100644 index 000000000000..ab86dd4a416a --- /dev/null +++ b/drivers/clk/mmp/clk.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | #ifndef __MACH_MMP_CLK_H | ||
| 2 | #define __MACH_MMP_CLK_H | ||
| 3 | |||
| 4 | #include <linux/clk-provider.h> | ||
| 5 | #include <linux/clkdev.h> | ||
| 6 | |||
| 7 | #define APBC_NO_BUS_CTRL BIT(0) | ||
| 8 | #define APBC_POWER_CTRL BIT(1) | ||
| 9 | |||
| 10 | struct clk_factor_masks { | ||
| 11 | unsigned int factor; | ||
| 12 | unsigned int num_mask; | ||
| 13 | unsigned int den_mask; | ||
| 14 | unsigned int num_shift; | ||
| 15 | unsigned int den_shift; | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct clk_factor_tbl { | ||
| 19 | unsigned int num; | ||
| 20 | unsigned int den; | ||
| 21 | }; | ||
| 22 | |||
| 23 | extern struct clk *mmp_clk_register_pll2(const char *name, | ||
| 24 | const char *parent_name, unsigned long flags); | ||
| 25 | extern struct clk *mmp_clk_register_apbc(const char *name, | ||
| 26 | const char *parent_name, void __iomem *base, | ||
| 27 | unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); | ||
| 28 | extern struct clk *mmp_clk_register_apmu(const char *name, | ||
| 29 | const char *parent_name, void __iomem *base, u32 enable_mask, | ||
| 30 | spinlock_t *lock); | ||
| 31 | extern struct clk *mmp_clk_register_factor(const char *name, | ||
| 32 | const char *parent_name, unsigned long flags, | ||
| 33 | void __iomem *base, struct clk_factor_masks *masks, | ||
| 34 | struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt); | ||
| 35 | #endif | ||
