]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-omap2/clock.c
OMAP3 clock: remove unnecessary dpll_data dereferences
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / clock.c
index ad721e0cbf7a1ded6c54ab2212efb4a5da1f281e..7aefabb6cf221a3d7b87f452e1c734fdb1561c8c 100644 (file)
 #include <mach/clockdomain.h>
 #include <mach/sram.h>
 #include <mach/cpu.h>
+#include <mach/prcm.h>
+#include <mach/control.h>
 #include <asm/div64.h>
 
-#include "memory.h"
+#include <mach/sdrc.h>
 #include "sdrc.h"
 #include "clock.h"
 #include "prm.h"
 #define DPLL_ROUNDING_VAL              ((DPLL_SCALE_BASE / 2) * \
                                         (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
 
+/* Some OMAP2xxx CM_CLKSEL_PLL.ST_CORE_CLK bits - for omap2_get_dpll_rate() */
+#define ST_CORE_CLK_REF                        0x1
+#define ST_CORE_CLK_32K                        0x3
+
+/* Bitmask to isolate the register type of clk.enable_reg */
+#define PRCM_REGTYPE_MASK              0xf0
+/* various CM register type options */
+#define CM_FCLKEN_REGTYPE              0x00
+#define CM_ICLKEN_REGTYPE              0x10
+#define CM_IDLEST_REGTYPE              0x20
+
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
  * OMAP2/3 specific clock functions
  *-------------------------------------------------------------------------*/
 
+/*
+ * _omap2_clk_read_reg - read a clock register
+ * @clk: struct clk *
+ *
+ * Given a struct clk *, returns the value of the clock's register.
+ */
+static u32 _omap2_clk_read_reg(u16 reg_offset, struct clk *clk)
+{
+       if (clk->prcm_mod & CLK_REG_IN_SCM)
+               return omap_ctrl_readl(reg_offset);
+       else if (clk->prcm_mod & CLK_REG_IN_PRM)
+               return prm_read_mod_reg(clk->prcm_mod & PRCM_MOD_ADDR_MASK,
+                                       reg_offset);
+       else
+               return cm_read_mod_reg(clk->prcm_mod, reg_offset);
+}
+
+/*
+ * _omap2_clk_write_reg - write a clock's register
+ * @v: value to write to the clock's enable_reg
+ * @clk: struct clk *
+ *
+ * Given a register value @v and struct clk * @clk, writes the value of @v to
+ * the clock's enable register.  No return value.
+ */
+static void _omap2_clk_write_reg(u32 v, u16 reg_offset, struct clk *clk)
+{
+       if (clk->prcm_mod & CLK_REG_IN_SCM)
+               omap_ctrl_writel(v, reg_offset);
+       else if (clk->prcm_mod & CLK_REG_IN_PRM)
+               prm_write_mod_reg(v, clk->prcm_mod & PRCM_MOD_ADDR_MASK,
+                                 reg_offset);
+       else
+               cm_write_mod_reg(v, clk->prcm_mod, reg_offset);
+}
+
+
 /**
  * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
  * @clk: OMAP clock struct ptr to use
@@ -77,17 +127,19 @@ void omap2_init_clk_clkdm(struct clk *clk)
 {
        struct clockdomain *clkdm;
 
-       if (!clk->clkdm_name)
+       if (!clk->clkdm.name) {
+               pr_err("clock: %s: missing clockdomain", clk->name);
                return;
+       }
 
-       clkdm = clkdm_lookup(clk->clkdm_name);
+       clkdm = clkdm_lookup(clk->clkdm.name);
        if (clkdm) {
                pr_debug("clock: associated clk %s to clkdm %s\n",
-                        clk->name, clk->clkdm_name);
-               clk->clkdm = clkdm;
+                        clk->name, clk->clkdm.name);
+               clk->clkdm.ptr = clkdm;
        } else {
-               pr_debug("clock: could not associate clk %s to "
-                        "clkdm %s\n", clk->name, clk->clkdm_name);
+               pr_err("clock: %s: could not associate to clkdm %s\n",
+                      clk->name, clk->clkdm.name);
        }
 }
 
@@ -108,7 +160,8 @@ void omap2_init_clksel_parent(struct clk *clk)
        if (!clk->clksel)
                return;
 
-       r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+       r = _omap2_clk_read_reg(clk->clksel_reg, clk);
+       r &= clk->clksel_mask;
        r >>= __ffs(clk->clksel_mask);
 
        for (clks = clk->clksel; clks->parent && !found; clks++) {
@@ -134,22 +187,52 @@ void omap2_init_clksel_parent(struct clk *clk)
        return;
 }
 
-/* Returns the DPLL rate */
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values.  When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk.  Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
 u32 omap2_get_dpll_rate(struct clk *clk)
 {
        long long dpll_clk;
-       u32 dpll_mult, dpll_div, dpll;
+       u32 dpll_mult, dpll_div, v;
        struct dpll_data *dd;
 
        dd = clk->dpll_data;
-       /* REVISIT: What do we return on error? */
        if (!dd)
                return 0;
 
-       dpll = __raw_readl(dd->mult_div1_reg);
-       dpll_mult = dpll & dd->mult_mask;
+       /* Return bypass rate if DPLL is bypassed */
+       v = cm_read_mod_reg(clk->prcm_mod, dd->idlest_reg);
+       v &= dd->idlest_mask;
+       v >>= __ffs(dd->idlest_mask);
+       if (cpu_is_omap24xx()) {
+
+               if (v == ST_CORE_CLK_REF)
+                       return clk->parent->rate; /* sys_clk */
+               else if (v == ST_CORE_CLK_32K)
+                       return 32768;
+
+       } else if (cpu_is_omap34xx()) {
+
+               if (!v)
+                       return dd->bypass_clk->rate;
+
+       }
+
+       v = cm_read_mod_reg(clk->prcm_mod, dd->mult_div1_reg);
+       dpll_mult = v & dd->mult_mask;
        dpll_mult >>= __ffs(dd->mult_mask);
-       dpll_div = dpll & dd->div1_mask;
+       dpll_div = v & dd->div1_mask;
        dpll_div >>= __ffs(dd->div1_mask);
 
        dpll_clk = (long long)clk->parent->rate * dpll_mult;
@@ -174,30 +257,30 @@ void omap2_fixed_divisor_recalc(struct clk *clk)
 
 /**
  * omap2_wait_clock_ready - wait for clock to enable
- * @reg: physical address of clock IDLEST register
+ * @prcm_mod: CM submodule offset from CM_BASE (e.g., "MPU_MOD")
+ * @reg_index: offset of CM register address from prcm_mod
  * @mask: value to mask against to determine if the clock is active
  * @name: name of the clock (for printk)
  *
  * Returns 1 if the clock enabled in time, or 0 if it failed to enable
  * in roughly MAX_CLOCK_ENABLE_WAIT microseconds.
  */
-int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
+int omap2_wait_clock_ready(s16 prcm_mod, u16 reg_index, u32 mask,
+                          const char *name)
 {
-       int i = 0;
-       int ena = 0;
+       int i = 0, ena = 0;
 
        /*
         * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
         * 34xx reverses this, just to keep us on our toes
         */
-       if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) {
+       if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
                ena = mask;
-       } else if (cpu_mask & RATE_IN_343X) {
+       else if (cpu_mask & RATE_IN_343X)
                ena = 0;
-       }
 
        /* Wait for lock */
-       while (((__raw_readl(reg) & mask) != ena) &&
+       while (((cm_read_mod_reg(prcm_mod, reg_index) & mask) != ena) &&
               (i++ < MAX_CLOCK_ENABLE_WAIT)) {
                udelay(1);
        }
@@ -208,68 +291,64 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
                printk(KERN_ERR "Clock %s didn't enable in %d tries\n",
                       name, MAX_CLOCK_ENABLE_WAIT);
 
-
        return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0;
 };
 
 
 /*
- * Note: We don't need special code here for INVERT_ENABLE
- * for the time being since INVERT_ENABLE only applies to clocks enabled by
- * CM_CLKEN_PLL
+ * omap2_clk_wait_ready - wait for a OMAP module to come out of target idle
+ * @clk: struct clk * recently enabled to indicate the module to test
+ *
+ * Wait for an OMAP module with a target idle state bit to come out of
+ * idle once both its interface clock and primary functional clock are
+ * both enabled.  Any register read or write to the device before it
+ * returns from idle will cause an abort.  Not all modules have target
+ * idle state bits (for example, DSS and CAM on OMAP24xx); so we don't
+ * wait for those.  No return value.
+ *
+ * We don't need special code here for INVERT_ENABLE for the time
+ * being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL.
+ *
+ * REVISIT: This function is misnamed: it should be something like
+ * "omap2_module_wait_ready", and in the long-term, it does not belong
+ * in the clock framework. It also shouldn't be doing register
+ * arithmetic to determine the companion clock.
  */
 static void omap2_clk_wait_ready(struct clk *clk)
 {
-       void __iomem *reg, *other_reg, *st_reg;
-       u32 bit;
+       u16 other_reg, idlest_reg;
+       u32 other_bit;
 
-       /*
-        * REVISIT: This code is pretty ugly.  It would be nice to generalize
-        * it and pull it into struct clk itself somehow.
-        */
-       reg = clk->enable_reg;
-       if ((((u32)reg & 0xff) >= CM_FCLKEN1) &&
-           (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
-               other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
-       else if ((((u32)reg & 0xff) >= CM_ICLKEN1) &&
-                (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
-               other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
-       else
+       if (!(clk->flags & WAIT_READY))
                return;
 
-       /* REVISIT: What are the appropriate exclusions for 34XX? */
-       /* No check for DSS or cam clocks */
-       if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
-               if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
-                   clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
-                   clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
-                       return;
-       }
+       /* If we are enabling an iclk, also test the fclk; and vice versa */
+       other_bit = 1 << clk->enable_bit;
+       other_reg = clk->enable_reg & ~PRCM_REGTYPE_MASK;
 
-       /* REVISIT: What are the appropriate exclusions for 34XX? */
-       /* OMAP3: ignore DSS-mod clocks */
-       if (cpu_is_omap34xx() &&
-           (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
-            ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) &&
-            clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
-               return;
+       if (clk->enable_reg & CM_ICLKEN_REGTYPE)
+               other_reg |= CM_FCLKEN_REGTYPE;
+       else
+               other_reg |= CM_ICLKEN_REGTYPE;
 
-       /* Check if both functional and interface clocks
-        * are running. */
-       bit = 1 << clk->enable_bit;
-       if (!(__raw_readl(other_reg) & bit))
+       /* Ensure functional and interface clocks are running. */
+       if (!(cm_read_mod_reg(clk->prcm_mod, other_reg) & other_bit))
                return;
-       st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */
 
-       omap2_wait_clock_ready(st_reg, bit, clk->name);
+       idlest_reg = other_reg & ~PRCM_REGTYPE_MASK;
+       idlest_reg |= CM_IDLEST_REGTYPE;
+
+       omap2_wait_clock_ready(clk->prcm_mod, idlest_reg, 1 << clk->idlest_bit,
+                              clk->name);
 }
 
 /* Enables clock without considering parent dependencies or use count
  * REVISIT: Maybe change this to use clk->enable like on omap1?
  */
-int _omap2_clk_enable(struct clk *clk)
+static int _omap2_clk_enable(struct clk *clk)
 {
-       u32 regval32;
+       u32 v;
 
        if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
                return 0;
@@ -277,18 +356,12 @@ int _omap2_clk_enable(struct clk *clk)
        if (clk->enable)
                return clk->enable(clk);
 
-       if (unlikely(clk->enable_reg == NULL)) {
-               printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
-                      clk->name);
-               return 0; /* REVISIT: -EINVAL */
-       }
-
-       regval32 = __raw_readl(clk->enable_reg);
+       v = _omap2_clk_read_reg(clk->enable_reg, clk);
        if (clk->flags & INVERT_ENABLE)
-               regval32 &= ~(1 << clk->enable_bit);
+               v &= ~(1 << clk->enable_bit);
        else
-               regval32 |= (1 << clk->enable_bit);
-       __raw_writel(regval32, clk->enable_reg);
+               v |= (1 << clk->enable_bit);
+       _omap2_clk_write_reg(v, clk->enable_reg, clk);
        wmb();
 
        omap2_clk_wait_ready(clk);
@@ -297,9 +370,9 @@ int _omap2_clk_enable(struct clk *clk)
 }
 
 /* Disables clock without considering parent dependencies or use count */
-void _omap2_clk_disable(struct clk *clk)
+static void _omap2_clk_disable(struct clk *clk)
 {
-       u32 regval32;
+       u32 v;
 
        if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
                return;
@@ -309,22 +382,12 @@ void _omap2_clk_disable(struct clk *clk)
                return;
        }
 
-       if (clk->enable_reg == NULL) {
-               /*
-                * 'Independent' here refers to a clock which is not
-                * controlled by its parent.
-                */
-               printk(KERN_ERR "clock: clk_disable called on independent "
-                      "clock %s which has no enable_reg\n", clk->name);
-               return;
-       }
-
-       regval32 = __raw_readl(clk->enable_reg);
+       v = _omap2_clk_read_reg(clk->enable_reg, clk);
        if (clk->flags & INVERT_ENABLE)
-               regval32 |= (1 << clk->enable_bit);
+               v |= (1 << clk->enable_bit);
        else
-               regval32 &= ~(1 << clk->enable_bit);
-       __raw_writel(regval32, clk->enable_reg);
+               v &= ~(1 << clk->enable_bit);
+       _omap2_clk_write_reg(v, clk->enable_reg, clk);
        wmb();
 }
 
@@ -332,10 +395,10 @@ void omap2_clk_disable(struct clk *clk)
 {
        if (clk->usecount > 0 && !(--clk->usecount)) {
                _omap2_clk_disable(clk);
-               if (likely((u32)clk->parent))
+               if (clk->parent)
                        omap2_clk_disable(clk->parent);
-               if (clk->clkdm)
-                       omap2_clkdm_clk_disable(clk->clkdm, clk);
+               if (clk->clkdm.ptr)
+                       omap2_clkdm_clk_disable(clk->clkdm.ptr, clk);
 
        }
 }
@@ -345,22 +408,22 @@ int omap2_clk_enable(struct clk *clk)
        int ret = 0;
 
        if (clk->usecount++ == 0) {
-               if (likely((u32)clk->parent))
+               if (clk->parent)
                        ret = omap2_clk_enable(clk->parent);
 
-               if (unlikely(ret != 0)) {
+               if (ret != 0) {
                        clk->usecount--;
                        return ret;
                }
 
-               if (clk->clkdm)
-                       omap2_clkdm_clk_enable(clk->clkdm, clk);
+               if (clk->clkdm.ptr)
+                       omap2_clkdm_clk_enable(clk->clkdm.ptr, clk);
 
                ret = _omap2_clk_enable(clk);
 
-               if (unlikely(ret != 0)) {
-                       if (clk->clkdm)
-                               omap2_clkdm_clk_disable(clk->clkdm, clk);
+               if (ret != 0) {
+                       if (clk->clkdm.ptr)
+                               omap2_clkdm_clk_disable(clk->clkdm.ptr, clk);
 
                        if (clk->parent) {
                                omap2_clk_disable(clk->parent);
@@ -386,13 +449,13 @@ void omap2_clksel_recalc(struct clk *clk)
        if (div == 0)
                return;
 
-       if (unlikely(clk->rate == clk->parent->rate / div))
+       if (clk->rate == (clk->parent->rate / div))
                return;
        clk->rate = clk->parent->rate / div;
 
        pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div);
 
-       if (unlikely(clk->flags & RATE_PROPAGATES))
+       if (clk->flags & RATE_PROPAGATES)
                propagate_rate(clk);
 }
 
@@ -405,8 +468,8 @@ void omap2_clksel_recalc(struct clk *clk)
  * the element associated with the supplied parent clock address.
  * Returns a pointer to the struct clksel on success or NULL on error.
  */
-const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
-                                               struct clk *src_clk)
+static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
+                                                      struct clk *src_clk)
 {
        const struct clksel *clks;
 
@@ -455,7 +518,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
        *new_div = 1;
 
        clks = omap2_get_clksel_by_parent(clk, clk->parent);
-       if (clks == NULL)
+       if (!clks)
                return ~0;
 
        for (clkr = clks->rates; clkr->div; clkr++) {
@@ -540,7 +603,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
        const struct clksel_rate *clkr;
 
        clks = omap2_get_clksel_by_parent(clk, clk->parent);
-       if (clks == NULL)
+       if (!clks)
                return 0;
 
        for (clkr = clks->rates; clkr->div; clkr++) {
@@ -576,7 +639,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
        WARN_ON(div == 0);
 
        clks = omap2_get_clksel_by_parent(clk, clk->parent);
-       if (clks == NULL)
+       if (!clks)
                return 0;
 
        for (clkr = clks->rates; clkr->div; clkr++) {
@@ -594,23 +657,6 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
        return clkr->val;
 }
 
-/**
- * omap2_get_clksel - find clksel register addr & field mask for a clk
- * @clk: struct clk to use
- * @field_mask: ptr to u32 to store the register field mask
- *
- * Returns the address of the clksel register upon success or NULL on error.
- */
-void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
-{
-       if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
-               return NULL;
-
-       *field_mask = clk->clksel_mask;
-
-       return clk->clksel_reg;
-}
-
 /**
  * omap2_clksel_get_divisor - get current divider applied to parent clock.
  * @clk: OMAP struct clk to use.
@@ -619,40 +665,38 @@ void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
  */
 u32 omap2_clksel_get_divisor(struct clk *clk)
 {
-       u32 field_mask, field_val;
-       void __iomem *div_addr;
+       u32 v;
 
-       div_addr = omap2_get_clksel(clk, &field_mask);
-       if (div_addr == NULL)
+       if (!clk->clksel_mask)
                return 0;
 
-       field_val = __raw_readl(div_addr) & field_mask;
-       field_val >>= __ffs(field_mask);
+       v = _omap2_clk_read_reg(clk->clksel_reg, clk);
+       v &= clk->clksel_mask;
+       v >>= __ffs(clk->clksel_mask);
 
-       return omap2_clksel_to_divisor(clk, field_val);
+       return omap2_clksel_to_divisor(clk, v);
 }
 
 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
 {
-       u32 field_mask, field_val, reg_val, validrate, new_div = 0;
-       void __iomem *div_addr;
+       u32 v, field_val, validrate, new_div = 0;
 
-       validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
-       if (validrate != rate)
+       if (!clk->clksel_mask)
                return -EINVAL;
 
-       div_addr = omap2_get_clksel(clk, &field_mask);
-       if (div_addr == NULL)
-               return -EINVAL;
+       validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+       if (validrate != rate)
+              return -EINVAL;
 
        field_val = omap2_divisor_to_clksel(clk, new_div);
        if (field_val == ~0)
                return -EINVAL;
 
-       reg_val = __raw_readl(div_addr);
-       reg_val &= ~field_mask;
-       reg_val |= (field_val << __ffs(field_mask));
-       __raw_writel(reg_val, div_addr);
+       v = _omap2_clk_read_reg(clk->clksel_reg, clk);
+       v &= ~clk->clksel_mask;
+       v |= field_val << __ffs(clk->clksel_mask);
+       _omap2_clk_write_reg(v, clk->clksel_reg, clk);
+
        wmb();
 
        clk->rate = clk->parent->rate / new_div;
@@ -683,7 +727,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
        if (clk->set_rate != NULL)
                ret = clk->set_rate(clk, rate);
 
-       if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+       if (ret == 0 && (clk->flags & RATE_PROPAGATES))
                propagate_rate(clk);
 
        return ret;
@@ -691,20 +735,16 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
 
 /*
  * Converts encoded control register address into a full address
- * On error, *src_addr will be returned as 0.
+ * On error, the return value (parent_div) will be 0.
  */
-static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
-                                     struct clk *src_clk, u32 *field_mask,
-                                     struct clk *clk, u32 *parent_div)
+static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
+                                      u32 *field_val)
 {
        const struct clksel *clks;
        const struct clksel_rate *clkr;
 
-       *parent_div = 0;
-       *src_addr = NULL;
-
        clks = omap2_get_clksel_by_parent(clk, src_clk);
-       if (clks == NULL)
+       if (!clks)
                return 0;
 
        for (clkr = clks->rates; clkr->div; clkr++) {
@@ -722,40 +762,38 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
        /* Should never happen.  Add a clksel mask to the struct clk. */
        WARN_ON(clk->clksel_mask == 0);
 
-       *field_mask = clk->clksel_mask;
-       *src_addr = clk->clksel_reg;
-       *parent_div = clkr->div;
+       *field_val = clkr->val;
 
-       return clkr->val;
+       return clkr->div;
 }
 
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 {
-       void __iomem *src_addr;
-       u32 field_val, field_mask, reg_val, parent_div;
+       u32 field_val, v, parent_div;
 
-       if (unlikely(clk->flags & CONFIG_PARTICIPANT))
+       if (clk->flags & CONFIG_PARTICIPANT)
                return -EINVAL;
 
        if (!clk->clksel)
                return -EINVAL;
 
-       field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
-                                              &field_mask, clk, &parent_div);
-       if (src_addr == NULL)
+       parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
+       if (!parent_div)
                return -EINVAL;
 
        if (clk->usecount > 0)
                _omap2_clk_disable(clk);
 
        /* Set new source value (previous dividers if any in effect) */
-       reg_val = __raw_readl(src_addr) & ~field_mask;
-       reg_val |= (field_val << __ffs(field_mask));
-       __raw_writel(reg_val, src_addr);
+       v = _omap2_clk_read_reg(clk->clksel_reg, clk);
+       v &= ~clk->clksel_mask;
+       v |= field_val << __ffs(clk->clksel_mask);
+       _omap2_clk_write_reg(v, clk->clksel_reg, clk);
        wmb();
 
        if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
-               __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
+               prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
+                       OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
                wmb();
        }
 
@@ -773,7 +811,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
        pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
                 clk->name, clk->parent->name, clk->rate);
 
-       if (unlikely(clk->flags & RATE_PROPAGATES))
+       if (clk->flags & RATE_PROPAGATES)
                propagate_rate(clk);
 
        return 0;
@@ -805,7 +843,8 @@ int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
        return 0;
 }
 
-static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n)
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+                                           unsigned int m, unsigned int n)
 {
        unsigned long long num;
 
@@ -889,19 +928,22 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
        int m, n, r, e, scaled_max_m;
        unsigned long scaled_rt_rp, new_rate;
        int min_e = -1, min_e_m = -1, min_e_n = -1;
+       struct dpll_data *dd;
 
        if (!clk || !clk->dpll_data)
                return ~0;
 
+       dd = clk->dpll_data;
+
        pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
                 "%ld\n", clk->name, target_rate);
 
        scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR);
-       scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR;
+       scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
 
-       clk->dpll_data->last_rounded_rate = 0;
+       dd->last_rounded_rate = 0;
 
-       for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
+       for (n = dd->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
 
                /* Compute the scaled DPLL multiplier, based on the divider */
                m = scaled_rt_rp * n;
@@ -921,7 +963,7 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
                         "(new_rate = %ld)\n", n, m, e, new_rate);
 
                if (min_e == -1 ||
-                   min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) {
+                   min_e >= (int)(abs(e) - dd->rate_tolerance)) {
                        min_e = e;
                        min_e_m = m;
                        min_e_n = n;
@@ -944,17 +986,17 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
                return ~0;
        }
 
-       clk->dpll_data->last_rounded_m = min_e_m;
-       clk->dpll_data->last_rounded_n = min_e_n;
-       clk->dpll_data->last_rounded_rate =
-               _dpll_compute_new_rate(clk->parent->rate, min_e_m,  min_e_n);
+       dd->last_rounded_m = min_e_m;
+       dd->last_rounded_n = min_e_n;
+       dd->last_rounded_rate = _dpll_compute_new_rate(clk->parent->rate,
+                                                      min_e_m,  min_e_n);
 
        pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
                 min_e, min_e_m, min_e_n);
        pr_debug("clock: final rate: %ld  (target rate: %ld)\n",
-                clk->dpll_data->last_rounded_rate, target_rate);
+                dd->last_rounded_rate, target_rate);
 
-       return clk->dpll_data->last_rounded_rate;
+       return dd->last_rounded_rate;
 }
 
 /*-------------------------------------------------------------------------
@@ -968,7 +1010,7 @@ void omap2_clk_disable_unused(struct clk *clk)
 
        v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
 
-       regval32 = __raw_readl(clk->enable_reg);
+       regval32 = _omap2_clk_read_reg(clk->enable_reg, clk);
        if ((regval32 & (1 << clk->enable_bit)) == v)
                return;