aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r--arch/sh/kernel/cpu/Makefile2
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c312
-rw-r--r--arch/sh/kernel/cpu/clock.c630
-rw-r--r--arch/sh/kernel/cpu/hwblk.c5
-rw-r--r--arch/sh/kernel/cpu/init.c24
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c5
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c6
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c4
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c9
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c9
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c12
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c15
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c4
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c9
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c9
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c9
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c24
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c17
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c4
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c9
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c15
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c9
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c231
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c210
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c177
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c279
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c295
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c11
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c176
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c223
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c13
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c16
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c13
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c21
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c27
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c81
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c18
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c27
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c24
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c30
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c157
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c18
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c74
-rw-r--r--arch/sh/kernel/cpu/sh5/probe.c4
-rw-r--r--arch/sh/kernel/cpu/sh5/setup-sh5.c9
48 files changed, 1457 insertions, 1849 deletions
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 0e48bc61c27..4edcb60a135 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
# Common interfaces.
obj-$(CONFIG_SH_ADC) += adc.o
-obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o
+obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_SH_FPU_EMU) += fpu.o
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index eed5eaff96b..e2f63d68da5 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -2,317 +2,25 @@
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <asm/clkdev.h>
#include <asm/clock.h>
-static int sh_clk_mstp32_enable(struct clk *clk)
-{
- __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
- clk->enable_reg);
- return 0;
-}
-
-static void sh_clk_mstp32_disable(struct clk *clk)
-{
- __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
- clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_mstp32_clk_ops = {
- .enable = sh_clk_mstp32_enable,
- .disable = sh_clk_mstp32_disable,
- .recalc = followparent_recalc,
-};
-
-int __init sh_clk_mstp32_register(struct clk *clks, int nr)
-{
- struct clk *clkp;
- int ret = 0;
- int k;
-
- for (k = 0; !ret && (k < nr); k++) {
- clkp = clks + k;
- clkp->ops = &sh_clk_mstp32_clk_ops;
- ret |= clk_register(clkp);
- }
-
- return ret;
-}
-
-static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
-{
- return clk_rate_table_round(clk, clk->freq_table, rate);
-}
-
-static int sh_clk_div6_divisors[64] = {
- 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
-};
-
-static struct clk_div_mult_table sh_clk_div6_table = {
- .divisors = sh_clk_div6_divisors,
- .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
-};
-
-static unsigned long sh_clk_div6_recalc(struct clk *clk)
-{
- struct clk_div_mult_table *table = &sh_clk_div6_table;
- unsigned int idx;
-
- clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
- table, NULL);
-
- idx = __raw_readl(clk->enable_reg) & 0x003f;
-
- return clk->freq_table[idx].frequency;
-}
-
-static int sh_clk_div6_set_rate(struct clk *clk,
- unsigned long rate, int algo_id)
-{
- unsigned long value;
- int idx;
-
- idx = clk_rate_table_find(clk, clk->freq_table, rate);
- if (idx < 0)
- return idx;
-
- value = __raw_readl(clk->enable_reg);
- value &= ~0x3f;
- value |= idx;
- __raw_writel(value, clk->enable_reg);
- return 0;
-}
-
-static int sh_clk_div6_enable(struct clk *clk)
-{
- unsigned long value;
- int ret;
-
- ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
- if (ret == 0) {
- value = __raw_readl(clk->enable_reg);
- value &= ~0x100; /* clear stop bit to enable clock */
- __raw_writel(value, clk->enable_reg);
- }
- return ret;
-}
-
-static void sh_clk_div6_disable(struct clk *clk)
-{
- unsigned long value;
-
- value = __raw_readl(clk->enable_reg);
- value |= 0x100; /* stop clock */
- value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
- __raw_writel(value, clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_div6_clk_ops = {
- .recalc = sh_clk_div6_recalc,
- .round_rate = sh_clk_div_round_rate,
- .set_rate = sh_clk_div6_set_rate,
- .enable = sh_clk_div6_enable,
- .disable = sh_clk_div6_disable,
-};
-
-int __init sh_clk_div6_register(struct clk *clks, int nr)
-{
- struct clk *clkp;
- void *freq_table;
- int nr_divs = sh_clk_div6_table.nr_divisors;
- int freq_table_size = sizeof(struct cpufreq_frequency_table);
- int ret = 0;
- int k;
-
- freq_table_size *= (nr_divs + 1);
- freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
- if (!freq_table) {
- pr_err("sh_clk_div6_register: unable to alloc memory\n");
- return -ENOMEM;
- }
-
- for (k = 0; !ret && (k < nr); k++) {
- clkp = clks + k;
-
- clkp->ops = &sh_clk_div6_clk_ops;
- clkp->id = -1;
- clkp->freq_table = freq_table + (k * freq_table_size);
- clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
-
- ret = clk_register(clkp);
- }
-
- return ret;
-}
-
-static unsigned long sh_clk_div4_recalc(struct clk *clk)
-{
- struct clk_div4_table *d4t = clk->priv;
- struct clk_div_mult_table *table = d4t->div_mult_table;
- unsigned int idx;
-
- clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
- table, &clk->arch_flags);
-
- idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
-
- return clk->freq_table[idx].frequency;
-}
-
-static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
-{
- struct clk_div4_table *d4t = clk->priv;
- struct clk_div_mult_table *table = d4t->div_mult_table;
- u32 value;
- int ret;
-
- if (!strcmp("pll_clk", parent->name))
- value = __raw_readl(clk->enable_reg) & ~(1 << 7);
- else
- value = __raw_readl(clk->enable_reg) | (1 << 7);
-
- ret = clk_reparent(clk, parent);
- if (ret < 0)
- return ret;
-
- __raw_writel(value, clk->enable_reg);
-
- /* Rebiuld the frequency table */
- clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
- table, &clk->arch_flags);
-
- return 0;
-}
-
-static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
-{
- struct clk_div4_table *d4t = clk->priv;
- unsigned long value;
- int idx = clk_rate_table_find(clk, clk->freq_table, rate);
- if (idx < 0)
- return idx;
-
- value = __raw_readl(clk->enable_reg);
- value &= ~(0xf << clk->enable_bit);
- value |= (idx << clk->enable_bit);
- __raw_writel(value, clk->enable_reg);
-
- if (d4t->kick)
- d4t->kick(clk);
-
- return 0;
-}
-
-static int sh_clk_div4_enable(struct clk *clk)
-{
- __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
- return 0;
-}
-
-static void sh_clk_div4_disable(struct clk *clk)
-{
- __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_div4_clk_ops = {
- .recalc = sh_clk_div4_recalc,
- .set_rate = sh_clk_div4_set_rate,
- .round_rate = sh_clk_div_round_rate,
-};
-
-static struct clk_ops sh_clk_div4_enable_clk_ops = {
- .recalc = sh_clk_div4_recalc,
- .set_rate = sh_clk_div4_set_rate,
- .round_rate = sh_clk_div_round_rate,
- .enable = sh_clk_div4_enable,
- .disable = sh_clk_div4_disable,
-};
-
-static struct clk_ops sh_clk_div4_reparent_clk_ops = {
- .recalc = sh_clk_div4_recalc,
- .set_rate = sh_clk_div4_set_rate,
- .round_rate = sh_clk_div_round_rate,
- .enable = sh_clk_div4_enable,
- .disable = sh_clk_div4_disable,
- .set_parent = sh_clk_div4_set_parent,
-};
-
-static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
- struct clk_div4_table *table, struct clk_ops *ops)
-{
- struct clk *clkp;
- void *freq_table;
- int nr_divs = table->div_mult_table->nr_divisors;
- int freq_table_size = sizeof(struct cpufreq_frequency_table);
- int ret = 0;
- int k;
-
- freq_table_size *= (nr_divs + 1);
- freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
- if (!freq_table) {
- pr_err("sh_clk_div4_register: unable to alloc memory\n");
- return -ENOMEM;
- }
-
- for (k = 0; !ret && (k < nr); k++) {
- clkp = clks + k;
-
- clkp->ops = ops;
- clkp->id = -1;
- clkp->priv = table;
-
- clkp->freq_table = freq_table + (k * freq_table_size);
- clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
-
- ret = clk_register(clkp);
- }
-
- return ret;
-}
-
-int __init sh_clk_div4_register(struct clk *clks, int nr,
- struct clk_div4_table *table)
-{
- return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
-}
-
-int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
- struct clk_div4_table *table)
-{
- return sh_clk_div4_register_ops(clks, nr, table,
- &sh_clk_div4_enable_clk_ops);
-}
-
-int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
- struct clk_div4_table *table)
-{
- return sh_clk_div4_register_ops(clks, nr, table,
- &sh_clk_div4_reparent_clk_ops);
-}
-
-#ifdef CONFIG_SH_CLK_CPG_LEGACY
static struct clk master_clk = {
- .name = "master_clk",
.flags = CLK_ENABLE_ON_INIT,
.rate = CONFIG_SH_PCLK_FREQ,
};
static struct clk peripheral_clk = {
- .name = "peripheral_clk",
.parent = &master_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk bus_clk = {
- .name = "bus_clk",
.parent = &master_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk cpu_clk = {
- .name = "cpu_clk",
.parent = &master_clk,
.flags = CLK_ENABLE_ON_INIT,
};
@@ -327,6 +35,16 @@ static struct clk *onchip_clocks[] = {
&cpu_clk,
};
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("master_clk", &master_clk),
+ CLKDEV_CON_ID("peripheral_clk", &peripheral_clk),
+ CLKDEV_CON_ID("bus_clk", &bus_clk),
+ CLKDEV_CON_ID("cpu_clk", &cpu_clk),
+};
+
int __init __deprecated cpg_clk_init(void)
{
int i, ret = 0;
@@ -338,6 +56,13 @@ int __init __deprecated cpg_clk_init(void)
ret |= clk_register(clk);
}
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL);
+ clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL);
+ clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL);
+ clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
+
return ret;
}
@@ -349,4 +74,3 @@ int __init __weak arch_clk_init(void)
{
return cpg_clk_init();
}
-#endif /* CONFIG_SH_CPG_CLK_LEGACY */
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index e9fa1bfed53..50f887dda56 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -10,558 +10,16 @@
*
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
*
- * With clkdev bits:
- *
- * Copyright (C) 2008 Russell King.
- *
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/kobject.h>
-#include <linux/sysdev.h>
-#include <linux/seq_file.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <linux/cpufreq.h>
+#include <linux/clk.h>
#include <asm/clock.h>
#include <asm/machvec.h>
-static LIST_HEAD(clock_list);
-static DEFINE_SPINLOCK(clock_lock);
-static DEFINE_MUTEX(clock_list_sem);
-
-void clk_rate_table_build(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- int nr_freqs,
- struct clk_div_mult_table *src_table,
- unsigned long *bitmap)
-{
- unsigned long mult, div;
- unsigned long freq;
- int i;
-
- for (i = 0; i < nr_freqs; i++) {
- div = 1;
- mult = 1;
-
- if (src_table->divisors && i < src_table->nr_divisors)
- div = src_table->divisors[i];
-
- if (src_table->multipliers && i < src_table->nr_multipliers)
- mult = src_table->multipliers[i];
-
- if (!div || !mult || (bitmap && !test_bit(i, bitmap)))
- freq = CPUFREQ_ENTRY_INVALID;
- else
- freq = clk->parent->rate * mult / div;
-
- freq_table[i].index = i;
- freq_table[i].frequency = freq;
- }
-
- /* Termination entry */
- freq_table[i].index = i;
- freq_table[i].frequency = CPUFREQ_TABLE_END;
-}
-
-long clk_rate_table_round(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- unsigned long rate)
-{
- unsigned long rate_error, rate_error_prev = ~0UL;
- unsigned long rate_best_fit = rate;
- unsigned long highest, lowest;
- int i;
-
- highest = lowest = 0;
-
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned long freq = freq_table[i].frequency;
-
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
-
- if (freq > highest)
- highest = freq;
- if (freq < lowest)
- lowest = freq;
-
- rate_error = abs(freq - rate);
- if (rate_error < rate_error_prev) {
- rate_best_fit = freq;
- rate_error_prev = rate_error;
- }
-
- if (rate_error == 0)
- break;
- }
-
- if (rate >= highest)
- rate_best_fit = highest;
- if (rate <= lowest)
- rate_best_fit = lowest;
-
- return rate_best_fit;
-}
-
-int clk_rate_table_find(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- unsigned long rate)
-{
- int i;
-
- for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
- unsigned long freq = freq_table[i].frequency;
-
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
-
- if (freq == rate)
- return i;
- }
-
- return -ENOENT;
-}
-
-/* Used for clocks that always have same value as the parent clock */
-unsigned long followparent_recalc(struct clk *clk)
-{
- return clk->parent ? clk->parent->rate : 0;
-}
-
-int clk_reparent(struct clk *child, struct clk *parent)
-{
- list_del_init(&child->sibling);
- if (parent)
- list_add(&child->sibling, &parent->children);
- child->parent = parent;
-
- /* now do the debugfs renaming to reattach the child
- to the proper parent */
-
- return 0;
-}
-
-/* Propagate rate to children */
-void propagate_rate(struct clk *tclk)
-{
- struct clk *clkp;
-
- list_for_each_entry(clkp, &tclk->children, sibling) {
- if (clkp->ops && clkp->ops->recalc)
- clkp->rate = clkp->ops->recalc(clkp);
-
- propagate_rate(clkp);
- }
-}
-
-static void __clk_disable(struct clk *clk)
-{
- if (clk->usecount == 0) {
- printk(KERN_ERR "Trying disable clock %s with 0 usecount\n",
- clk->name);
- WARN_ON(1);
- return;
- }
-
- if (!(--clk->usecount)) {
- if (likely(clk->ops && clk->ops->disable))
- clk->ops->disable(clk);
- if (likely(clk->parent))
- __clk_disable(clk->parent);
- }
-}
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- if (!clk)
- return;
-
- spin_lock_irqsave(&clock_lock, flags);
- __clk_disable(clk);
- spin_unlock_irqrestore(&clock_lock, flags);
-}
-EXPORT_SYMBOL_GPL(clk_disable);
-
-static int __clk_enable(struct clk *clk)
-{
- int ret = 0;
-
- if (clk->usecount++ == 0) {
- if (clk->parent) {
- ret = __clk_enable(clk->parent);
- if (unlikely(ret))
- goto err;
- }
-
- if (clk->ops && clk->ops->enable) {
- ret = clk->ops->enable(clk);
- if (ret) {
- if (clk->parent)
- __clk_disable(clk->parent);
- goto err;
- }
- }
- }
-
- return ret;
-err:
- clk->usecount--;
- return ret;
-}
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
- int ret;
-
- if (!clk)
- return -EINVAL;
-
- spin_lock_irqsave(&clock_lock, flags);
- ret = __clk_enable(clk);
- spin_unlock_irqrestore(&clock_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(clk_enable);
-
-static LIST_HEAD(root_clks);
-
-/**
- * recalculate_root_clocks - recalculate and propagate all root clocks
- *
- * Recalculates all root clocks (clocks with no parent), which if the
- * clock's .recalc is set correctly, should also propagate their rates.
- * Called at init.
- */
-void recalculate_root_clocks(void)
-{
- struct clk *clkp;
-
- list_for_each_entry(clkp, &root_clks, sibling) {
- if (clkp->ops && clkp->ops->recalc)
- clkp->rate = clkp->ops->recalc(clkp);
- propagate_rate(clkp);
- }
-}
-
-int clk_register(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- /*
- * trap out already registered clocks
- */
- if (clk->node.next || clk->node.prev)
- return 0;
-
- mutex_lock(&clock_list_sem);
-
- INIT_LIST_HEAD(&clk->children);
- clk->usecount = 0;
-
- if (clk->parent)
- list_add(&clk->sibling, &clk->parent->children);
- else
- list_add(&clk->sibling, &root_clks);
-
- list_add(&clk->node, &clock_list);
- if (clk->ops && clk->ops->init)
- clk->ops->init(clk);
- mutex_unlock(&clock_list_sem);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
- mutex_lock(&clock_list_sem);
- list_del(&clk->sibling);
- list_del(&clk->node);
- mutex_unlock(&clock_list_sem);
-}
-EXPORT_SYMBOL_GPL(clk_unregister);
-
-static void clk_enable_init_clocks(void)
-{
- struct clk *clkp;
-
- list_for_each_entry(clkp, &clock_list, node)
- if (clkp->flags & CLK_ENABLE_ON_INIT)
- clk_enable(clkp);
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-EXPORT_SYMBOL_GPL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- return clk_set_rate_ex(clk, rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
-{
- int ret = -EOPNOTSUPP;
- unsigned long flags;
-
- spin_lock_irqsave(&clock_lock, flags);
-
- if (likely(clk->ops && clk->ops->set_rate)) {
- ret = clk->ops->set_rate(clk, rate, algo_id);
- if (ret != 0)
- goto out_unlock;
- } else {
- clk->rate = rate;
- ret = 0;
- }
-
- if (clk->ops && clk->ops->recalc)
- clk->rate = clk->ops->recalc(clk);
-
- propagate_rate(clk);
-
-out_unlock:
- spin_unlock_irqrestore(&clock_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_rate_ex);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- unsigned long flags;
- int ret = -EINVAL;
-
- if (!parent || !clk)
- return ret;
- if (clk->parent == parent)
- return 0;
-
- spin_lock_irqsave(&clock_lock, flags);
- if (clk->usecount == 0) {
- if (clk->ops->set_parent)
- ret = clk->ops->set_parent(clk, parent);
- else
- ret = clk_reparent(clk, parent);
-
- if (ret == 0) {
- pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
- clk->name, clk->parent->name, clk->rate);
- if (clk->ops->recalc)
- clk->rate = clk->ops->recalc(clk);
- propagate_rate(clk);
- }
- } else
- ret = -EBUSY;
- spin_unlock_irqrestore(&clock_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- return clk->parent;
-}
-EXPORT_SYMBOL_GPL(clk_get_parent);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (likely(clk->ops && clk->ops->round_rate)) {
- unsigned long flags, rounded;
-
- spin_lock_irqsave(&clock_lock, flags);
- rounded = clk->ops->round_rate(clk, rate);
- spin_unlock_irqrestore(&clock_lock, flags);
-
- return rounded;
- }
-
- return clk_get_rate(clk);
-}
-EXPORT_SYMBOL_GPL(clk_round_rate);
-
-/*
- * Find the correct struct clk for the device and connection ID.
- * We do slightly fuzzy matching here:
- * An entry with a NULL ID is assumed to be a wildcard.
- * If an entry has a device ID, it must match
- * If an entry has a connection ID, it must match
- * Then we take the most specific entry - with the following
- * order of precedence: dev+con > dev only > con only.
- */
-static struct clk *clk_find(const char *dev_id, const char *con_id)
-{
- struct clk_lookup *p;
- struct clk *clk = NULL;
- int match, best = 0;
-
- list_for_each_entry(p, &clock_list, node) {
- match = 0;
- if (p->dev_id) {
- if (!dev_id || strcmp(p->dev_id, dev_id))
- continue;
- match += 2;
- }
- if (p->con_id) {
- if (!con_id || strcmp(p->con_id, con_id))
- continue;
- match += 1;
- }
- if (match == 0)
- continue;
-
- if (match > best) {
- clk = p->clk;
- best = match;
- }
- }
- return clk;
-}
-
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
-{
- struct clk *clk;
-
- mutex_lock(&clock_list_sem);
- clk = clk_find(dev_id, con_id);
- mutex_unlock(&clock_list_sem);
-
- return clk ? clk : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL_GPL(clk_get_sys);
-
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk *clk_g