This converts all of arch/arm/mach-davinci to the common clock framework.
The clock drivers from clock.c and psc.c have been moved to drivers/clk,
so these files are removed.

There is one subtle change in the clock trees. AUX, BPDIV and OSCDIV
clocks now have "ref_clk" as a parent instead of the PLL clock. These
clocks are part of the PLL's MMIO block, but they bypass the PLL and
therefore it makes more sense to have "ref_clk" as their parent since
"ref_clk" is the input clock of the PLL.

CONFIG_DAVINCI_RESET_CLOCKS is removed since the common clock frameworks
takes care of disabling unused clocks.

Known issue: This breaks CPU frequency scaling on da850.

Also, the order of #includes are cleaned up in files while we are touching
this code.

Signed-off-by: David Lechner <[email protected]>
---
 arch/arm/Kconfig                            |   2 +-
 arch/arm/mach-davinci/Kconfig               |  12 -
 arch/arm/mach-davinci/Makefile              |   2 +-
 arch/arm/mach-davinci/board-da830-evm.c     |  15 +-
 arch/arm/mach-davinci/board-omapl138-hawk.c |  15 +-
 arch/arm/mach-davinci/clock.c               | 702 ----------------------------
 arch/arm/mach-davinci/clock.h               |  64 ---
 arch/arm/mach-davinci/common.c              |   1 -
 arch/arm/mach-davinci/da830.c               | 423 +++--------------
 arch/arm/mach-davinci/da850.c               | 650 ++++----------------------
 arch/arm/mach-davinci/da8xx-dt.c            |  15 +-
 arch/arm/mach-davinci/devices-da8xx.c       |  43 +-
 arch/arm/mach-davinci/dm355.c               | 394 +++-------------
 arch/arm/mach-davinci/dm365.c               | 520 ++++-----------------
 arch/arm/mach-davinci/dm644x.c              | 346 +++-----------
 arch/arm/mach-davinci/dm646x.c              | 386 +++------------
 arch/arm/mach-davinci/include/mach/clock.h  |   3 -
 arch/arm/mach-davinci/include/mach/common.h |   8 -
 arch/arm/mach-davinci/include/mach/da8xx.h  |   8 +-
 arch/arm/mach-davinci/psc.c                 | 137 ------
 arch/arm/mach-davinci/psc.h                 |  14 -
 arch/arm/mach-davinci/usb-da8xx.c           | 216 +--------
 22 files changed, 493 insertions(+), 3483 deletions(-)
 delete mode 100644 arch/arm/mach-davinci/clock.c
 delete mode 100644 arch/arm/mach-davinci/psc.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 51c8df5..3a12f9e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -604,7 +604,7 @@ config ARCH_S3C24XX
 config ARCH_DAVINCI
        bool "TI DaVinci"
        select ARCH_HAS_HOLES_MEMORYMODEL
-       select CLKDEV_LOOKUP
+       select COMMON_CLK
        select CPU_ARM926T
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 05c3eecf..ba9912b 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -231,18 +231,6 @@ config DAVINCI_MUX_WARNINGS
          to change the pin multiplexing setup. When there are no warnings
          printed, it's safe to deselect DAVINCI_MUX for your product.
 
-config DAVINCI_RESET_CLOCKS
-       bool "Reset unused clocks during boot"
-       depends on ARCH_DAVINCI
-       help
-         Say Y if you want to reset unused clocks during boot.
-         This option saves power, but assumes all drivers are
-         using the clock framework. Broken drivers that do not
-         yet use clock framework may not work with this option.
-         If you are booting from another operating system, you
-         probably do not want this option enabled until your
-         device drivers work properly.
-
 endmenu
 
 endif
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 4e81780..8a8f413 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,7 +5,7 @@
 #
 
 # Common objects
-obj-y                  := time.o clock.o serial.o psc.o \
+obj-y                  := time.o serial.o \
                           usb.o common.o sram.o aemif.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
diff --git a/arch/arm/mach-davinci/board-da830-evm.c 
b/arch/arm/mach-davinci/board-da830-evm.c
index 7adf009..304b0f1 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -23,6 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/platform_data/davinci_clk.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
@@ -106,19 +107,19 @@ static irqreturn_t da830_evm_usb_ocic_irq(int irq, void 
*dev_id)
        return IRQ_HANDLED;
 }
 
+static struct da8xx_cfgchip_clk_data usb_phy_clk_data = {
+       .usb0_use_refclkin = false,
+       .usb1_use_refclkin = false,
+};
+
 static __init void da830_evm_usb_init(void)
 {
        int ret;
 
        /* USB_REFCLKIN is not used. */
-       ret = da8xx_register_usb20_phy_clk(false);
-       if (ret)
-               pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
-                       __func__, ret);
-
-       ret = da8xx_register_usb11_phy_clk(false);
+       ret = da8xx_register_usb_phy_clocks(&usb_phy_clk_data);
        if (ret)
-               pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+               pr_warn("%s: registering USB PHY clocks failed: %d",
                        __func__, ret);
 
        ret = da8xx_register_usb_phy();
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c 
b/arch/arm/mach-davinci/board-omapl138-hawk.c
index bc8a747..6831ca9 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
+#include <linux/platform_data/davinci_clk.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/regulator/machine.h>
 
@@ -222,6 +223,11 @@ static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, 
void *dev_id)
        return IRQ_HANDLED;
 }
 
+static struct da8xx_cfgchip_clk_data usb_phy_clk_data = {
+       .usb0_use_refclkin = false,
+       .usb1_use_refclkin = false,
+};
+
 static __init void omapl138_hawk_usb_init(void)
 {
        int ret;
@@ -232,14 +238,9 @@ static __init void omapl138_hawk_usb_init(void)
                return;
        }
 
-       ret = da8xx_register_usb20_phy_clk(false);
-       if (ret)
-               pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
-                       __func__, ret);
-
-       ret = da8xx_register_usb11_phy_clk(false);
+       ret = da8xx_register_usb_phy_clocks(&usb_phy_clk_data);
        if (ret)
-               pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+               pr_warn("%s: registering USB PHY clocks failed: %d",
                        __func__, ret);
 
        ret = da8xx_register_usb_phy();
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
deleted file mode 100644
index 52b95e2..0000000
--- a/arch/arm/mach-davinci/clock.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Clock and PLL control for DaVinci devices
- *
- * Copyright (C) 2006-2007 Texas Instruments.
- * Copyright (C) 2008-2009 Deep Root Systems, LLC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-
-#include <mach/clock.h>
-#include "psc.h"
-#include <mach/cputype.h>
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
-void davinci_clk_enable(struct clk *clk)
-{
-       if (clk->parent)
-               davinci_clk_enable(clk->parent);
-       if (clk->usecount++ == 0) {
-               if (clk->flags & CLK_PSC)
-                       davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
-                                          true, clk->flags);
-               else if (clk->clk_enable)
-                       clk->clk_enable(clk);
-       }
-}
-
-void davinci_clk_disable(struct clk *clk)
-{
-       if (WARN_ON(clk->usecount == 0))
-               return;
-       if (--clk->usecount == 0) {
-               if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
-                       davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
-                                          false, clk->flags);
-               else if (clk->clk_disable)
-                       clk->clk_disable(clk);
-       }
-       if (clk->parent)
-               davinci_clk_disable(clk->parent);
-}
-
-int davinci_clk_reset(struct clk *clk, bool reset)
-{
-       unsigned long flags;
-
-       if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       if (clk->flags & CLK_PSC)
-               davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_clk_reset);
-
-int davinci_clk_reset_assert(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk) || !clk->reset)
-               return -EINVAL;
-
-       return clk->reset(clk, true);
-}
-EXPORT_SYMBOL(davinci_clk_reset_assert);
-
-int davinci_clk_reset_deassert(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk) || !clk->reset)
-               return -EINVAL;
-
-       return clk->reset(clk, false);
-}
-EXPORT_SYMBOL(davinci_clk_reset_deassert);
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       davinci_clk_enable(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (clk == NULL || IS_ERR(clk))
-               return;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       davinci_clk_disable(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return 0;
-
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return 0;
-
-       if (clk->round_rate)
-               return clk->round_rate(clk, rate);
-
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Propagate rate to children */
-static void propagate_rate(struct clk *root)
-{
-       struct clk *clk;
-
-       list_for_each_entry(clk, &root->children, childnode) {
-               if (clk->recalc)
-                       clk->rate = clk->recalc(clk);
-               propagate_rate(clk);
-       }
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       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);
-               propagate_rate(clk);
-       }
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       /* Cannot change parent on enabled clock */
-       if (WARN_ON(clk->usecount))
-               return -EINVAL;
-
-       mutex_lock(&clocks_mutex);
-       if (clk->set_parent) {
-               int ret = clk->set_parent(clk, parent);
-
-               if (ret) {
-                       mutex_unlock(&clocks_mutex);
-                       return ret;
-               }
-       }
-       clk->parent = parent;
-       list_del_init(&clk->childnode);
-       list_add(&clk->childnode, &clk->parent->children);
-       mutex_unlock(&clocks_mutex);
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       if (clk->recalc)
-               clk->rate = clk->recalc(clk);
-       propagate_rate(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-       if (!clk)
-               return NULL;
-
-       return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_register(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
-
-       if (WARN(clk->parent && !clk->parent->rate,
-                       "CLK: %s parent %s has no rate!\n",
-                       clk->name, clk->parent->name))
-               return -EINVAL;
-
-       INIT_LIST_HEAD(&clk->children);
-
-       mutex_lock(&clocks_mutex);
-       list_add_tail(&clk->node, &clocks);
-       if (clk->parent) {
-               if (clk->set_parent) {
-                       int ret = clk->set_parent(clk, clk->parent);
-
-                       if (ret) {
-                               mutex_unlock(&clocks_mutex);
-                               return ret;
-                       }
-               }
-               list_add_tail(&clk->childnode, &clk->parent->children);
-       }
-       mutex_unlock(&clocks_mutex);
-
-       /* If rate is already set, use it */
-       if (clk->rate)
-               return 0;
-
-       /* Else, see if there is a way to calculate it */
-       if (clk->recalc)
-               clk->rate = clk->recalc(clk);
-
-       /* Otherwise, default to parent rate */
-       else if (clk->parent)
-               clk->rate = clk->parent->rate;
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return;
-
-       mutex_lock(&clocks_mutex);
-       list_del(&clk->node);
-       list_del(&clk->childnode);
-       mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-int __init davinci_clk_disable_unused(void)
-{
-       struct clk *ck;
-
-       spin_lock_irq(&clockfw_lock);
-       list_for_each_entry(ck, &clocks, node) {
-               if (ck->usecount > 0)
-                       continue;
-               if (!(ck->flags & CLK_PSC))
-                       continue;
-
-               /* ignore if in Disabled or SwRstDisable states */
-               if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
-                       continue;
-
-               pr_debug("Clocks: disable unused %s\n", ck->name);
-
-               davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
-                               false, ck->flags);
-       }
-       spin_unlock_irq(&clockfw_lock);
-
-       return 0;
-}
-#endif
-
-static unsigned long clk_sysclk_recalc(struct clk *clk)
-{
-       u32 v, plldiv;
-       struct pll_data *pll;
-       unsigned long rate = clk->rate;
-
-       /* If this is the PLL base clock, no more calculations needed */
-       if (clk->pll_data)
-               return rate;
-
-       if (WARN_ON(!clk->parent))
-               return rate;
-
-       rate = clk->parent->rate;
-
-       /* Otherwise, the parent must be a PLL */
-       if (WARN_ON(!clk->parent->pll_data))
-               return rate;
-
-       pll = clk->parent->pll_data;
-
-       /* If pre-PLL, source clock is before the multiplier and divider(s) */
-       if (clk->flags & PRE_PLL)
-               rate = pll->input_rate;
-
-       if (!clk->div_reg)
-               return rate;
-
-       v = __raw_readl(pll->base + clk->div_reg);
-       if (v & PLLDIV_EN) {
-               plldiv = (v & pll->div_ratio_mask) + 1;
-               if (plldiv)
-                       rate /= plldiv;
-       }
-
-       return rate;
-}
-
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned v;
-       struct pll_data *pll;
-       unsigned long input;
-       unsigned ratio = 0;
-
-       /* If this is the PLL base clock, wrong function to call */
-       if (clk->pll_data)
-               return -EINVAL;
-
-       /* There must be a parent... */
-       if (WARN_ON(!clk->parent))
-               return -EINVAL;
-
-       /* ... the parent must be a PLL... */
-       if (WARN_ON(!clk->parent->pll_data))
-               return -EINVAL;
-
-       /* ... and this clock must have a divider. */
-       if (WARN_ON(!clk->div_reg))
-               return -EINVAL;
-
-       pll = clk->parent->pll_data;
-
-       input = clk->parent->rate;
-
-       /* If pre-PLL, source clock is before the multiplier and divider(s) */
-       if (clk->flags & PRE_PLL)
-               input = pll->input_rate;
-
-       if (input > rate) {
-               /*
-                * Can afford to provide an output little higher than requested
-                * only if maximum rate supported by hardware on this sysclk
-                * is known.
-                */
-               if (clk->maxrate) {
-                       ratio = DIV_ROUND_CLOSEST(input, rate);
-                       if (input / ratio > clk->maxrate)
-                               ratio = 0;
-               }
-
-               if (ratio == 0)
-                       ratio = DIV_ROUND_UP(input, rate);
-
-               ratio--;
-       }
-
-       if (ratio > pll->div_ratio_mask)
-               return -EINVAL;
-
-       do {
-               v = __raw_readl(pll->base + PLLSTAT);
-       } while (v & PLLSTAT_GOSTAT);
-
-       v = __raw_readl(pll->base + clk->div_reg);
-       v &= ~pll->div_ratio_mask;
-       v |= ratio | PLLDIV_EN;
-       __raw_writel(v, pll->base + clk->div_reg);
-
-       v = __raw_readl(pll->base + PLLCMD);
-       v |= PLLCMD_GOSET;
-       __raw_writel(v, pll->base + PLLCMD);
-
-       do {
-               v = __raw_readl(pll->base + PLLSTAT);
-       } while (v & PLLSTAT_GOSTAT);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_set_sysclk_rate);
-
-static unsigned long clk_leafclk_recalc(struct clk *clk)
-{
-       if (WARN_ON(!clk->parent))
-               return clk->rate;
-
-       return clk->parent->rate;
-}
-
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
-{
-       clk->rate = rate;
-       return 0;
-}
-
-static unsigned long clk_pllclk_recalc(struct clk *clk)
-{
-       u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
-       u8 bypass;
-       struct pll_data *pll = clk->pll_data;
-       unsigned long rate = clk->rate;
-
-       ctrl = __raw_readl(pll->base + PLLCTL);
-       rate = pll->input_rate = clk->parent->rate;
-
-       if (ctrl & PLLCTL_PLLEN) {
-               bypass = 0;
-               mult = __raw_readl(pll->base + PLLM);
-               if (cpu_is_davinci_dm365())
-                       mult = 2 * (mult & PLLM_PLLM_MASK);
-               else
-                       mult = (mult & PLLM_PLLM_MASK) + 1;
-       } else
-               bypass = 1;
-
-       if (pll->flags & PLL_HAS_PREDIV) {
-               prediv = __raw_readl(pll->base + PREDIV);
-               if (prediv & PLLDIV_EN)
-                       prediv = (prediv & pll->div_ratio_mask) + 1;
-               else
-                       prediv = 1;
-       }
-
-       /* pre-divider is fixed, but (some?) chips won't report that */
-       if (cpu_is_davinci_dm355() && pll->num == 1)
-               prediv = 8;
-
-       if (pll->flags & PLL_HAS_POSTDIV) {
-               postdiv = __raw_readl(pll->base + POSTDIV);
-               if (postdiv & PLLDIV_EN)
-                       postdiv = (postdiv & pll->div_ratio_mask) + 1;
-               else
-                       postdiv = 1;
-       }
-
-       if (!bypass) {
-               rate /= prediv;
-               rate *= mult;
-               rate /= postdiv;
-       }
-
-       pr_debug("PLL%d: input = %lu MHz [ ",
-                pll->num, clk->parent->rate / 1000000);
-       if (bypass)
-               pr_debug("bypass ");
-       if (prediv > 1)
-               pr_debug("/ %d ", prediv);
-       if (mult > 1)
-               pr_debug("* %d ", mult);
-       if (postdiv > 1)
-               pr_debug("/ %d ", postdiv);
-       pr_debug("] --> %lu MHz output.\n", rate / 1000000);
-
-       return rate;
-}
-
-/**
- * davinci_set_pllrate - set the output rate of a given PLL.
- *
- * Note: Currently tested to work with OMAP-L138 only.
- *
- * @pll: pll whose rate needs to be changed.
- * @prediv: The pre divider value. Passing 0 disables the pre-divider.
- * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
- * @postdiv: The post divider value. Passing 0 disables the post-divider.
- */
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
-                                       unsigned int mult, unsigned int postdiv)
-{
-       u32 ctrl;
-       unsigned int locktime;
-       unsigned long flags;
-
-       if (pll->base == NULL)
-               return -EINVAL;
-
-       /*
-        *  PLL lock time required per OMAP-L138 datasheet is
-        * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
-        * as 4 and OSCIN cycle as 25 MHz.
-        */
-       if (prediv) {
-               locktime = ((2000 * prediv) / 100);
-               prediv = (prediv - 1) | PLLDIV_EN;
-       } else {
-               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);
-
-       udelay(PLL_BYPASS_TIME);
-
-       /* Reset and enable PLL */
-       ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       if (pll->flags & PLL_HAS_PREDIV)
-               __raw_writel(prediv, pll->base + PREDIV);
-
-       __raw_writel(mult, pll->base + PLLM);
-
-       if (pll->flags & PLL_HAS_POSTDIV)
-               __raw_writel(postdiv, pll->base + POSTDIV);
-
-       udelay(PLL_RESET_TIME);
-
-       /* Bring PLL out of reset */
-       ctrl |= PLLCTL_PLLRST;
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       udelay(locktime);
-
-       /* Remove PLL from bypass mode */
-       ctrl |= PLLCTL_PLLEN;
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_set_pllrate);
-
-struct clk * __init davinci_clk_init(struct clk *clk)
-{
-       if (!clk->recalc) {
-
-               /* Check if clock is a PLL */
-               if (clk->pll_data)
-                       clk->recalc = clk_pllclk_recalc;
-
-               /* Else, if it is a PLL-derived clock */
-               else if (clk->flags & CLK_PLL)
-                       clk->recalc = clk_sysclk_recalc;
-
-               /* Otherwise, it is a leaf clock (PSC clock) */
-               else if (clk->parent)
-                       clk->recalc = clk_leafclk_recalc;
-       }
-
-       if (clk->pll_data) {
-               struct pll_data *pll = clk->pll_data;
-
-               if (!pll->div_ratio_mask)
-                       pll->div_ratio_mask = PLLDIV_RATIO_MASK;
-
-               if (pll->phys_base && !pll->base) {
-                       pll->base = ioremap(pll->phys_base, SZ_4K);
-                       WARN_ON(!pll->base);
-               }
-       }
-
-       if (clk->recalc)
-               clk->rate = clk->recalc(clk);
-
-       if (clk->lpsc)
-               clk->flags |= CLK_PSC;
-
-       if (clk->flags & PSC_LRST)
-               clk->reset = davinci_clk_reset;
-
-       clk_register(clk);
-
-       /* Turn on clocks that Linux doesn't otherwise manage */
-       if (clk->flags & ALWAYS_ENABLED)
-               clk_enable(clk);
-
-       return clk;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#define CLKNAME_MAX    10              /* longest clock name */
-#define NEST_DELTA     2
-#define NEST_MAX       4
-
-static void
-dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
-{
-       char            *state;
-       char            buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
-       struct clk      *clk;
-       unsigned        i;
-
-       if (parent->flags & CLK_PLL)
-               state = "pll";
-       else if (parent->flags & CLK_PSC)
-               state = "psc";
-       else
-               state = "";
-
-       /* <nest spaces> name <pad to end> */
-       memset(buf, ' ', sizeof(buf) - 1);
-       buf[sizeof(buf) - 1] = 0;
-       i = strlen(parent->name);
-       memcpy(buf + nest, parent->name,
-                       min(i, (unsigned)(sizeof(buf) - 1 - nest)));
-
-       seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
-                  buf, parent->usecount, state, clk_get_rate(parent));
-       /* REVISIT show device associations too */
-
-       /* cost is now small, but not linear... */
-       list_for_each_entry(clk, &parent->children, childnode) {
-               dump_clock(s, nest + NEST_DELTA, clk);
-       }
-}
-
-static int davinci_ck_show(struct seq_file *m, void *v)
-{
-       struct clk *clk;
-
-       /*
-        * Show clock tree; We trust nonzero usecounts equate to PSC enables...
-        */
-       mutex_lock(&clocks_mutex);
-       list_for_each_entry(clk, &clocks, node)
-               if (!clk->parent)
-                       dump_clock(m, 0, clk);
-       mutex_unlock(&clocks_mutex);
-
-       return 0;
-}
-
-static int davinci_ck_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, davinci_ck_show, NULL);
-}
-
-static const struct file_operations davinci_ck_operations = {
-       .open           = davinci_ck_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init davinci_clk_debugfs_init(void)
-{
-       debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
-                                               &davinci_ck_operations);
-       return 0;
-
-}
-device_initcall(davinci_clk_debugfs_init);
-#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 61fcdaa..d113f89 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -14,7 +14,6 @@
 
 #define DAVINCI_PLL1_BASE 0x01c40800
 #define DAVINCI_PLL2_BASE 0x01c40c00
-#define MAX_PLL 2
 
 /* PLL/Reset register offsets */
 #define PLLCTL          0x100
@@ -65,67 +64,4 @@
  */
 #define PLL_LOCK_TIME          20
 
-#ifndef __ASSEMBLER__
-
-#include <linux/list.h>
-#include <linux/clkdev.h>
-
-#define PLLSTAT_GOSTAT BIT(0)
-#define PLLCMD_GOSET   BIT(0)
-
-struct pll_data {
-       u32 phys_base;
-       void __iomem *base;
-       u32 num;
-       u32 flags;
-       u32 input_rate;
-       u32 div_ratio_mask;
-};
-#define PLL_HAS_PREDIV          0x01
-#define PLL_HAS_POSTDIV         0x02
-
-struct clk {
-       struct list_head        node;
-       struct module           *owner;
-       const char              *name;
-       unsigned long           rate;
-       unsigned long           maxrate;        /* H/W supported max rate */
-       u8                      usecount;
-       u8                      lpsc;
-       u8                      gpsc;
-       u8                      domain;
-       u32                     flags;
-       struct clk              *parent;
-       struct list_head        children;       /* list of children */
-       struct list_head        childnode;      /* parent's child list node */
-       struct pll_data         *pll_data;
-       u32                     div_reg;
-       unsigned long (*recalc) (struct clk *);
-       int (*set_rate) (struct clk *clk, unsigned long rate);
-       int (*round_rate) (struct clk *clk, unsigned long rate);
-       int (*reset) (struct clk *clk, bool reset);
-       void (*clk_enable) (struct clk *clk);
-       void (*clk_disable) (struct clk *clk);
-       int (*set_parent) (struct clk *clk, struct clk *parent);
-};
-
-/* Clock flags: SoC-specific flags start at BIT(16) */
-#define ALWAYS_ENABLED         BIT(1)
-#define CLK_PSC                        BIT(2)
-#define CLK_PLL                        BIT(3) /* PLL-derived clock */
-#define PRE_PLL                        BIT(4) /* source is before PLL mult/div 
*/
-#define PSC_SWRSTDISABLE       BIT(5) /* Disable state is SwRstDisable */
-#define PSC_FORCE              BIT(6) /* Force module state transtition */
-#define PSC_LRST               BIT(8) /* Use local reset on enable/disable */
-
-struct clk *davinci_clk_init(struct clk *clk);
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
-                               unsigned int mult, unsigned int postdiv);
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
-int davinci_clk_reset(struct clk *clk, bool reset);
-void davinci_clk_enable(struct clk *clk);
-void davinci_clk_disable(struct clk *clk);
-#endif
-
 #endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index bcb6a7b..e03f95c 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -118,5 +118,4 @@ void __init davinci_common_init(const struct 
davinci_soc_info *soc_info)
 void __init davinci_init_late(void)
 {
        davinci_cpufreq_init();
-       davinci_clk_disable_unused();
 }
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index b0e54a1..5ea0815 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -8,22 +8,24 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
-#include <linux/clk.h>
 #include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
 #include <mach/da8xx.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
 
 #include "clock.h"
 #include "mux.h"
+#include "psc.h"
 
 /* Offsets of the 8 compare registers on the da830 */
 #define DA830_CMP12_0          0x60
@@ -37,405 +39,122 @@
 
 #define DA830_REF_FREQ         24000000
 
-static struct pll_data pll0_data = {
-       .num            = 1,
-       .phys_base      = DA8XX_PLL0_BASE,
-       .flags          = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DA830_REF_FREQ,
-};
-
-static struct clk pll0_clk = {
-       .name           = "pll0",
-       .parent         = &ref_clk,
-       .pll_data       = &pll0_data,
-       .flags          = CLK_PLL,
-};
-
-static struct clk pll0_aux_clk = {
-       .name           = "pll0_aux_clk",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk2 = {
-       .name           = "pll0_sysclk2",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
-       .name           = "pll0_sysclk3",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll0_sysclk4 = {
-       .name           = "pll0_sysclk4",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
-       .name           = "pll0_sysclk5",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
-       .name           = "pll0_sysclk6",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
-       .name           = "pll0_sysclk7",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk i2c0_clk = {
-       .name           = "i2c0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
-       .name           = "timer0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
-       .name           = "timer1",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
-       .name           = "arm_rom",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_ARM_RAM_ROM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr0_ss_clk = {
-       .name           = "scr0_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR0_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr1_ss_clk = {
-       .name           = "scr1_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR1_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr2_ss_clk = {
-       .name           = "scr2_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR2_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk dmax_clk = {
-       .name           = "dmax",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_PRUSS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc_clk = {
-       .name           = "tpcc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPCC,
-       .flags          = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
-       .name           = "tptc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC0,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
-       .name           = "tptc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk mmcsd_clk = {
-       .name           = "mmcsd",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_UART1,
-       .gpsc           = 1,
-};
-
-static struct clk uart2_clk = {
-       .name           = "uart2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_UART2,
-       .gpsc           = 1,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_SPI1,
-       .gpsc           = 1,
-};
-
-static struct clk ecap_clk = {
-       .name           = "ecap",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
-static struct clk pwm_clk = {
-       .name           = "pwm",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-static struct clk eqep_clk = {
-       .name           = "eqep",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_EQEP,
-       .gpsc           = 1,
-};
-
-static struct clk lcdc_clk = {
-       .name           = "lcdc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_LCDC,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp0_clk = {
-       .name           = "mcasp0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_McASP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp1_clk = {
-       .name           = "mcasp1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_McASP1,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp2_clk = {
-       .name           = "mcasp2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_McASP2,
-       .gpsc           = 1,
-};
-
-static struct clk usb20_clk = {
-       .name           = "usb20",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_USB20,
-       .gpsc           = 1,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll0_sysclk3,
-       .lpsc           = DA8XX_LPSC0_EMIF25,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk aintc_clk = {
-       .name           = "aintc",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_AINTC,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk secu_mgr_clk = {
-       .name           = "secu_mgr",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_SECU_MGR,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_CPGMAC,
-       .gpsc           = 1,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_GPIO,
-       .gpsc           = 1,
-};
-
-static struct clk i2c1_clk = {
-       .name           = "i2c1",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_I2C,
-       .gpsc           = 1,
-};
-
-static struct clk usb11_clk = {
-       .name           = "usb11",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_USB11,
-       .gpsc           = 1,
-};
-
-static struct clk emif3_clk = {
-       .name           = "emif3",
-       .parent         = &pll0_sysclk5,
-       .lpsc           = DA8XX_LPSC1_EMIF3C,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm",
-       .parent         = &pll0_sysclk6,
-       .lpsc           = DA8XX_LPSC0_ARM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk rmii_clk = {
-       .name           = "rmii",
-       .parent         = &pll0_sysclk7,
-};
-
 static __init void da830_clk_init(void)
 {
+       void __iomem *pll0, *psc0, *psc1;
        struct clk *clk;
 
-       clk = davinci_clk_init(&ref_clk);
+       pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+       psc0 = ioremap(DA8XX_PSC0_BASE, SZ_4K);
+       psc1 = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+
+       clk = EXT_CLK("ref_clk", DA830_REF_FREQ);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&pll0_clk);
+       clk = PLL_CLK("pll0", "ref_clk", pll0);
        clk_register_clkdev(clk, "pll0", NULL);
-       clk = davinci_clk_init(&pll0_aux_clk);
+       clk = PLL_AUX_CLK("pll0_aux_clk", "ref_clk", pll0);
        clk_register_clkdev(clk, "pll0_aux", NULL);
-       clk = davinci_clk_init(&pll0_sysclk2);
+       clk = PLL_DIV_CLK("pll0_sysclk2", "pll0", pll0, 2);
        clk_register_clkdev(clk, "pll0_sysclk2", NULL);
-       clk = davinci_clk_init(&pll0_sysclk3);
+       clk = PLL_DIV_CLK("pll0_sysclk3", "pll0", pll0, 3);
        clk_register_clkdev(clk, "pll0_sysclk3", NULL);
-       clk = davinci_clk_init(&pll0_sysclk4);
+       clk = PLL_DIV_CLK("pll0_sysclk4", "pll0", pll0, 4);
        clk_register_clkdev(clk, "pll0_sysclk4", NULL);
-       clk = davinci_clk_init(&pll0_sysclk5);
+       clk = PLL_DIV_CLK("pll0_sysclk5", "pll0", pll0, 5);
        clk_register_clkdev(clk, "pll0_sysclk5", NULL);
-       clk = davinci_clk_init(&pll0_sysclk6);
+       clk = PLL_DIV_CLK("pll0_sysclk6", "pll0", pll0, 6);
        clk_register_clkdev(clk, "pll0_sysclk6", NULL);
-       clk = davinci_clk_init(&pll0_sysclk7);
+       clk = PLL_DIV_CLK("pll0_sysclk7", "pll0", pll0, 7);
        clk_register_clkdev(clk, "pll0_sysclk7", NULL);
-       clk = davinci_clk_init(&i2c0_clk);
+       clk = FIX_CLK("i2c0", "pll0_aux_clk");
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&timerp64_0_clk);
+       clk = FIX_CLK("timer0", "pll0_aux_clk");
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timerp64_1_clk);
+       clk = FIX_CLK("timer1", "pll0_aux_clk");
        clk_register_clkdev(clk, NULL, "davinci-wdt");
-       clk = davinci_clk_init(&arm_rom_clk);
+       clk = PSC_CLK("arm_rom", "pll0_sysclk2", psc0, DA8XX_LPSC0_ARM_RAM_ROM, 
0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm_rom", NULL);
-       clk = davinci_clk_init(&scr0_ss_clk);
+       clk = PSC_CLK("scr0_ss", "pll0_sysclk2", psc0, DA8XX_LPSC0_SCR0_SS, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "scr0_ss", NULL);
-       clk = davinci_clk_init(&scr1_ss_clk);
+       clk = PSC_CLK("scr1_ss", "pll0_sysclk2", psc0, DA8XX_LPSC0_SCR1_SS, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "scr1_ss", NULL);
-       clk = davinci_clk_init(&scr2_ss_clk);
+       clk = PSC_CLK("scr2_ss", "pll0_sysclk2", psc0, DA8XX_LPSC0_SCR2_SS, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "scr2_ss", NULL);
-       clk = davinci_clk_init(&dmax_clk);
+       clk = PSC_CLK("dmax", "pll0_sysclk2", psc0, DA8XX_LPSC0_PRUSS, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "dmax", NULL);
-       clk = davinci_clk_init(&tpcc_clk);
+       clk = PSC_CLK("tpcc", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPCC, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "tpcc", NULL);
-       clk = davinci_clk_init(&tptc0_clk);
+       clk = PSC_CLK("tptc0", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPTC0, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "tptc0", NULL);
-       clk = davinci_clk_init(&tptc1_clk);
+       clk = PSC_CLK("tptc1", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPTC1, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "tptc1", NULL);
-       clk = davinci_clk_init(&mmcsd_clk);
+       clk = PSC_CLK("mmcsd", "pll0_sysclk2", psc0, DA8XX_LPSC0_MMC_SD, 0);
        clk_register_clkdev(clk, NULL, "da830-mmc.0");
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "pll0_sysclk2", psc0, DA8XX_LPSC0_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "pll0_sysclk2", psc1, DA8XX_LPSC1_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&uart2_clk);
+       clk = PSC_CLK("uart2", "pll0_sysclk2", psc1, DA8XX_LPSC1_UART2, 0);
        clk_register_clkdev(clk, NULL, "serial8250.2");
-       clk = davinci_clk_init(&spi0_clk);
+       clk = PSC_CLK("spi0", "pll0_sysclk2", psc0, DA8XX_LPSC0_SPI0, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.0");
-       clk = davinci_clk_init(&spi1_clk);
+       clk = PSC_CLK("spi1", "pll0_sysclk2", psc1, DA8XX_LPSC1_SPI1, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.1");
-       clk = davinci_clk_init(&ecap_clk);
+       clk = PSC_CLK("ecap", "pll0_sysclk2", psc1, DA8XX_LPSC1_ECAP, 0);
        clk_register_clkdev(clk, "ecap0", NULL);
        clk_register_clkdev(clk, "ecap1", NULL);
        clk_register_clkdev(clk, "ecap2", NULL);
-       clk = davinci_clk_init(&pwm_clk);
+       clk = PSC_CLK("pwm", "pll0_sysclk2", psc1, DA8XX_LPSC1_PWM, 0);
        clk_register_clkdev(clk, "pwm0", NULL);
        clk_register_clkdev(clk, "pwm1", NULL);
        clk_register_clkdev(clk, "pwm2", NULL);
-       clk = davinci_clk_init(&eqep_clk);
+       clk = PSC_CLK("eqep", "pll0_sysclk2", psc1, DA830_LPSC1_EQEP, 0);
        clk_register_clkdev(clk, NULL, "eqep.0");
        clk_register_clkdev(clk, NULL, "eqep.1");
-       clk = davinci_clk_init(&lcdc_clk);
+       clk = PSC_CLK("lcdc", "pll0_sysclk2", psc1, DA8XX_LPSC1_LCDC, 0);
        clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
-       clk = davinci_clk_init(&mcasp0_clk);
+       clk = PSC_CLK("mcasp0", "pll0_sysclk2", psc1, DA8XX_LPSC1_McASP0, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
-       clk = davinci_clk_init(&mcasp1_clk);
+       clk = PSC_CLK("mcasp1", "pll0_sysclk2", psc1, DA830_LPSC1_McASP1, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
-       clk = davinci_clk_init(&mcasp2_clk);
+       clk = PSC_CLK("mcasp2", "pll0_sysclk2", psc1, DA830_LPSC1_McASP2, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.2");
-       clk = davinci_clk_init(&usb20_clk);
+       clk = PSC_CLK("usb20", "pll0_sysclk2", psc1, DA8XX_LPSC1_USB20, 0);
        clk_register_clkdev(clk, "usb20", "musb-da8xx");
        clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll0_sysclk3", psc0, DA8XX_LPSC0_EMIF25, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "aemif", NULL);
-       clk = davinci_clk_init(&aintc_clk);
+       clk = PSC_CLK("aintc", "pll0_sysclk4", psc0, DA8XX_LPSC0_AINTC, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "aintc", NULL);
-       clk = davinci_clk_init(&secu_mgr_clk);
+       clk = PSC_CLK("secu_mgr", "pll0_sysclk4", psc0, DA8XX_LPSC0_SECU_MGR, 
0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "secu_mgr", NULL);
-       clk = davinci_clk_init(&emac_clk);
+       clk = PSC_CLK("emac", "pll0_sysclk4", psc1, DA8XX_LPSC1_CPGMAC, 0);
        clk_register_clkdev(clk, NULL, "davinci_emac.1");
        clk_register_clkdev(clk, "fck", "davinci_mdio.0");
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll0_sysclk4", psc1, DA8XX_LPSC1_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&i2c1_clk);
+       clk = PSC_CLK("i2c1", "pll0_sysclk4", psc1, DA8XX_LPSC1_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.2");
-       clk = davinci_clk_init(&usb11_clk);
+       clk = PSC_CLK("usb11", "pll0_sysclk4", psc1, DA8XX_LPSC1_USB11, 0);
        clk_register_clkdev(clk, "usb11", "ohci-da8xx");
-       clk = davinci_clk_init(&emif3_clk);
+       clk = PSC_CLK("emif3", "pll0_sysclk5", psc1, DA8XX_LPSC1_EMIF3C, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "emif3", NULL);
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm", "pll0_sysclk6", psc0, DA8XX_LPSC0_ARM, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&rmii_clk);
+       clk = FIX_CLK("rmii", "pll0_sysclk7");
        clk_register_clkdev(clk, "rmii", NULL);
 }
 
@@ -1136,8 +855,6 @@ static struct map_desc da830_io_desc[] = {
        },
 };
 
-static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da830_ids[] = {
        {
@@ -1206,8 +923,6 @@ static const struct davinci_soc_info 
davinci_soc_info_da830 = {
        .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da830_ids,
        .ids_num                = ARRAY_SIZE(da830_ids),
-       .psc_bases              = da830_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(da830_psc_bases),
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da830_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da830_pins),
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 0975edb..a630c10 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -11,28 +11,29 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
 #include <linux/clkdev.h>
+#include <linux/cpufreq.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
-#include <linux/clk.h>
+#include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_device.h>
-#include <linux/cpufreq.h>
 #include <linux/regulator/consumer.h>
-#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <mach/common.h>
-#include <mach/time.h>
-#include <mach/da8xx.h>
 #include <mach/cpufreq.h>
+#include <mach/cputype.h>
+#include <mach/da8xx.h>
+#include <mach/irqs.h>
 #include <mach/pm.h>
+#include <mach/time.h>
 
 #include "clock.h"
 #include "mux.h"
+#include "psc.h"
 
 #define DA850_PLL1_BASE                0x01e1a000
 #define DA850_TIMER64P2_BASE   0x01f0c000
@@ -40,537 +41,148 @@
 
 #define DA850_REF_FREQ         24000000
 
-#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
+#define CFGCHIP1_TBCLKSYNC     12
+#define CFGCHIP3_ASYNC3_CLKSRC 4
 #define CFGCHIP3_PLL1_MASTER_LOCK      BIT(5)
 #define CFGCHIP0_PLL_MASTER_LOCK       BIT(4)
 
-static int da850_set_armrate(struct clk *clk, unsigned long rate);
-static int da850_round_armrate(struct clk *clk, unsigned long rate);
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
-
-static struct pll_data pll0_data = {
-       .num            = 1,
-       .phys_base      = DA8XX_PLL0_BASE,
-       .flags          = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DA850_REF_FREQ,
-       .set_rate       = davinci_simple_set_rate,
-};
-
-static struct clk pll0_clk = {
-       .name           = "pll0",
-       .parent         = &ref_clk,
-       .pll_data       = &pll0_data,
-       .flags          = CLK_PLL,
-       .set_rate       = da850_set_pll0rate,
-};
-
-static struct clk pll0_aux_clk = {
-       .name           = "pll0_aux_clk",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk1 = {
-       .name           = "pll0_sysclk1",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll0_sysclk2 = {
-       .name           = "pll0_sysclk2",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
-       .name           = "pll0_sysclk3",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-       .set_rate       = davinci_set_sysclk_rate,
-       .maxrate        = 100000000,
-};
-
-static struct clk pll0_sysclk4 = {
-       .name           = "pll0_sysclk4",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
-       .name           = "pll0_sysclk5",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
-       .name           = "pll0_sysclk6",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
-       .name           = "pll0_sysclk7",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct pll_data pll1_data = {
-       .num            = 2,
-       .phys_base      = DA850_PLL1_BASE,
-       .flags          = PLL_HAS_POSTDIV,
-};
-
-static struct clk pll1_clk = {
-       .name           = "pll1",
-       .parent         = &ref_clk,
-       .pll_data       = &pll1_data,
-       .flags          = CLK_PLL,
-};
-
-static struct clk pll1_aux_clk = {
-       .name           = "pll1_aux_clk",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name           = "pll1_sysclk2",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name           = "pll1_sysclk3",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static int da850_async3_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
-       if (parent == &pll0_sysclk2) {
-               val &= ~CFGCHIP3_ASYNC3_CLKSRC;
-       } else if (parent == &pll1_sysclk2) {
-               val |= CFGCHIP3_ASYNC3_CLKSRC;
-       } else {
-               pr_err("Bad parent on async3 clock mux\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
-       return 0;
-}
-
-static struct clk async3_clk = {
-       .name           = "async3",
-       .parent         = &pll1_sysclk2,
-       .set_parent     = da850_async3_set_parent,
-};
-
-static struct clk i2c0_clk = {
-       .name           = "i2c0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
-       .name           = "timer0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
-       .name           = "timer1",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
-       .name           = "arm_rom",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_ARM_RAM_ROM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc0_clk = {
-       .name           = "tpcc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPCC,
-       .flags          = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
-       .name           = "tptc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC0,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
-       .name           = "tptc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc1_clk = {
-       .name           = "tpcc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_TPCC1,
-       .gpsc           = 1,
-       .flags          = CLK_PSC | ALWAYS_ENABLED,
-};
-
-static struct clk tptc2_clk = {
-       .name           = "tptc2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_TPTC2,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk pruss_clk = {
-       .name           = "pruss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_PRUSS,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_UART1,
-       .gpsc           = 1,
-};
-
-static struct clk uart2_clk = {
-       .name           = "uart2",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_UART2,
-       .gpsc           = 1,
-};
-
-static struct clk aintc_clk = {
-       .name           = "aintc",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_AINTC,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_GPIO,
-       .gpsc           = 1,
-};
-
-static struct clk i2c1_clk = {
-       .name           = "i2c1",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_I2C,
-       .gpsc           = 1,
-};
-
-static struct clk emif3_clk = {
-       .name           = "emif3",
-       .parent         = &pll0_sysclk5,
-       .lpsc           = DA8XX_LPSC1_EMIF3C,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm",
-       .parent         = &pll0_sysclk6,
-       .lpsc           = DA8XX_LPSC0_ARM,
-       .flags          = ALWAYS_ENABLED,
-       .set_rate       = da850_set_armrate,
-       .round_rate     = da850_round_armrate,
-};
-
-static struct clk rmii_clk = {
-       .name           = "rmii",
-       .parent         = &pll0_sysclk7,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_CPGMAC,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp_clk = {
-       .name           = "mcasp",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_McASP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcbsp0_clk = {
-       .name           = "mcbsp0",
-       .parent         = &async3_clk,
-       .lpsc           = DA850_LPSC1_McBSP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcbsp1_clk = {
-       .name           = "mcbsp1",
-       .parent         = &async3_clk,
-       .lpsc           = DA850_LPSC1_McBSP1,
-       .gpsc           = 1,
-};
-
-static struct clk lcdc_clk = {
-       .name           = "lcdc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_LCDC,
-       .gpsc           = 1,
-};
-
-static struct clk mmcsd0_clk = {
-       .name           = "mmcsd0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name           = "mmcsd1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_MMC_SD1,
-       .gpsc           = 1,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll0_sysclk3,
-       .lpsc           = DA8XX_LPSC0_EMIF25,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk usb11_clk = {
-       .name           = "usb11",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_USB11,
-       .gpsc           = 1,
-};
-
-static struct clk usb20_clk = {
-       .name           = "usb20",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_USB20,
-       .gpsc           = 1,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_SPI1,
-       .gpsc           = 1,
-};
-
-static struct clk vpif_clk = {
-       .name           = "vpif",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_VPIF,
-       .gpsc           = 1,
-};
-
-static struct clk sata_clk = {
-       .name           = "sata",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_SATA,
-       .gpsc           = 1,
-       .flags          = PSC_FORCE,
-};
-
-static struct clk dsp_clk = {
-       .name           = "dsp",
-       .parent         = &pll0_sysclk1,
-       .domain         = DAVINCI_GPSC_DSPDOMAIN,
-       .lpsc           = DA8XX_LPSC0_GEM,
-       .flags          = PSC_LRST | PSC_FORCE,
-};
-
-static struct clk ehrpwm_clk = {
-       .name           = "ehrpwm",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
-
-static void ehrpwm_tblck_enable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-       val |= DA8XX_EHRPWM_TBCLKSYNC;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static void ehrpwm_tblck_disable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-       val &= ~DA8XX_EHRPWM_TBCLKSYNC;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static struct clk ehrpwm_tbclk = {
-       .name           = "ehrpwm_tbclk",
-       .parent         = &ehrpwm_clk,
-       .clk_enable     = ehrpwm_tblck_enable,
-       .clk_disable    = ehrpwm_tblck_disable,
-};
-
-
-static struct clk ecap_clk = {
-       .name           = "ecap",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
 static __init void da850_clk_init(void)
 {
-       struct clk *clk;
+       void __iomem *pll0, *pll1, *psc0, *psc1;
+       struct clk *clk, *pll1_sysclk2_clk;
+
+       pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+       pll1 = ioremap(DA850_PLL1_BASE, SZ_4K);
+       psc0 = ioremap(DA8XX_PSC0_BASE, SZ_4K);
+       psc1 = ioremap(DA8XX_PSC1_BASE, SZ_4K);
 
-       clk = davinci_clk_init(&ref_clk);
+       clk = EXT_CLK("ref_clk", DA850_REF_FREQ);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&pll0_clk);
+       clk = PLL_CLK("pll0", "ref_clk", pll0);
        clk_register_clkdev(clk, "pll0", NULL);
-       clk = davinci_clk_init(&pll0_aux_clk);
-       clk_register_clkdev(clk, "pll0_aux", NULL);
-       clk = davinci_clk_init(&pll0_sysclk1);
+       clk = PLL_AUX_CLK("pll0_aux_clk", "ref_clk", pll0);
+       clk_register_clkdev(clk, "pll0_aux", "da8xx-cfgchip-clk");
+       clk = PLL_DIV_CLK("pll0_sysclk1", "pll0", pll0, 1);
        clk_register_clkdev(clk, "pll0_sysclk1", NULL);
-       clk = davinci_clk_init(&pll0_sysclk2);
+       clk = PLL_DIV_CLK("pll0_sysclk2", "pll0", pll0, 2);
        clk_register_clkdev(clk, "pll0_sysclk2", NULL);
-       clk = davinci_clk_init(&pll0_sysclk3);
+       clk = PLL_DIV_CLK("pll0_sysclk3", "pll0", pll0, 3);
        clk_register_clkdev(clk, "pll0_sysclk3", NULL);
-       clk = davinci_clk_init(&pll0_sysclk4);
+       clk = PLL_DIV_CLK("pll0_sysclk4", "pll0", pll0, 4);
        clk_register_clkdev(clk, "pll0_sysclk4", NULL);
-       clk = davinci_clk_init(&pll0_sysclk5);
+       clk = PLL_DIV_CLK("pll0_sysclk5", "pll0", pll0, 5);
        clk_register_clkdev(clk, "pll0_sysclk5", NULL);
-       clk = davinci_clk_init(&pll0_sysclk6);
+       clk = PLL_DIV_CLK("pll0_sysclk6", "pll0", pll0, 6);
        clk_register_clkdev(clk, "pll0_sysclk6", NULL);
-       clk = davinci_clk_init(&pll0_sysclk7);
+       clk = PLL_DIV_CLK("pll0_sysclk7", "pll0", pll0, 7);
        clk_register_clkdev(clk, "pll0_sysclk7", NULL);
-       clk = davinci_clk_init(&pll1_clk);
+       clk = PLL_CLK("pll1", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1", NULL);
-       clk = davinci_clk_init(&pll1_aux_clk);
+       clk = PLL_AUX_CLK("pll1_aux_clk", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_aux", NULL);
-       clk = davinci_clk_init(&pll1_sysclk2);
+       clk = PLL_DIV_CLK("pll1_sysclk2", "pll1", pll1, 2);
+       pll1_sysclk2_clk = clk;
        clk_register_clkdev(clk, "pll1_sysclk2", NULL);
-       clk = davinci_clk_init(&pll1_sysclk3);
+       clk = PLL_DIV_CLK("pll1_sysclk3", "pll1", pll1, 3);
        clk_register_clkdev(clk, "pll1_sysclk3", NULL);
-       clk = davinci_clk_init(&async3_clk);
+       clk = clk_register_mux(NULL, "async3",
+               (const char * const[]){ "pll0_sysclk2", "pll1_sysclk2" }, 2, 0,
+               DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG), CFGCHIP3_ASYNC3_CLKSRC,
+               1, 0, NULL);
+       /* pll1_sysclk2 is not affected by CPU scaling, so use it */
+       clk_set_parent(clk, pll1_sysclk2_clk);
        clk_register_clkdev(clk, "async3", NULL);
-       clk = davinci_clk_init(&i2c0_clk);
+       clk = FIX_CLK("i2c0", "pll0_aux_clk");
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&timerp64_0_clk);
+       clk = FIX_CLK("timer0", "pll0_aux_clk");
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timerp64_1_clk);
+       clk = FIX_CLK("timer1", "pll0_aux_clk");
        clk_register_clkdev(clk, NULL, "davinci-wdt");
-       clk = davinci_clk_init(&arm_rom_clk);
+       clk = PSC_CLK("arm_rom", "pll0_sysclk2", psc0, DA8XX_LPSC0_ARM_RAM_ROM, 
0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "arm_rom", NULL);
-       clk = davinci_clk_init(&tpcc0_clk);
+       clk = PSC_CLK("tpcc0", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPCC, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "tpcc0", NULL);
-       clk = davinci_clk_init(&tptc0_clk);
+       clk = PSC_CLK("tptc0", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPTC0, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "tptc0", NULL);
-       clk = davinci_clk_init(&tptc1_clk);
+       clk = PSC_CLK("tptc1", "pll0_sysclk2", psc0, DA8XX_LPSC0_TPTC1, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "tptc1", NULL);
-       clk = davinci_clk_init(&tpcc1_clk);
+       clk = PSC_CLK("tpcc1", "pll0_sysclk2", psc1, DA850_LPSC1_TPCC1, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "tpcc1", NULL);
-       clk = davinci_clk_init(&tptc2_clk);
+       clk = PSC_CLK("tptc2", "pll0_sysclk2", psc1, DA850_LPSC1_TPTC2, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "tptc2", NULL);
-       clk = davinci_clk_init(&pruss_clk);
+       clk = PSC_CLK("pruss", "pll0_sysclk2", psc0, DA8XX_LPSC0_PRUSS, 0);
        clk_register_clkdev(clk, "pruss", "pruss_uio");
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "pll0_sysclk2", psc0, DA8XX_LPSC0_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "async3", psc1, DA8XX_LPSC1_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&uart2_clk);
+       clk = PSC_CLK("uart2", "async3", psc1, DA8XX_LPSC1_UART2, 0);
        clk_register_clkdev(clk, NULL, "serial8250.2");
-       clk = davinci_clk_init(&aintc_clk);
+       clk = PSC_CLK("aintc", "pll0_sysclk4", psc0, DA8XX_LPSC0_AINTC, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "aintc", NULL);
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll0_sysclk4", psc1, DA8XX_LPSC1_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&i2c1_clk);
+       clk = PSC_CLK("i2c1", "pll0_sysclk4", psc1, DA8XX_LPSC1_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.2");
-       clk = davinci_clk_init(&emif3_clk);
+       clk = PSC_CLK("emif3", "pll0_sysclk5", psc1, DA8XX_LPSC1_EMIF3C, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "emif3", NULL);
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm", "pll0_sysclk6", psc0, DA8XX_LPSC0_ARM, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&rmii_clk);
+       clk = FIX_CLK("rmii", "pll0_sysclk7");
        clk_register_clkdev(clk, "rmii", NULL);
-       clk = davinci_clk_init(&emac_clk);
+       clk = PSC_CLK("emac", "pll0_sysclk4", psc1, DA8XX_LPSC1_CPGMAC, 0);
        clk_register_clkdev(clk, NULL, "davinci_emac.1");
        clk_register_clkdev(clk, "fck", "davinci_mdio.0");
-       clk = davinci_clk_init(&mcasp_clk);
+       clk = PSC_CLK("mcasp", "async3", psc1, DA8XX_LPSC1_McASP0, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
-       clk = davinci_clk_init(&mcbsp0_clk);
+       clk = PSC_CLK("mcbsp0", "async3", psc1, DA850_LPSC1_McBSP0, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
-       clk = davinci_clk_init(&mcbsp1_clk);
+       clk = PSC_CLK("mcbsp1", "async3", psc1, DA850_LPSC1_McBSP1, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
-       clk = davinci_clk_init(&lcdc_clk);
+       clk = PSC_CLK("lcdc", "pll0_sysclk2", psc1, DA8XX_LPSC1_LCDC, 0);
        clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
-       clk = davinci_clk_init(&mmcsd0_clk);
+       clk = PSC_CLK("mmcsd0", "pll0_sysclk2", psc0, DA8XX_LPSC0_MMC_SD, 0);
        clk_register_clkdev(clk, NULL, "da830-mmc.0");
-       clk = davinci_clk_init(&mmcsd1_clk);
+       clk = PSC_CLK("mmcsd1", "pll0_sysclk2", psc1, DA850_LPSC1_MMC_SD1, 0);
        clk_register_clkdev(clk, NULL, "da830-mmc.1");
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll0_sysclk3", psc0, DA8XX_LPSC0_EMIF25, 0);
+       clk_prepare_enable(clk); /* always on */
        clk_register_clkdev(clk, NULL, "ti-aemif");
        clk_register_clkdev(clk, "aemif", "davinci-nand.0");
-       clk = davinci_clk_init(&usb11_clk);
+       clk = PSC_CLK("usb11", "pll0_sysclk4", psc1, DA8XX_LPSC1_USB11, 0);
        clk_register_clkdev(clk, "usb11", "ohci-da8xx");
-       clk = davinci_clk_init(&usb20_clk);
+       clk = PSC_CLK("usb20", "pll0_sysclk2", psc1, DA8XX_LPSC1_USB20, 0);
+       clk_register_clkdev(clk, "usb20", "da8xx-cfgchip-clk");
        clk_register_clkdev(clk, "usb20", "musb-da8xx");
        clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
-       clk = davinci_clk_init(&spi0_clk);
+       clk = PSC_CLK("spi0", "pll0_sysclk2", psc0, DA8XX_LPSC0_SPI0, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.0");
-       clk = davinci_clk_init(&spi1_clk);
+       clk = PSC_CLK("spi1", "async3", psc1, DA8XX_LPSC1_SPI1, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.1");
-       clk = davinci_clk_init(&vpif_clk);
+       clk = PSC_CLK("vpif", "pll0_sysclk2", psc1, DA850_LPSC1_VPIF, 0);
        clk_register_clkdev(clk, NULL, "vpif");
-       clk = davinci_clk_init(&sata_clk);
+       clk = PSC_CLK("sata", "pll0_sysclk2", psc1, DA850_LPSC1_SATA, 0);
        clk_register_clkdev(clk, "fck", "ahci_da850");
-       clk = davinci_clk_init(&dsp_clk);
+       clk = PSC_CLK("dsp", "pll0_sysclk1", psc0, DA8XX_LPSC0_GEM, 1);
        clk_register_clkdev(clk, NULL, "davinci-rproc.0");
-       clk = davinci_clk_init(&ehrpwm_clk);
+       clk = PSC_CLK("ehrpwm", "async3", psc1, DA8XX_LPSC1_PWM, 0);
        clk_register_clkdev(clk, "fck", "ehrpwm.0");
        clk_register_clkdev(clk, "fck", "ehrpwm.1");
-       clk = davinci_clk_init(&ehrpwm_tbclk);
+       clk = clk_register_gate(NULL, "ehrpwm_tbclk", "ehrpwm", 0,
+                               DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG),
+                               CFGCHIP1_TBCLKSYNC, 0, NULL);
        clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
        clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
-       clk = davinci_clk_init(&ecap_clk);
+       clk = PSC_CLK("ecap", "async3", psc1, DA8XX_LPSC1_ECAP, 0);
        clk_register_clkdev(clk, "fck", "ecap.0");
        clk_register_clkdev(clk, "fck", "ecap.1");
        clk_register_clkdev(clk, "fck", "ecap.2");
@@ -950,8 +562,6 @@ static struct map_desc da850_io_desc[] = {
        },
 };
 
-static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da850_ids[] = {
        {
@@ -1161,89 +771,11 @@ int da850_register_cpufreq(char *async_clk)
 
        return platform_device_register(&da850_cpufreq_device);
 }
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
-       int ret = 0, diff;
-       unsigned int best = (unsigned int) -1;
-       struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
-       struct cpufreq_frequency_table *pos;
-
-       rate /= 1000; /* convert to kHz */
-
-       cpufreq_for_each_entry(pos, table) {
-               diff = pos->frequency - rate;
-               if (diff < 0)
-                       diff = -diff;
-
-               if (diff < best) {
-                       best = diff;
-                       ret = pos->frequency;
-               }
-       }
-
-       return ret * 1000;
-}
-
-static int da850_set_armrate(struct clk *clk, unsigned long index)
-{
-       struct clk *pllclk = &pll0_clk;
-
-       return clk_set_rate(pllclk, index);
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
-{
-       struct pll_data *pll = clk->pll_data;
-       struct cpufreq_frequency_table *freq;
-       unsigned int prediv, mult, postdiv;
-       struct da850_opp *opp = NULL;
-       int ret;
-
-       rate /= 1000;
-
-       for (freq = da850_freq_table;
-            freq->frequency != CPUFREQ_TABLE_END; freq++) {
-               /* rate is in Hz, freq->frequency is in KHz */
-               if (freq->frequency == rate) {
-                       opp = (struct da850_opp *)freq->driver_data;
-                       break;
-               }
-       }
-
-       if (!opp)
-               return -EINVAL;
-
-       prediv = opp->prediv;
-       mult = opp->mult;
-       postdiv = opp->postdiv;
-
-       ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
-       if (WARN_ON(ret))
-               return ret;
-
-       return 0;
-}
 #else
 int __init da850_register_cpufreq(char *async_clk)
 {
        return 0;
 }
-
-static int da850_set_armrate(struct clk *clk, unsigned long rate)
-{
-       return -EINVAL;
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
-{
-       return -EINVAL;
-}
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
-       return clk->rate;
-}
 #endif
 
 /* VPIF resource, platform data */
@@ -1345,8 +877,6 @@ static const struct davinci_soc_info 
davinci_soc_info_da850 = {
        .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da850_ids,
        .ids_num                = ARRAY_SIZE(da850_ids),
-       .psc_bases              = da850_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(da850_psc_bases),
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da850_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da850_pins),
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index ab199f4..6bbdb769 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -11,6 +11,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/irqdomain.h>
+#include <linux/platform_data/davinci_clk.h>
 #include <linux/platform_data/ti-aemif.h>
 
 #include <asm/mach/arch.h>
@@ -52,6 +53,7 @@ static struct of_dev_auxdata da850_auxdata_lookup[] 
__initdata = {
        OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
        OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
        OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
+       OF_DEV_AUXDATA("ti,da830-cfgchip-clk", 0x01c1417c, "da8xx-cfgchip-clk", 
NULL),
        OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
        OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
        OF_DEV_AUXDATA("ti,da850-dsp", 0x11800000, "davinci-rproc.0", NULL),
@@ -60,6 +62,11 @@ static struct of_dev_auxdata da850_auxdata_lookup[] 
__initdata = {
 
 #ifdef CONFIG_ARCH_DAVINCI_DA850
 
+static struct da8xx_cfgchip_clk_data usb_phy_clk_data = {
+       .usb0_use_refclkin = false,
+       .usb1_use_refclkin = false,
+};
+
 static void __init da850_init_machine(void)
 {
        /* All existing boards use 100MHz SATA refclkpn */
@@ -67,13 +74,9 @@ static void __init da850_init_machine(void)
 
        int ret;
 
-       ret = da8xx_register_usb20_phy_clk(false);
-       if (ret)
-               pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
-                       __func__, ret);
-       ret = da8xx_register_usb11_phy_clk(false);
+       ret = da8xx_register_usb_phy_clocks(&usb_phy_clk_data);
        if (ret)
-               pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
+               pr_warn("%s: registering USB PHY clocks failed: %d",
                        __func__, ret);
 
        ret = da850_register_sata_refclk(sata_refclkpn);
diff --git a/arch/arm/mach-davinci/devices-da8xx.c 
b/arch/arm/mach-davinci/devices-da8xx.c
index c9a79b2..f80a28d 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -10,26 +10,28 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/ahci_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/dma-contiguous.h>
+#include <linux/dmaengine.h>
 #include <linux/init.h>
 #include <linux/platform_data/syscon.h>
 #include <linux/platform_device.h>
-#include <linux/dma-contiguous.h>
-#include <linux/serial_8250.h>
-#include <linux/ahci_platform.h>
-#include <linux/clk.h>
 #include <linux/reboot.h>
-#include <linux/dmaengine.h>
+#include <linux/serial_8250.h>
 
-#include <mach/cputype.h>
+#include <mach/clock.h>
 #include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
 #include <mach/da8xx.h>
-#include <mach/clock.h>
-#include "cpuidle.h"
-#include "sram.h"
+#include <mach/time.h>
 
-#include "clock.h"
 #include "asp.h"
+#include "clock.h"
+#include "cpuidle.h"
+#include "sram.h"
 
 #define DA8XX_TPCC_BASE                        0x01c00000
 #define DA8XX_TPTC0_BASE               0x01c08000
@@ -1041,23 +1043,16 @@ int __init da8xx_register_spi_bus(int instance, 
unsigned num_chipselect)
 }
 
 #ifdef CONFIG_ARCH_DAVINCI_DA850
-static struct clk sata_refclk = {
-       .name           = "sata_refclk",
-       .set_rate       = davinci_simple_set_rate,
-};
 
-int __init da850_register_sata_refclk(int rate)
+int __init da850_register_sata_refclk(unsigned long rate)
 {
-       int ret;
+       struct clk *clk;
 
-       sata_refclk.rate = rate;
-       ret = clk_register(&sata_refclk);
-       if (ret)
-               return ret;
-
-       clk_register_clkdev(&sata_refclk, "refclk", "ahci_da850");
+       clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
 
-       return 0;
+       return clk_register_clkdev(clk, "refclk", "ahci_da850");
 }
 
 static struct resource da850_sata_resources[] = {
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 9e5cfa9..17859b1 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -8,31 +8,33 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
 #include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
-#include "davinci.h"
+#include "asp.h"
 #include "clock.h"
+#include "davinci.h"
 #include "mux.h"
-#include "asp.h"
+#include "psc.h"
 
 #define DM355_UART2_BASE       (IO_PHYS + 0x206000)
 #define DM355_OSD_BASE         (IO_PHYS + 0x70200)
@@ -43,136 +45,6 @@
  */
 #define DM355_REF_FREQ         24000000        /* 24 or 36 MHz */
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-       .flags     = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-       .flags     = PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       /* FIXME -- crystal rate is board-specific */
-       .rate = DM355_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .flags = CLK_PLL,
-       .pll_data = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name = "pll1_sysclk4",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk vpss_dac_clk = {
-       .name = "vpss_dac",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM355_LPSC_VPSS_DAC,
-};
-
-static struct clk vpss_master_clk = {
-       .name = "vpss_master",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_VPSSMSTR,
-       .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name = "vpss_slave",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk clkout1_clk = {
-       .name = "clkout1",
-       .parent = &pll1_aux_clk,
-       /* NOTE:  clkout1 can be externally gated by muxing GPIO-18 */
-};
-
-static struct clk clkout2_clk = {
-       .name = "clkout2",
-       .parent = &pll1_sysclkbp,
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2",
-       .parent = &ref_clk,
-       .flags = CLK_PLL,
-       .pll_data = &pll2_data,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclkbp = {
-       .name = "pll2_sysclkbp",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk clkout3_clk = {
-       .name = "clkout3",
-       .parent = &pll2_sysclkbp,
-       /* NOTE:  clkout3 can be externally gated by muxing GPIO-16 */
-};
-
-static struct clk arm_clk = {
-       .name = "arm_clk",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
 /*
  * NOT LISTED below, and not touched by Linux
  *   - in SyncReset state by default
@@ -192,238 +64,102 @@ static struct clk arm_clk = {
  *     .lpsc = DAVINCI_LPSC_CFG5,      // "test"
  */
 
-static struct clk mjcp_clk = {
-       .name = "mjcp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_IMCOP,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
-       .name = "i2c",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk asp0_clk = {
-       .name = "asp0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk asp1_clk = {
-       .name = "asp1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_McBSP1,
-};
-
-static struct clk mmcsd0_clk = {
-       .name = "mmcsd0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name = "mmcsd1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
-       .name = "spi0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
-       .name = "spi1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
-       .name = "spi2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_SPI2,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name = "pwm2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
-       .name = "pwm3",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk timer3_clk = {
-       .name = "timer3",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_TIMER3,
-};
-
-static struct clk rto_clk = {
-       .name = "rto",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_RTO,
-};
-
-static struct clk usb_clk = {
-       .name = "usb",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_USB,
-};
-
 static __init void dm355_clk_init(void)
 {
+       void __iomem *pll1, *pll2, *psc;
        struct clk *clk;
 
-       clk = davinci_clk_init(&ref_clk);
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+       pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+       clk = EXT_CLK("ref_clk", DM355_REF_FREQ);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&pll1_clk);
+       clk = PLL_CLK("pll1", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk1);
+       clk = PLL_DIV_CLK("pll1_sysclk1", "pll1", pll1, 1);
        clk_register_clkdev(clk, "pll1_sysclk1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk2);
+       clk = PLL_DIV_CLK("pll1_sysclk2", "pll1", pll1, 2);
        clk_register_clkdev(clk, "pll1_sysclk2", NULL);
-       clk = davinci_clk_init(&pll1_sysclk3);
+       clk = PLL_DIV_CLK("pll1_sysclk3", "pll1", pll1, 3);
        clk_register_clkdev(clk, "pll1_sysclk3", NULL);
-       clk = davinci_clk_init(&pll1_sysclk4);
+       clk = PLL_DIV_CLK("pll1_sysclk4", "pll1", pll1, 4);
        clk_register_clkdev(clk, "pll1_sysclk4", NULL);
-       clk = davinci_clk_init(&pll1_aux_clk);
+       clk = PLL_AUX_CLK("pll1_aux_clk", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_aux", NULL);
-       clk = davinci_clk_init(&pll1_sysclkbp);
+       clk = PLL_BP_CLK("pll1_sysclkbp", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
-       clk = davinci_clk_init(&vpss_dac_clk);
+       clk = PSC_CLK("vpss_dac", "pll1_sysclk3", psc, DM355_LPSC_VPSS_DAC, 0);
        clk_register_clkdev(clk, "vpss_dac", NULL);
-       clk = davinci_clk_init(&vpss_master_clk);
+       clk = PSC_CLK("vpss_master", "pll1_sysclk4", psc, 
DAVINCI_LPSC_VPSSMSTR, 0);
        clk_register_clkdev(clk, "master", "vpss");
-       clk = davinci_clk_init(&vpss_slave_clk);
+       clk = PSC_CLK("vpss_slave", "pll1_sysclk4", psc, DAVINCI_LPSC_VPSSSLV, 
0);
        clk_register_clkdev(clk, "slave", "vpss");
-       clk = davinci_clk_init(&clkout1_clk);
+       clk = FIX_CLK("clkout1", "pll1_aux_clk");
+       /* NOTE:  clkout1 can be externally gated by muxing GPIO-18 */
        clk_register_clkdev(clk, "clkout1", NULL);
-       clk = davinci_clk_init(&clkout2_clk);
+       clk = FIX_CLK("clkout2", "pll1_sysclkbp");
        clk_register_clkdev(clk, "clkout2", NULL);
-       clk = davinci_clk_init(&pll2_clk);
+       clk = PLL_CLK("pll2", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2", NULL);
-       clk = davinci_clk_init(&pll2_sysclk1);
+       clk = PLL_DIV_CLK("pll2_sysclk1", "pll2", pll2, 1);
        clk_register_clkdev(clk, "pll2_sysclk1", NULL);
-       clk = davinci_clk_init(&pll2_sysclkbp);
+       clk = PLL_BP_CLK("pll2_sysclkbp", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
-       clk = davinci_clk_init(&clkout3_clk);
+       clk = FIX_CLK("clkout3", "pll2_sysclkbp");
+       /* NOTE:  clkout3 can be externally gated by muxing GPIO-16 */
        clk_register_clkdev(clk, "clkout3", NULL);
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm_clk", "pll1_sysclk1", psc, DAVINCI_LPSC_ARM, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&mjcp_clk);
+       clk = PSC_CLK("mjcp", "pll1_sysclk1", psc, DAVINCI_LPSC_IMCOP, 0);
        clk_register_clkdev(clk, "mjcp", NULL);
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "pll1_aux_clk", psc, DAVINCI_LPSC_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "pll1_aux_clk", psc, DAVINCI_LPSC_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&uart2_clk);
+       clk = PSC_CLK("uart2", "pll1_sysclk2", psc, DAVINCI_LPSC_UART2, 0);
        clk_register_clkdev(clk, NULL, "serial8250.2");
-       clk = davinci_clk_init(&i2c_clk);
+       clk = PSC_CLK("i2c", "pll1_aux_clk", psc, DAVINCI_LPSC_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&asp0_clk);
+       clk = PSC_CLK("asp0", "pll1_sysclk2", psc, DAVINCI_LPSC_McBSP, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
-       clk = davinci_clk_init(&asp1_clk);
+       clk = PSC_CLK("asp1", "pll1_sysclk2", psc, DM355_LPSC_McBSP1, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
-       clk = davinci_clk_init(&mmcsd0_clk);
+       clk = PSC_CLK("mmcsd0", "pll1_sysclk2", psc, DAVINCI_LPSC_MMC_SD, 0);
        clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
-       clk = davinci_clk_init(&mmcsd1_clk);
+       clk = PSC_CLK("mmcsd1", "pll1_sysclk2", psc, DM355_LPSC_MMC_SD1, 0);
        clk_register_clkdev(clk, NULL, "dm6441-mmc.1");
-       clk = davinci_clk_init(&spi0_clk);
+       clk = PSC_CLK("spi0", "pll1_sysclk2", psc, DAVINCI_LPSC_SPI, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.0");
-       clk = davinci_clk_init(&spi1_clk);
+       clk = PSC_CLK("spi1", "pll1_sysclk2", psc, DM355_LPSC_SPI1, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.1");
-       clk = davinci_clk_init(&spi2_clk);
+       clk = PSC_CLK("spi2", "pll1_sysclk2", psc, DM355_LPSC_SPI2, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.2");
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll1_sysclk2", psc, DAVINCI_LPSC_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll1_sysclk2", psc, DAVINCI_LPSC_AEMIF, 0);
        clk_register_clkdev(clk, "aemif", NULL);
-       clk = davinci_clk_init(&pwm0_clk);
+       clk = PSC_CLK("pwm0", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM0, 0);
        clk_register_clkdev(clk, "pwm0", NULL);
-       clk = davinci_clk_init(&pwm1_clk);
+       clk = PSC_CLK("pwm1", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM1, 0);
        clk_register_clkdev(clk, "pwm1", NULL);
-       clk = davinci_clk_init(&pwm2_clk);
+       clk = PSC_CLK("pwm2", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM2, 0);
        clk_register_clkdev(clk, "pwm2", NULL);
-       clk = davinci_clk_init(&pwm3_clk);
+       clk = PSC_CLK("pwm3", "pll1_aux_clk", psc, DM355_LPSC_PWM3, 0);
        clk_register_clkdev(clk, "pwm3", NULL);
-       clk = davinci_clk_init(&timer0_clk);
+       clk = PSC_CLK("timer0", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER0, 0);
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timer1_clk);
+       clk = PSC_CLK("timer1", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER1, 0);
        clk_register_clkdev(clk, "timer1", NULL);
-       clk = davinci_clk_init(&timer2_clk);
+       clk = PSC_CLK("timer2", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER2, 0);
+       clk_prepare_enable(clk); /* REVISIT: why can't this be disabled? */
        clk_register_clkdev(clk, NULL, "davinci-wdt");
-       clk = davinci_clk_init(&timer3_clk);
+       clk = PSC_CLK("timer3", "pll1_aux_clk", psc, DM355_LPSC_TIMER3, 0);
        clk_register_clkdev(clk, "timer3", NULL);
-       clk = davinci_clk_init(&rto_clk);
+       clk = PSC_CLK("rto", "pll1_aux_clk", psc, DM355_LPSC_RTO, 0);
        clk_register_clkdev(clk, "rto", NULL);
-       clk = davinci_clk_init(&usb_clk);
+       clk = PSC_CLK("usb", "pll1_sysclk2", psc, DAVINCI_LPSC_USB, 0);
        clk_register_clkdev(clk, "usb", NULL);
 }
 
@@ -970,8 +706,6 @@ static struct davinci_id dm355_ids[] = {
        },
 };
 
-static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -1056,8 +790,6 @@ static const struct davinci_soc_info 
davinci_soc_info_dm355 = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm355_ids,
        .ids_num                = ARRAY_SIZE(dm355_ids),
-       .psc_bases              = dm355_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm355_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm355_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm355_pins),
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 430fb1e..44b5599 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -12,32 +12,34 @@
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/keyscan-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
 #include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
-#include "davinci.h"
+#include "asp.h"
 #include "clock.h"
+#include "davinci.h"
 #include "mux.h"
-#include "asp.h"
+#include "psc.h"
 
 #define DM365_REF_FREQ         24000000        /* 24 MHz on the DM365 EVM */
 #define DM365_RTC_BASE                 0x01c69000
@@ -54,493 +56,141 @@
 #define DM365_EMAC_CNTRL_RAM_OFFSET    0x1000
 #define DM365_EMAC_CNTRL_RAM_SIZE      0x2000
 
-static struct pll_data pll1_data = {
-       .num            = 1,
-       .phys_base      = DAVINCI_PLL1_BASE,
-       .flags          = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct pll_data pll2_data = {
-       .num            = 2,
-       .phys_base      = DAVINCI_PLL2_BASE,
-       .flags          = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DM365_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name           = "pll1",
-       .parent         = &ref_clk,
-       .flags          = CLK_PLL,
-       .pll_data       = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
-       .name           = "pll1_aux_clk",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name           = "pll1_sysclkbp",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-       .div_reg        = BPDIV
-};
-
-static struct clk clkout0_clk = {
-       .name           = "clkout0",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name           = "pll1_sysclk1",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name           = "pll1_sysclk2",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name           = "pll1_sysclk3",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name           = "pll1_sysclk4",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name           = "pll1_sysclk5",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
-       .name           = "pll1_sysclk6",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
-       .name           = "pll1_sysclk7",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk pll1_sysclk8 = {
-       .name           = "pll1_sysclk8",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
-       .name           = "pll1_sysclk9",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV9,
-};
-
-static struct clk pll2_clk = {
-       .name           = "pll2",
-       .parent         = &ref_clk,
-       .flags          = CLK_PLL,
-       .pll_data       = &pll2_data,
-};
-
-static struct clk pll2_aux_clk = {
-       .name           = "pll2_aux_clk",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk clkout1_clk = {
-       .name           = "clkout1",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name           = "pll2_sysclk1",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
-       .name           = "pll2_sysclk2",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll2_sysclk3 = {
-       .name           = "pll2_sysclk3",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll2_sysclk4 = {
-       .name           = "pll2_sysclk4",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll2_sysclk5 = {
-       .name           = "pll2_sysclk5",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll2_sysclk6 = {
-       .name           = "pll2_sysclk6",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll2_sysclk7 = {
-       .name           = "pll2_sysclk7",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk pll2_sysclk8 = {
-       .name           = "pll2_sysclk8",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV8,
-};
-
-static struct clk pll2_sysclk9 = {
-       .name           = "pll2_sysclk9",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV9,
-};
-
-static struct clk vpss_dac_clk = {
-       .name           = "vpss_dac",
-       .parent         = &pll1_sysclk3,
-       .lpsc           = DM365_LPSC_DAC_CLK,
-};
-
-static struct clk vpss_master_clk = {
-       .name           = "vpss_master",
-       .parent         = &pll1_sysclk5,
-       .lpsc           = DM365_LPSC_VPSSMSTR,
-       .flags          = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name           = "vpss_slave",
-       .parent         = &pll1_sysclk5,
-       .lpsc           = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm_clk",
-       .parent         = &pll2_sysclk2,
-       .lpsc           = DAVINCI_LPSC_ARM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_UART0,
+static const char * const pll_obsclk_parent_names[] = {
+       "ref_clk",
 };
 
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_UART1,
-};
-
-static struct clk i2c_clk = {
-       .name           = "i2c",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_I2C,
-};
-
-static struct clk mmcsd0_clk = {
-       .name           = "mmcsd0",
-       .parent         = &pll1_sysclk8,
-       .lpsc           = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name           = "mmcsd1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
-       .name           = "spi2",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI2,
-};
-
-static struct clk spi3_clk = {
-       .name           = "spi3",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI3,
-};
-
-static struct clk spi4_clk = {
-       .name           = "spi4",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DM365_LPSC_SPI4,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name           = "pwm0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name           = "pwm1",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name           = "pwm2",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
-       .name           = "pwm3",
-       .parent         = &ref_clk,
-       .lpsc           = DM365_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
-       .name           = "timer0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name           = "timer1",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name           = "timer2",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER2,
-       .usecount       = 1,
-};
-
-static struct clk timer3_clk = {
-       .name           = "timer3",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DM365_LPSC_TIMER3,
-};
-
-static struct clk usb_clk = {
-       .name           = "usb",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_USB,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_EMAC,
-};
-
-static struct clk voicecodec_clk = {
-       .name           = "voice_codec",
-       .parent         = &pll2_sysclk4,
-       .lpsc           = DM365_LPSC_VOICE_CODEC,
-};
-
-static struct clk asp0_clk = {
-       .name           = "asp0",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_McBSP1,
-};
-
-static struct clk rto_clk = {
-       .name           = "rto",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_RTO,
-};
-
-static struct clk mjcp_clk = {
-       .name           = "mjcp",
-       .parent         = &pll1_sysclk3,
-       .lpsc           = DM365_LPSC_MJCP,
+static u32 pll_obsclk_table[] = {
+       0x10,
 };
 
 static __init void dm365_clk_init(void)
 {
+       void __iomem *pll1, *pll2, *psc;
        struct clk *clk;
 
-       clk = davinci_clk_init(&ref_clk);
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+       pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+       clk = EXT_CLK("ref_clk", DM365_REF_FREQ);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&pll1_clk);
+       clk = PLL_CLK("pll1", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1", NULL);
-       clk = davinci_clk_init(&pll1_aux_clk);
+       clk = PLL_AUX_CLK("pll1_aux_clk", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_aux", NULL);
-       clk = davinci_clk_init(&pll1_sysclkbp);
+       clk = PLL_BP_CLK("pll1_sysclkbp", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
-       clk = davinci_clk_init(&clkout0_clk);
+       clk = PLL_OBS_CLK("clkout0", pll_obsclk_parent_names,
+                         ARRAY_SIZE(pll_obsclk_parent_names), pll1,
+                         pll_obsclk_table);
        clk_register_clkdev(clk, "clkout0", NULL);
-       clk = davinci_clk_init(&pll1_sysclk1);
+       clk = PLL_DIV_CLK("pll1_sysclk1", "pll1", pll1, 1);
        clk_register_clkdev(clk, "pll1_sysclk1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk2);
+       clk = PLL_DIV_CLK("pll1_sysclk2", "pll1", pll1, 2);
        clk_register_clkdev(clk, "pll1_sysclk2", NULL);
-       clk = davinci_clk_init(&pll1_sysclk3);
+       clk = PLL_DIV_CLK("pll1_sysclk3", "pll1", pll1, 3);
        clk_register_clkdev(clk, "pll1_sysclk3", NULL);
-       clk = davinci_clk_init(&pll1_sysclk4);
+       clk = PLL_DIV_CLK("pll1_sysclk4", "pll1", pll1, 4);
        clk_register_clkdev(clk, "pll1_sysclk4", NULL);
-       clk = davinci_clk_init(&pll1_sysclk5);
+       clk = PLL_DIV_CLK("pll1_sysclk5", "pll1", pll1, 5);
        clk_register_clkdev(clk, "pll1_sysclk5", NULL);
-       clk = davinci_clk_init(&pll1_sysclk6);
+       clk = PLL_DIV_CLK("pll1_sysclk6", "pll1", pll1, 6);
        clk_register_clkdev(clk, "pll1_sysclk6", NULL);
-       clk = davinci_clk_init(&pll1_sysclk7);
+       clk = PLL_DIV_CLK("pll1_sysclk7", "pll1", pll1, 7);
        clk_register_clkdev(clk, "pll1_sysclk7", NULL);
-       clk = davinci_clk_init(&pll1_sysclk8);
+       clk = PLL_DIV_CLK("pll1_sysclk8", "pll1", pll1, 8);
        clk_register_clkdev(clk, "pll1_sysclk8", NULL);
-       clk = davinci_clk_init(&pll1_sysclk9);
+       clk = PLL_DIV_CLK("pll1_sysclk9", "pll1", pll1, 9);
        clk_register_clkdev(clk, "pll1_sysclk9", NULL);
-       clk = davinci_clk_init(&pll2_clk);
+       clk = PLL_CLK("pll2", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2", NULL);
-       clk = davinci_clk_init(&pll2_aux_clk);
+       clk = PLL_AUX_CLK("clkout1", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2_aux", NULL);
-       clk = davinci_clk_init(&clkout1_clk);
+       clk = PLL_OBS_CLK("clkout1", pll_obsclk_parent_names,
+                         ARRAY_SIZE(pll_obsclk_parent_names), pll2,
+                         pll_obsclk_table);
        clk_register_clkdev(clk, "clkout1", NULL);
-       clk = davinci_clk_init(&pll2_sysclk1);
+       clk = PLL_DIV_CLK("pll2_sysclk1", "pll2", pll2, 1);
        clk_register_clkdev(clk, "pll2_sysclk1", NULL);
-       clk = davinci_clk_init(&pll2_sysclk2);
+       clk = PLL_DIV_CLK("pll2_sysclk2", "pll2", pll2, 2);
        clk_register_clkdev(clk, "pll2_sysclk2", NULL);
-       clk = davinci_clk_init(&pll2_sysclk3);
+       clk = PLL_DIV_CLK("pll2_sysclk3", "pll2", pll2, 3);
        clk_register_clkdev(clk, "pll2_sysclk3", NULL);
-       clk = davinci_clk_init(&pll2_sysclk4);
+       clk = PLL_DIV_CLK("pll2_sysclk4", "pll2", pll2, 4);
        clk_register_clkdev(clk, "pll2_sysclk4", NULL);
-       clk = davinci_clk_init(&pll2_sysclk5);
+       clk = PLL_DIV_CLK("pll2_sysclk5", "pll2", pll2, 5);
        clk_register_clkdev(clk, "pll2_sysclk5", NULL);
-       clk = davinci_clk_init(&pll2_sysclk6);
+       clk = PLL_DIV_CLK("pll2_sysclk6", "pll2", pll2, 6);
        clk_register_clkdev(clk, "pll2_sysclk6", NULL);
-       clk = davinci_clk_init(&pll2_sysclk7);
+       clk = PLL_DIV_CLK("pll2_sysclk7", "pll2", pll2, 7);
        clk_register_clkdev(clk, "pll2_sysclk7", NULL);
-       clk = davinci_clk_init(&pll2_sysclk8);
+       clk = PLL_DIV_CLK("pll2_sysclk8", "pll2", pll2, 8);
        clk_register_clkdev(clk, "pll2_sysclk8", NULL);
-       clk = davinci_clk_init(&pll2_sysclk9);
+       clk = PLL_DIV_CLK("pll2_sysclk9", "pll2", pll2, 9);
        clk_register_clkdev(clk, "pll2_sysclk9", NULL);
-       clk = davinci_clk_init(&vpss_dac_clk);
+       clk = PSC_CLK("vpss_dac", "pll1_sysclk3", psc, DM365_LPSC_DAC_CLK, 0);
        clk_register_clkdev(clk, "vpss_dac", NULL);
-       clk = davinci_clk_init(&vpss_master_clk);
+       clk = PSC_CLK("vpss_master", "pll1_sysclk5", psc, DM365_LPSC_VPSSMSTR, 
0);
        clk_register_clkdev(clk, "master", "vpss");
-       clk = davinci_clk_init(&vpss_slave_clk);
+       clk = PSC_CLK("vpss_slave", "pll1_sysclk5", psc, DAVINCI_LPSC_VPSSSLV, 
0);
        clk_register_clkdev(clk, "slave", "vpss");
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm_clk", "pll2_sysclk2", psc, DAVINCI_LPSC_ARM, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "pll1_aux_clk", psc, DAVINCI_LPSC_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "pll1_sysclk4", psc, DAVINCI_LPSC_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&i2c_clk);
+       clk = PSC_CLK("i2c", "pll1_aux_clk", psc, DAVINCI_LPSC_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&mmcsd0_clk);
+       clk = PSC_CLK("mmcsd0", "pll1_sysclk8", psc, DAVINCI_LPSC_MMC_SD, 0);
        clk_register_clkdev(clk, NULL, "da830-mmc.0");
-       clk = davinci_clk_init(&mmcsd1_clk);
+       clk = PSC_CLK("mmcsd1", "pll1_sysclk4", psc, DM365_LPSC_MMC_SD1, 0);
        clk_register_clkdev(clk, NULL, "da830-mmc.1");
-       clk = davinci_clk_init(&spi0_clk);
+       clk = PSC_CLK("spi0", "pll1_sysclk4", psc, DAVINCI_LPSC_SPI, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.0");
-       clk = davinci_clk_init(&spi1_clk);
+       clk = PSC_CLK("spi1", "pll1_sysclk4", psc, DM365_LPSC_SPI1, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.1");
-       clk = davinci_clk_init(&spi2_clk);
+       clk = PSC_CLK("spi2", "pll1_sysclk4", psc, DM365_LPSC_SPI2, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.2");
-       clk = davinci_clk_init(&spi3_clk);
+       clk = PSC_CLK("spi3", "pll1_sysclk4", psc, DM365_LPSC_SPI3, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.3");
-       clk = davinci_clk_init(&spi4_clk);
+       clk = PSC_CLK("spi4", "pll1_aux_clk", psc, DM365_LPSC_SPI4, 0);
        clk_register_clkdev(clk, NULL, "spi_davinci.4");
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll1_sysclk4", psc, DAVINCI_LPSC_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll1_sysclk4", psc, DAVINCI_LPSC_AEMIF, 0);
        clk_register_clkdev(clk, "aemif", NULL);
-       clk = davinci_clk_init(&pwm0_clk);
+       clk = PSC_CLK("pwm0", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM0, 0);
        clk_register_clkdev(clk, "pwm0", NULL);
-       clk = davinci_clk_init(&pwm1_clk);
+       clk = PSC_CLK("pwm1", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM1, 0);
        clk_register_clkdev(clk, "pwm1", NULL);
-       clk = davinci_clk_init(&pwm2_clk);
+       clk = PSC_CLK("pwm2", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM2, 0);
        clk_register_clkdev(clk, "pwm2", NULL);
-       clk = davinci_clk_init(&pwm3_clk);
+       clk = PSC_CLK("pwm3", "ref_clk", psc, DM365_LPSC_PWM3, 0);
        clk_register_clkdev(clk, "pwm3", NULL);
-       clk = davinci_clk_init(&timer0_clk);
+       clk = PSC_CLK("timer0", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER0, 0);
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timer1_clk);
+       clk = PSC_CLK("timer1", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER1, 0);
        clk_register_clkdev(clk, "timer1", NULL);
-       clk = davinci_clk_init(&timer2_clk);
+       clk = PSC_CLK("timer2", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER2, 0);
+       clk_prepare_enable(clk);
        clk_register_clkdev(clk, NULL, "davinci-wdt");
-       clk = davinci_clk_init(&timer3_clk);
+       clk = PSC_CLK("timer3", "pll1_aux_clk", psc, DM365_LPSC_TIMER3, 0);
        clk_register_clkdev(clk, "timer3", NULL);
-       clk = davinci_clk_init(&usb_clk);
+       clk = PSC_CLK("usb", "pll1_aux_clk", psc, DAVINCI_LPSC_USB, 0);
        clk_register_clkdev(clk, "usb", NULL);
-       clk = davinci_clk_init(&emac_clk);
+       clk = PSC_CLK("emac", "pll1_sysclk4", psc, DM365_LPSC_EMAC, 0);
        clk_register_clkdev(clk, NULL, "davinci_emac.1");
        clk_register_clkdev(clk, "fck", "davinci_mdio.0");
-       clk = davinci_clk_init(&voicecodec_clk);
+       clk = PSC_CLK("voice_codec", "pll2_sysclk4", psc, 
DM365_LPSC_VOICE_CODEC, 0);
        clk_register_clkdev(clk, NULL, "davinci_voicecodec");
-       clk = davinci_clk_init(&asp0_clk);
+       clk = PSC_CLK("asp0", "pll1_sysclk4", psc, DM365_LPSC_McBSP1, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp");
-       clk = davinci_clk_init(&rto_clk);
+       clk = PSC_CLK("rto", "pll1_sysclk4", psc, DM365_LPSC_RTO, 0);
        clk_register_clkdev(clk, "rto", NULL);
-       clk = davinci_clk_init(&mjcp_clk);
+       clk = PSC_CLK("mjcp", "pll1_sysclk3", psc, DM365_LPSC_MJCP, 0);
        clk_register_clkdev(clk, "mjcp", NULL);
 }
 
@@ -1112,8 +762,6 @@ static struct davinci_id dm365_ids[] = {
        },
 };
 
-static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 static struct davinci_timer_info dm365_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
@@ -1174,8 +822,6 @@ static const struct davinci_soc_info 
davinci_soc_info_dm365 = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm365_ids,
        .ids_num                = ARRAY_SIZE(dm365_ids),
-       .psc_bases              = dm365_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm365_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm365_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm365_pins),
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 58120f4..b9235e0 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -8,28 +8,31 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/init.h>
+#include <linux/clk-provider.h>
 #include <linux/clk.h>
-#include <linux/serial_8250.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dmaengine.h>
-#include <linux/platform_device.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include "psc.h"
 #include <mach/mux.h>
-#include <mach/time.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
-#include "davinci.h"
+#include "asp.h"
 #include "clock.h"
+#include "davinci.h"
 #include "mux.h"
-#include "asp.h"
+#include "psc.h"
 
 /*
  * Device specific clocks
@@ -43,324 +46,91 @@
 #define DM644X_EMAC_CNTRL_RAM_OFFSET   0x2000
 #define DM644X_EMAC_CNTRL_RAM_SIZE     0x2000
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       .rate = DM644X_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .pll_data = &pll1_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name = "pll1_sysclk5",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2",
-       .parent = &ref_clk,
-       .pll_data = &pll2_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
-       .name = "pll2_sysclk2",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll2_sysclkbp = {
-       .name = "pll2_sysclkbp",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk dsp_clk = {
-       .name = "dsp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_GEM,
-       .domain = DAVINCI_GPSC_DSPDOMAIN,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
-       .name = "arm",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vicp_clk = {
-       .name = "vicp",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_IMCOP,
-       .domain = DAVINCI_GPSC_DSPDOMAIN,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk vpss_master_clk = {
-       .name = "vpss_master",
-       .parent = &pll1_sysclk3,
-       .lpsc = DAVINCI_LPSC_VPSSMSTR,
-       .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name = "vpss_slave",
-       .parent = &pll1_sysclk3,
-       .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk emac_clk = {
-       .name = "emac",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
-};
-
-static struct clk i2c_clk = {
-       .name = "i2c",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk ide_clk = {
-       .name = "ide",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk asp_clk = {
-       .name = "asp0",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk mmcsd_clk = {
-       .name = "mmcsd",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk spi_clk = {
-       .name = "spi",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk usb_clk = {
-       .name = "usb",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk vlynq_clk = {
-       .name = "vlynq",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_VLYNQ,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name = "pwm2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't this be disabled? */
-};
-
 static __init void dm644x_clk_init(void)
 {
+       void __iomem *pll1, *pll2, *psc;
        struct clk *clk;
 
-       clk = davinci_clk_init(&ref_clk);
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+       pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+       clk = EXT_CLK("ref_clk", DM644X_REF_FREQ);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&pll1_clk);
+       clk = PLL_CLK("pll1", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk1);
+       clk = PLL_DIV_CLK("pll1_sysclk1", "pll1", pll1, 1);
        clk_register_clkdev(clk, "pll1_sysclk1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk2);
+       clk = PLL_DIV_CLK("pll1_sysclk2", "pll1", pll1, 2);
        clk_register_clkdev(clk, "pll1_sysclk2", NULL);
-       clk = davinci_clk_init(&pll1_sysclk3);
+       clk = PLL_DIV_CLK("pll1_sysclk3", "pll1", pll1, 3);
        clk_register_clkdev(clk, "pll1_sysclk3", NULL);
-       clk = davinci_clk_init(&pll1_sysclk5);
+       clk = PLL_DIV_CLK("pll1_sysclk5", "pll1", pll1, 5);
        clk_register_clkdev(clk, "pll1_sysclk5", NULL);
-       clk = davinci_clk_init(&pll1_aux_clk);
+       clk = PLL_AUX_CLK("pll1_aux_clk", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_aux", NULL);
-       clk = davinci_clk_init(&pll1_sysclkbp);
+       clk = PLL_BP_CLK("pll1_sysclkbp", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
-       clk = davinci_clk_init(&pll2_clk);
+       clk = PLL_CLK("pll2", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2", NULL);
-       clk = davinci_clk_init(&pll2_sysclk1);
+       clk = PLL_DIV_CLK("pll2_sysclk1", "pll2", pll2, 1);
        clk_register_clkdev(clk, "pll2_sysclk1", NULL);
-       clk = davinci_clk_init(&pll2_sysclk2);
+       clk = PLL_DIV_CLK("pll2_sysclk2", "pll2", pll2, 2);
        clk_register_clkdev(clk, "pll2_sysclk2", NULL);
-       clk = davinci_clk_init(&pll2_sysclkbp);
+       clk = PLL_BP_CLK("pll2_sysclkbp", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
-       clk = davinci_clk_init(&dsp_clk);
+       clk = PSC_CLK("dsp", "pll1_sysclk1", psc, DAVINCI_LPSC_GEM, 1);
+       clk_prepare_enable(clk); /* REVISIT how to disable? */
        clk_register_clkdev(clk, "dsp", NULL);
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm", "pll1_sysclk2", psc, DAVINCI_LPSC_ARM, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&vicp_clk);
+       clk = PSC_CLK("vicp", "pll1_sysclk2", psc, DAVINCI_LPSC_IMCOP, 1);
+       clk_prepare_enable(clk); /* REVISIT how to disable? */
        clk_register_clkdev(clk, "vicp", NULL);
-       clk = davinci_clk_init(&vpss_master_clk);
+       clk = PSC_CLK("vpss_master", "pll1_sysclk3", psc, 
DAVINCI_LPSC_VPSSMSTR, 0);
        clk_register_clkdev(clk, "master", "vpss");
-       clk = davinci_clk_init(&vpss_slave_clk);
+       clk = PSC_CLK("vpss_slave", "pll1_sysclk3", psc, DAVINCI_LPSC_VPSSSLV, 
0);
        clk_register_clkdev(clk, "slave", "vpss");
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "pll1_aux_clk", psc, DAVINCI_LPSC_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "pll1_aux_clk", psc, DAVINCI_LPSC_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&uart2_clk);
+       clk = PSC_CLK("uart2", "pll1_aux_clk", psc, DAVINCI_LPSC_UART2, 0);
        clk_register_clkdev(clk, NULL, "serial8250.2");
-       clk = davinci_clk_init(&emac_clk);
+       clk = PSC_CLK("emac", "pll1_sysclk5", psc, DAVINCI_LPSC_EMAC_WRAPPER, 
0);
        clk_register_clkdev(clk, NULL, "davinci_emac.1");
        clk_register_clkdev(clk, "fck", "davinci_mdio.0");
-       clk = davinci_clk_init(&i2c_clk);
+       clk = PSC_CLK("i2c", "pll1_aux_clk", psc, DAVINCI_LPSC_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&ide_clk);
+       clk = PSC_CLK("ide", "pll1_sysclk5", psc, DAVINCI_LPSC_ATA, 0);
        clk_register_clkdev(clk, NULL, "palm_bk3710");
-       clk = davinci_clk_init(&asp_clk);
+       clk = PSC_CLK("asp0", "pll1_sysclk5", psc, DAVINCI_LPSC_McBSP, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcbsp");
-       clk = davinci_clk_init(&mmcsd_clk);
+       clk = PSC_CLK("mmcsd", "pll1_sysclk5", psc, DAVINCI_LPSC_MMC_SD, 0);
        clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
-       clk = davinci_clk_init(&spi_clk);
+       clk = PSC_CLK("spi", "pll1_sysclk5", psc, DAVINCI_LPSC_SPI, 0);
        clk_register_clkdev(clk, "spi", NULL);
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll1_sysclk5", psc, DAVINCI_LPSC_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&usb_clk);
+       clk = PSC_CLK("usb", "pll1_sysclk5", psc, DAVINCI_LPSC_USB, 0);
        clk_register_clkdev(clk, "usb", NULL);
-       clk = davinci_clk_init(&vlynq_clk);
+       clk = PSC_CLK("vlynq", "pll1_sysclk5", psc, DAVINCI_LPSC_VLYNQ, 0);
        clk_register_clkdev(clk, "vlynq", NULL);
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll1_sysclk5", psc, DAVINCI_LPSC_AEMIF, 0);
        clk_register_clkdev(clk, "aemif", NULL);
-       clk = davinci_clk_init(&pwm0_clk);
+       clk = PSC_CLK("pwm0", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM0, 0);
        clk_register_clkdev(clk, "pwm0", NULL);
-       clk = davinci_clk_init(&pwm1_clk);
+       clk = PSC_CLK("pwm1", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM1, 0);
        clk_register_clkdev(clk, "pwm1", NULL);
-       clk = davinci_clk_init(&pwm2_clk);
+       clk = PSC_CLK("pwm2", "pll1_aux_clk", psc, DAVINCI_LPSC_PWM2, 0);
        clk_register_clkdev(clk, "pwm2", NULL);
-       clk = davinci_clk_init(&timer0_clk);
+       clk = PSC_CLK("timer0", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER0, 0);
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timer1_clk);
+       clk = PSC_CLK("timer1", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER1, 0);
        clk_register_clkdev(clk, "timer1", NULL);
-       clk = davinci_clk_init(&timer2_clk);
+       clk = PSC_CLK("timer2", "pll1_aux_clk", psc, DAVINCI_LPSC_TIMER2, 0);
+       clk_prepare_enable(clk); /* REVISIT: why can't this be disabled? */
        clk_register_clkdev(clk, NULL, "davinci-wdt");
 }
 
@@ -856,8 +626,6 @@ static struct davinci_id dm644x_ids[] = {
        },
 };
 
-static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -942,8 +710,6 @@ static const struct davinci_soc_info 
davinci_soc_info_dm644x = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm644x_ids,
        .ids_num                = ARRAY_SIZE(dm644x_ids),
-       .psc_bases              = dm644x_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm644x_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm644x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm644x_pins),
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 31dbe93..4b15933 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -8,29 +8,31 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include "psc.h"
 #include <mach/mux.h>
-#include <mach/time.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
-#include "davinci.h"
+#include "asp.h"
 #include "clock.h"
+#include "davinci.h"
 #include "mux.h"
-#include "asp.h"
+#include "psc.h"
 
 #define DAVINCI_VPIF_BASE       (0x01C12000)
 
@@ -46,357 +48,107 @@
 #define DM646X_EMAC_CNTRL_RAM_OFFSET   0x2000
 #define DM646X_EMAC_CNTRL_RAM_SIZE     0x2000
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk aux_clkin = {
-       .name = "aux_clkin",
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .pll_data = &pll1_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name = "pll1_sysclk4",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name = "pll1_sysclk5",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
-       .name = "pll1_sysclk6",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk8 = {
-       .name = "pll1_sysclk8",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
-       .name = "pll1_sysclk9",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV9,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2_clk",
-       .parent = &ref_clk,
-       .pll_data = &pll2_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk dsp_clk = {
-       .name = "dsp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DM646X_LPSC_C64X_CPU,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
-       .name = "arm",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_cc_clk = {
-       .name = "edma_cc",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPCC,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc0_clk = {
-       .name = "edma_tc0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC0,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc1_clk = {
-       .name = "edma_tc1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC1,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc2_clk = {
-       .name = "edma_tc2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC2,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc3_clk = {
-       .name = "edma_tc3",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC3,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
-       .name = "I2CCLK",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_I2C,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_GPIO,
-};
-
-static struct clk mcasp0_clk = {
-       .name = "mcasp0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_McASP0,
-};
-
-static struct clk mcasp1_clk = {
-       .name = "mcasp1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_McASP1,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_AEMIF,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
-       .name = "emac",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_EMAC,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_PWM0,
-       .usecount = 1,            /* REVIST: disabling hangs system */
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_PWM1,
-       .usecount = 1,            /* REVIST: disabling hangs system */
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_sysclk3,
-       .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
-};
-
-
-static struct clk ide_clk = {
-       .name = "ide",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk vpif0_clk = {
-       .name = "vpif0",
-       .parent = &ref_clk,
-       .lpsc = DM646X_LPSC_VPSSMSTR,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vpif1_clk = {
-       .name = "vpif1",
-       .parent = &ref_clk,
-       .lpsc = DM646X_LPSC_VPSSSLV,
-       .flags = ALWAYS_ENABLED,
-};
-
 static __init void dm646x_clk_init(unsigned long ref_clk_rate,
                                   unsigned long aux_clkin_rate)
 {
+       void __iomem *pll1, *pll2, *psc;
        struct clk *clk;
 
-       ref_clk.rate = ref_clk_rate;
-       aux_clkin.rate = aux_clkin_rate;
-       clk = davinci_clk_init(&ref_clk);
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+       pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+       clk = EXT_CLK("ref_clk", ref_clk_rate);
        clk_register_clkdev(clk, "ref", NULL);
-       clk = davinci_clk_init(&aux_clkin);
+       clk = EXT_CLK("aux_clkin", aux_clkin_rate);
        clk_register_clkdev(clk, "aux", NULL);
-       clk = davinci_clk_init(&pll1_clk);
+       clk = PLL_CLK("pll1", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1", NULL);
-       clk = davinci_clk_init(&pll1_sysclk1);
+       clk = PLL_DIV_CLK("pll1_sysclk1", "pll1", pll1, 1);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk2);
+       clk = PLL_DIV_CLK("pll1_sysclk2", "pll1", pll1, 2);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk3);
+       clk = PLL_DIV_CLK("pll1_sysclk3", "pll1", pll1, 3);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk4);
+       clk = PLL_DIV_CLK("pll1_sysclk4", "pll1", pll1, 4);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk5);
+       clk = PLL_DIV_CLK("pll1_sysclk5", "pll1", pll1, 5);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk6);
+       clk = PLL_DIV_CLK("pll1_sysclk6", "pll1", pll1, 6);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk8);
+       clk = PLL_DIV_CLK("pll1_sysclk8", "pll1", pll1, 8);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclk9);
+       clk = PLL_DIV_CLK("pll1_sysclk9", "pll1", pll1, 9);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_sysclkbp);
+       clk = PLL_BP_CLK("pll1_sysclkbp", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_sysclk", NULL);
-       clk = davinci_clk_init(&pll1_aux_clk);
+       clk = PLL_AUX_CLK("pll1_aux_clk", "ref_clk", pll1);
        clk_register_clkdev(clk, "pll1_aux", NULL);
-       clk = davinci_clk_init(&pll2_clk);
+       clk = PLL_CLK("pll2_clk", "ref_clk", pll2);
        clk_register_clkdev(clk, "pll2", NULL);
-       clk = davinci_clk_init(&pll2_sysclk1);
+       clk = PLL_DIV_CLK("pll2_sysclk1", "pll2", pll2, 2);
        clk_register_clkdev(clk, "pll2_sysclk1", NULL);
-       clk = davinci_clk_init(&dsp_clk);
+       clk = PSC_CLK("dsp", "pll1_sysclk1", psc, DM646X_LPSC_C64X_CPU, 0);
+       clk_prepare_enable(clk); /* REVISIT how to disable? */
        clk_register_clkdev(clk, "dsp", NULL);
-       clk = davinci_clk_init(&arm_clk);
+       clk = PSC_CLK("arm", "pll1_sysclk2", psc, DM646X_LPSC_ARM, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "arm", NULL);
-       clk = davinci_clk_init(&edma_cc_clk);
+       clk = PSC_CLK("edma_cc", "pll1_sysclk2", psc, DM646X_LPSC_TPCC, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "edma_cc", NULL);
-       clk = davinci_clk_init(&edma_tc0_clk);
+       clk = PSC_CLK("edma_tc0", "pll1_sysclk2", psc, DM646X_LPSC_TPTC0, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "edma_tc0", NULL);
-       clk = davinci_clk_init(&edma_tc1_clk);
+       clk = PSC_CLK("edma_tc1", "pll1_sysclk2", psc, DM646X_LPSC_TPTC1, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "edma_tc1", NULL);
-       clk = davinci_clk_init(&edma_tc2_clk);
+       clk = PSC_CLK("edma_tc2", "pll1_sysclk2", psc, DM646X_LPSC_TPTC2, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "edma_tc2", NULL);
-       clk = davinci_clk_init(&edma_tc3_clk);
+       clk = PSC_CLK("edma_tc3", "pll1_sysclk2", psc, DM646X_LPSC_TPTC3, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "edma_tc3", NULL);
-       clk = davinci_clk_init(&uart0_clk);
+       clk = PSC_CLK("uart0", "aux_clkin", psc, DM646X_LPSC_UART0, 0);
        clk_register_clkdev(clk, NULL, "serial8250.0");
-       clk = davinci_clk_init(&uart1_clk);
+       clk = PSC_CLK("uart1", "aux_clkin", psc, DM646X_LPSC_UART1, 0);
        clk_register_clkdev(clk, NULL, "serial8250.1");
-       clk = davinci_clk_init(&uart2_clk);
+       clk = PSC_CLK("uart2", "aux_clkin", psc, DM646X_LPSC_UART2, 0);
        clk_register_clkdev(clk, NULL, "serial8250.2");
-       clk = davinci_clk_init(&i2c_clk);
+       clk = PSC_CLK("I2CCLK", "pll1_sysclk3", psc, DM646X_LPSC_I2C, 0);
        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
-       clk = davinci_clk_init(&gpio_clk);
+       clk = PSC_CLK("gpio", "pll1_sysclk3", psc, DM646X_LPSC_GPIO, 0);
        clk_register_clkdev(clk, "gpio", NULL);
-       clk = davinci_clk_init(&mcasp0_clk);
+       clk = PSC_CLK("mcasp0", "pll1_sysclk3", psc, DM646X_LPSC_McASP0, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
-       clk = davinci_clk_init(&mcasp1_clk);
+       clk = PSC_CLK("mcasp1", "pll1_sysclk3", psc, DM646X_LPSC_McASP1, 0);
        clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
-       clk = davinci_clk_init(&aemif_clk);
+       clk = PSC_CLK("aemif", "pll1_sysclk3", psc, DM646X_LPSC_AEMIF, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "aemif", NULL);
-       clk = davinci_clk_init(&emac_clk);
+       clk = PSC_CLK("emac", "pll1_sysclk3", psc, DM646X_LPSC_EMAC, 0);
        clk_register_clkdev(clk, NULL, "davinci_emac.1");
        clk_register_clkdev(clk, "fck", "davinci_mdio.0");
-       clk = davinci_clk_init(&pwm0_clk);
+       clk = PSC_CLK("pwm0", "pll1_sysclk3", psc, DM646X_LPSC_PWM0, 0);
+       clk_prepare_enable(clk); /* REVIST: disabling hangs system */
        clk_register_clkdev(clk, "pwm0", NULL);
-       clk = davinci_clk_init(&pwm1_clk);
+       clk = PSC_CLK("pwm1", "pll1_sysclk3", psc, DM646X_LPSC_PWM1, 0);
+       clk_prepare_enable(clk); /* REVIST: disabling hangs system */
        clk_register_clkdev(clk, "pwm1", NULL);
-       clk = davinci_clk_init(&timer0_clk);
+       clk = PSC_CLK("timer0", "pll1_sysclk3", psc, DM646X_LPSC_TIMER0, 0);
        clk_register_clkdev(clk, "timer0", NULL);
-       clk = davinci_clk_init(&timer1_clk);
+       clk = PSC_CLK("timer1", "pll1_sysclk3", psc, DM646X_LPSC_TIMER1, 0);
        clk_register_clkdev(clk, "timer1", NULL);
-       clk = davinci_clk_init(&timer2_clk);
+       clk = FIX_CLK("timer2", "pll1_sysclk3");
+       clk_prepare_enable(clk); /* no LPSC, always enabled; c.f. spruep9a */
        clk_register_clkdev(clk, NULL, "davinci-wdt");
-       clk = davinci_clk_init(&ide_clk);
+       clk = PSC_CLK("ide", "pll1_sysclk4", psc, DAVINCI_LPSC_ATA, 0);
        clk_register_clkdev(clk, NULL, "palm_bk3710");
-       clk = davinci_clk_init(&vpif0_clk);
+       clk = PSC_CLK("vpif0", "ref_clk", psc, DM646X_LPSC_VPSSMSTR, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "vpif0", NULL);
-       clk = davinci_clk_init(&vpif1_clk);
+       clk = PSC_CLK("vpif1", "ref_clk", psc, DM646X_LPSC_VPSSSLV, 0);
+       clk_prepare_enable(clk); /* always enabled */
        clk_register_clkdev(clk, "vpif1", NULL);
 }
 
@@ -838,8 +590,6 @@ static struct davinci_id dm646x_ids[] = {
        },
 };
 
-static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -924,8 +674,6 @@ static const struct davinci_soc_info 
davinci_soc_info_dm646x = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm646x_ids,
        .ids_num                = ARRAY_SIZE(dm646x_ids),
-       .psc_bases              = dm646x_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm646x_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm646x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm646x_pins),
diff --git a/arch/arm/mach-davinci/include/mach/clock.h 
b/arch/arm/mach-davinci/include/mach/clock.h
index 3e8af6a..42ed4f2 100644
--- a/arch/arm/mach-davinci/include/mach/clock.h
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -15,9 +15,6 @@
 
 struct clk;
 
-extern int clk_register(struct clk *clk);
-extern void clk_unregister(struct clk *clk);
-
 int davinci_clk_reset_assert(struct clk *c);
 int davinci_clk_reset_deassert(struct clk *c);
 
diff --git a/arch/arm/mach-davinci/include/mach/common.h 
b/arch/arm/mach-davinci/include/mach/common.h
index f0d5e858..fb1e88f 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,8 +53,6 @@ struct davinci_soc_info {
        u32                             jtag_id_reg;
        struct davinci_id               *ids;
        unsigned long                   ids_num;
-       u32                             *psc_bases;
-       unsigned long                   psc_bases_num;
        u32                             pinmux_base;
        const struct mux_config         *pinmux_pins;
        unsigned long                   pinmux_pins_num;
@@ -82,12 +80,6 @@ extern void davinci_common_init(const struct 
davinci_soc_info *soc_info);
 extern void davinci_init_ide(void);
 void davinci_init_late(void);
 
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-int davinci_clk_disable_unused(void);
-#else
-static inline int davinci_clk_disable_unused(void) { return 0; }
-#endif
-
 #ifdef CONFIG_CPU_FREQ
 int davinci_cpufreq_init(void);
 #else
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h 
b/arch/arm/mach-davinci/include/mach/da8xx.h
index 3481a0d..672d842 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -23,6 +23,7 @@
 #include <mach/serial.h>
 #include <mach/pm.h>
 #include <linux/platform_data/edma.h>
+#include <linux/platform_data/davinci_clk.h>
 #include <linux/platform_data/i2c-davinci.h>
 #include <linux/platform_data/mmc-davinci.h>
 #include <linux/platform_data/usb-davinci.h>
@@ -100,10 +101,9 @@ int da8xx_register_watchdog(void);
 int da8xx_register_usb_phy(void);
 int da8xx_register_usb20(unsigned mA, unsigned potpgt);
 int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
-int da8xx_register_usb_refclkin(int rate);
-int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
-int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
-int da850_register_sata_refclk(int rate);
+int da8xx_register_usb_refclkin(unsigned long rate);
+int da8xx_register_usb_phy_clocks(struct da8xx_cfgchip_clk_data *pdata);
+int da850_register_sata_refclk(unsigned long rate);
 int da8xx_register_emac(void);
 int da8xx_register_uio_pruss(void);
 int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
deleted file mode 100644
index e5dc6bf..0000000
--- a/arch/arm/mach-davinci/psc.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * TI DaVinci Power and Sleep Controller (PSC)
- *
- * Copyright (C) 2006 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/cputype.h>
-#include "psc.h"
-
-#include "clock.h"
-
-/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
-{
-       void __iomem *psc_base;
-       u32 mdstat;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return 0;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-       mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
-       iounmap(psc_base);
-
-       /* if clocked, state can be "Enable" or "SyncReset" */
-       return mdstat & BIT(12);
-}
-
-/* Control "reset" line associated with PSC domain */
-void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
-{
-       u32 mdctl;
-       void __iomem *psc_base;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
-       mdctl = readl(psc_base + MDCTL + 4 * id);
-       if (reset)
-               mdctl &= ~MDCTL_LRST;
-       else
-               mdctl |= MDCTL_LRST;
-       writel(mdctl, psc_base + MDCTL + 4 * id);
-
-       iounmap(psc_base);
-}
-
-/* Enable or disable a PSC domain */
-void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, bool enable, u32 flags)
-{
-       u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
-       void __iomem *psc_base;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       u32 next_state = PSC_STATE_ENABLE;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
-       if (!enable) {
-               if (flags & PSC_SWRSTDISABLE)
-                       next_state = PSC_STATE_SWRSTDISABLE;
-               else
-                       next_state = PSC_STATE_DISABLE;
-       }
-
-       mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
-       mdctl &= ~MDSTAT_STATE_MASK;
-       mdctl |= next_state;
-       if (flags & PSC_FORCE)
-               mdctl |= MDCTL_FORCE;
-       __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
-
-       pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
-       if ((pdstat & PDSTAT_STATE_MASK) == 0) {
-               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
-               pdctl |= PDCTL_NEXT;
-               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-
-               ptcmd = 1 << domain;
-               __raw_writel(ptcmd, psc_base + PTCMD);
-
-               do {
-                       epcpr = __raw_readl(psc_base + EPCPR);
-               } while ((((epcpr >> domain) & 1) == 0));
-
-               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
-               pdctl |= PDCTL_EPCGOOD;
-               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-       } else {
-               ptcmd = 1 << domain;
-               __raw_writel(ptcmd, psc_base + PTCMD);
-       }
-
-       do {
-               ptstat = __raw_readl(psc_base + PTSTAT);
-       } while (!(((ptstat >> domain) & 1) == 0));
-
-       do {
-               mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
-       } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
-
-       iounmap(psc_base);
-}
diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h
index 8af9f09..aad4565 100644
--- a/arch/arm/mach-davinci/psc.h
+++ b/arch/arm/mach-davinci/psc.h
@@ -29,10 +29,6 @@
 
 #define        DAVINCI_PWR_SLEEP_CNTRL_BASE    0x01C41000
 
-/* Power and Sleep Controller (PSC) Domains */
-#define DAVINCI_GPSC_ARMDOMAIN         0
-#define DAVINCI_GPSC_DSPDOMAIN         1
-
 #define DAVINCI_LPSC_VPSSMSTR          0
 #define DAVINCI_LPSC_VPSSSLV           1
 #define DAVINCI_LPSC_TPCC              2
@@ -206,14 +202,4 @@
 #define PDCTL_NEXT             BIT(0)
 #define PDCTL_EPCGOOD          BIT(8)
 
-#ifndef __ASSEMBLER__
-
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
-               bool reset);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, bool enable, u32 flags);
-
-#endif
-
 #endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/usb-da8xx.c 
b/arch/arm/mach-davinci/usb-da8xx.c
index a2e575e..fda6bf0 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -2,12 +2,15 @@
 /*
  * DA8xx USB
  */
+#include <linux/clk-provider.h>
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/mfd/da8xx-cfgchip.h>
 #include <linux/phy/phy.h>
+#include <linux/platform_data/davinci_clk.h>
 #include <linux/platform_data/usb-davinci.h>
 #include <linux/platform_device.h>
 #include <linux/usb/musb.h>
@@ -23,8 +26,6 @@
 #define DA8XX_USB0_BASE                0x01e00000
 #define DA8XX_USB1_BASE                0x01e25000
 
-static struct clk *usb20_clk;
-
 static struct platform_device da8xx_usb_phy = {
        .name           = "da8xx-usb-phy",
        .id             = -1,
@@ -128,11 +129,6 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub 
*pdata)
        return platform_device_register(&da8xx_usb11_device);
 }
 
-static struct clk usb_refclkin = {
-       .name           = "usb_refclkin",
-       .set_rate       = davinci_simple_set_rate,
-};
-
 /**
  * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
  *
@@ -142,206 +138,24 @@ static struct clk usb_refclkin = {
  * signal, in which case it will be used as the parent of usb20_phy_clk and/or
  * usb11_phy_clk.
  */
-int __init da8xx_register_usb_refclkin(int rate)
-{
-       int ret;
-
-       usb_refclkin.rate = rate;
-       ret = clk_register(&usb_refclkin);
-       if (ret)
-               return ret;
-
-       clk_register_clkdev(&usb_refclkin, "usb_refclkin", NULL);
-
-       return 0;
-}
-
-static void usb20_phy_clk_enable(struct clk *clk)
+int __init da8xx_register_usb_refclkin(unsigned long rate)
 {
-       u32 val;
-       u32 timeout = 500000; /* 500 msec */
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
-       davinci_clk_enable(usb20_clk);
+       struct clk *clk;
 
-       /*
-        * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
-        * host may use the PLL clock without USB 2.0 OTG being used.
-        */
-       val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
-       val |= CFGCHIP2_PHY_PLLON;
+       clk = clk_register_fixed_rate(NULL, "usb_refclkin", NULL, 0, rate);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
 
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       while (--timeout) {
-               val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-               if (val & CFGCHIP2_PHYCLKGD)
-                       goto done;
-               udelay(1);
-       }
-
-       pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
-done:
-       davinci_clk_disable(usb20_clk);
+       return clk_register_clkdev(clk, "usb_refclkin", NULL);
 }
 
-static void usb20_phy_clk_disable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-       val |= CFGCHIP2_PHYPWRDN;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-}
-
-static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* Set the mux depending on the parent clock. */
-       if (parent == &usb_refclkin) {
-               val &= ~CFGCHIP2_USB2PHYCLKMUX;
-       } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
-               val |= CFGCHIP2_USB2PHYCLKMUX;
-       } else {
-               pr_err("Bad parent on USB 2.0 PHY clock\n");
-               return -EINVAL;
-       }
-
-       /* reference frequency also comes from parent clock */
-       val &= ~CFGCHIP2_REFFREQ_MASK;
-       switch (clk_get_rate(parent)) {
-       case 12000000:
-               val |= CFGCHIP2_REFFREQ_12MHZ;
-               break;
-       case 13000000:
-               val |= CFGCHIP2_REFFREQ_13MHZ;
-               break;
-       case 19200000:
-               val |= CFGCHIP2_REFFREQ_19_2MHZ;
-               break;
-       case 20000000:
-               val |= CFGCHIP2_REFFREQ_20MHZ;
-               break;
-       case 24000000:
-               val |= CFGCHIP2_REFFREQ_24MHZ;
-               break;
-       case 26000000:
-               val |= CFGCHIP2_REFFREQ_26MHZ;
-               break;
-       case 38400000:
-               val |= CFGCHIP2_REFFREQ_38_4MHZ;
-               break;
-       case 40000000:
-               val |= CFGCHIP2_REFFREQ_40MHZ;
-               break;
-       case 48000000:
-               val |= CFGCHIP2_REFFREQ_48MHZ;
-               break;
-       default:
-               pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       return 0;
-}
-
-static struct clk usb20_phy_clk = {
-       .name           = "usb20_phy",
-       .clk_enable     = usb20_phy_clk_enable,
-       .clk_disable    = usb20_phy_clk_disable,
-       .set_parent     = usb20_phy_clk_set_parent,
-};
-
-/**
- * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- *     or "pll0_aux" if false.
- */
-int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
-{
-       struct clk *parent;
-       int ret;
-
-       usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
-       ret = PTR_ERR_OR_ZERO(usb20_clk);
-       if (ret)
-               return ret;
-
-       parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
-       ret = PTR_ERR_OR_ZERO(parent);
-       if (ret) {
-               clk_put(usb20_clk);
-               return ret;
-       }
-
-       usb20_phy_clk.parent = parent;
-       ret = clk_register(&usb20_phy_clk);
-       if (!ret)
-               clk_register_clkdev(&usb20_phy_clk, "usb20_phy", 
"da8xx-usb-phy");
-
-       clk_put(parent);
-
-       return ret;
-}
-
-static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* Set the USB 1.1 PHY clock mux based on the parent clock. */
-       if (parent == &usb20_phy_clk) {
-               val &= ~CFGCHIP2_USB1PHYCLKMUX;
-       } else if (parent == &usb_refclkin) {
-               val |= CFGCHIP2_USB1PHYCLKMUX;
-       } else {
-               pr_err("Bad parent on USB 1.1 PHY clock\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       return 0;
-}
-
-static struct clk usb11_phy_clk = {
-       .name           = "usb11_phy",
-       .set_parent     = usb11_phy_clk_set_parent,
+static struct platform_device da8xx_phy_clocks_device = {
+       .name           = "da8xx-cfgchip-clk",
+       .id             = -1,
 };
 
-/**
- * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- *     or "usb20_phy" if false.
- */
-int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
+int __init da8xx_register_usb_phy_clocks(struct da8xx_cfgchip_clk_data *pdata)
 {
-       struct clk *parent;
-       int ret = 0;
-
-       if (use_usb_refclkin)
-               parent = clk_get(NULL, "usb_refclkin");
-       else
-               parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
-       if (IS_ERR(parent))
-               return PTR_ERR(parent);
-
-       usb11_phy_clk.parent = parent;
-       ret = clk_register(&usb11_phy_clk);
-       if (!ret)
-               clk_register_clkdev(&usb11_phy_clk, "usb11_phy", 
"da8xx-usb-phy");
-
-       clk_put(parent);
-
-       return ret;
+       da8xx_phy_clocks_device.dev.platform_data = pdata;
+       return platform_device_register(&da8xx_phy_clocks_device);
 }
-- 
2.7.4

Reply via email to