]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-davinci/clock.c
Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
[karo-tx-linux.git] / arch / arm / mach-davinci / clock.c
index baece65cb9c0829ed04bfc210e8894f075512bbe..bf6218ee94e193a69b9de7ef1da240f2d320e16b 100644 (file)
@@ -49,7 +49,8 @@ static void __clk_disable(struct clk *clk)
 {
        if (WARN_ON(clk->usecount == 0))
                return;
-       if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
+       if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
+           (clk->flags & CLK_PSC))
                davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
        if (clk->parent)
                __clk_disable(clk->parent);
@@ -124,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        if (clk == NULL || IS_ERR(clk))
                return ret;
 
-       spin_lock_irqsave(&clockfw_lock, flags);
        if (clk->set_rate)
                ret = clk->set_rate(clk, rate);
+
+       spin_lock_irqsave(&clockfw_lock, flags);
        if (ret == 0) {
                if (clk->recalc)
                        clk->rate = clk->recalc(clk);
@@ -363,6 +365,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
 {
        u32 ctrl;
        unsigned int locktime;
+       unsigned long flags;
 
        if (pll->base == NULL)
                return -EINVAL;
@@ -376,25 +379,23 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
                locktime = ((2000 * prediv) / 100);
                prediv = (prediv - 1) | PLLDIV_EN;
        } else {
-               locktime = 20;
+               locktime = PLL_LOCK_TIME;
        }
        if (postdiv)
                postdiv = (postdiv - 1) | PLLDIV_EN;
        if (mult)
                mult = mult - 1;
 
+       /* Protect against simultaneous calls to PLL setting seqeunce */
+       spin_lock_irqsave(&clockfw_lock, flags);
+
        ctrl = __raw_readl(pll->base + PLLCTL);
 
        /* Switch the PLL to bypass mode */
        ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
        __raw_writel(ctrl, pll->base + PLLCTL);
 
-       /*
-        * Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
-        * to bypass mode. Delay of 1us ensures we are good for all > 4MHz
-        * OSCIN/CLKIN inputs. Typically the input is ~25MHz.
-        */
-       udelay(1);
+       udelay(PLL_BYPASS_TIME);
 
        /* Reset and enable PLL */
        ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
@@ -408,11 +409,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
        if (pll->flags & PLL_HAS_POSTDIV)
                __raw_writel(postdiv, pll->base + POSTDIV);
 
-       /*
-        * Wait for PLL to reset properly, OMAP-L138 datasheet says
-        * 'min' time = 125ns
-        */
-       udelay(1);
+       udelay(PLL_RESET_TIME);
 
        /* Bring PLL out of reset */
        ctrl |= PLLCTL_PLLRST;
@@ -424,17 +421,20 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
        ctrl |= PLLCTL_PLLEN;
        __raw_writel(ctrl, pll->base + PLLCTL);
 
+       spin_unlock_irqrestore(&clockfw_lock, flags);
+
        return 0;
 }
 EXPORT_SYMBOL(davinci_set_pllrate);
 
-int __init davinci_clk_init(struct davinci_clk *clocks)
+int __init davinci_clk_init(struct clk_lookup *clocks)
   {
-       struct davinci_clk *c;
+       struct clk_lookup *c;
        struct clk *clk;
+       size_t num_clocks = 0;
 
-       for (c = clocks; c->lk.clk; c++) {
-               clk = c->lk.clk;
+       for (c = clocks; c->clk; c++) {
+               clk = c->clk;
 
                if (!clk->recalc) {
 
@@ -457,35 +457,23 @@ int __init davinci_clk_init(struct davinci_clk *clocks)
                if (clk->lpsc)
                        clk->flags |= CLK_PSC;
 
-               clkdev_add(&c->lk);
                clk_register(clk);
+               num_clocks++;
 
                /* Turn on clocks that Linux doesn't otherwise manage */
                if (clk->flags & ALWAYS_ENABLED)
                        clk_enable(clk);
        }
 
-       return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+       clkdev_add_table(clocks, num_clocks);
 
-static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
-{
-       return *pos < 1 ? (void *)1 : NULL;
+       return 0;
 }
 
-static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       ++*pos;
-       return NULL;
-}
+#ifdef CONFIG_DEBUG_FS
 
-static void davinci_ck_stop(struct seq_file *m, void *v)
-{
-}
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #define CLKNAME_MAX    10              /* longest clock name */
 #define NEST_DELTA     2
@@ -525,41 +513,38 @@ dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
 
 static int davinci_ck_show(struct seq_file *m, void *v)
 {
-       /* Show clock tree; we know the main oscillator is first.
-        * We trust nonzero usecounts equate to PSC enables...
+       struct clk *clk;
+
+       /*
+        * Show clock tree; We trust nonzero usecounts equate to PSC enables...
         */
        mutex_lock(&clocks_mutex);
-       if (!list_empty(&clocks))
-               dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
+       list_for_each_entry(clk, &clocks, node)
+               if (!clk->parent)
+                       dump_clock(m, 0, clk);
        mutex_unlock(&clocks_mutex);
 
        return 0;
 }
 
-static const struct seq_operations davinci_ck_op = {
-       .start  = davinci_ck_start,
-       .next   = davinci_ck_next,
-       .stop   = davinci_ck_stop,
-       .show   = davinci_ck_show
-};
-
 static int davinci_ck_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &davinci_ck_op);
+       return single_open(file, davinci_ck_show, NULL);
 }
 
-static const struct file_operations proc_davinci_ck_operations = {
+static const struct file_operations davinci_ck_operations = {
        .open           = davinci_ck_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release,
+       .release        = single_release,
 };
 
-static int __init davinci_ck_proc_init(void)
+static int __init davinci_clk_debugfs_init(void)
 {
-       proc_create("davinci_clocks", 0, NULL, &proc_davinci_ck_operations);
+       debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
+                                               &davinci_ck_operations);
        return 0;
 
 }
-__initcall(davinci_ck_proc_init);
-#endif /* CONFIG_DEBUG_PROC_FS */
+device_initcall(davinci_clk_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */