All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2017-12-31 23:39 ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

This series converts mach-davinci to use the common clock framework.

Basically, this series does some cleanup and rearranging to get things
ready for the conversion. Then there is a patch to add new driver in
drivers/clk and finally a patch to make the conversion from the mach
clock drivers to the new drivers.

I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
that I haven't broken anything (too badly) in da850. But, I don't have
other hardware to test.

The one thing that I know I have broken is CPU frequency scaling on da850.
I don't think it was working with device tree anyway, so I can't really test
it with the hardware I have. I'm hoping that it will be OK to defer fixing
it and add device tree support at the same time.

Dependencies:
* This series applies on top of "ARM: davinici: move watchdog restart from
  mach to drivers​" [1][2]
* On da850, you will also need a patch to prevent problems with the USB PHY
  clocks [3]
* Or get it all at once:
    git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4

[1]: https://patchwork.kernel.org/patch/10105623/
[2]: https://patchwork.kernel.org/patch/10105613/
[3]: https://patchwork.kernel.org/patch/10133193/


v4 changes:
* Basically, the whole series is new/reworked except for the first patch.
* Instead of having an intermediate conversion of the clocks in mach-davinci,
  new clock drivers are introduced in drivers/clk.
* There are a few more cleanup patches added before making the conversion.

v3 changes:
* Remove leftovers from rebasing in "ARM: davinci: don't use static clk_lookup"
  (fixes compile error)

v2 changes:
* Dropped "ARM: davinci: clean up map_io functions" - will resend as separate
  patch series
* Reworked remaining patches so that there is less shuffling around



David Lechner (7):
  ARM: davinci: move davinci_clk_init() to init_time
  ARM: davinci: don't use static clk_lookup
  ARM: davinci: fix duplicate clocks
  ARM: davinci: remove davinci_set_refclk_rate()
  clk: Introduce davinci clocks
  ARM: davinci: convert to common clock framework
  ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS

 arch/arm/Kconfig                            |   2 +-
 arch/arm/configs/davinci_all_defconfig      |   1 -
 arch/arm/mach-davinci/Kconfig               |  12 -
 arch/arm/mach-davinci/Makefile              |   2 +-
 arch/arm/mach-davinci/board-da830-evm.c     |  17 +-
 arch/arm/mach-davinci/board-da850-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm355-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm355-leopard.c |   2 +-
 arch/arm/mach-davinci/board-dm365-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm644x-evm.c    |   2 +-
 arch/arm/mach-davinci/board-dm646x-evm.c    |  17 +-
 arch/arm/mach-davinci/board-mityomapl138.c  |   2 +-
 arch/arm/mach-davinci/board-neuros-osd2.c   |   2 +-
 arch/arm/mach-davinci/board-omapl138-hawk.c |  17 +-
 arch/arm/mach-davinci/board-sffsdr.c        |   2 +-
 arch/arm/mach-davinci/clock.c               | 745 --------------------------
 arch/arm/mach-davinci/clock.h               |  72 ---
 arch/arm/mach-davinci/common.c              |   1 -
 arch/arm/mach-davinci/da830.c               | 536 +++++--------------
 arch/arm/mach-davinci/da850.c               | 785 ++++++----------------------
 arch/arm/mach-davinci/da8xx-dt.c            |  17 +-
 arch/arm/mach-davinci/davinci.h             |   4 +
 arch/arm/mach-davinci/devices-da8xx.c       |  46 +-
 arch/arm/mach-davinci/dm355.c               | 452 ++++------------
 arch/arm/mach-davinci/dm365.c               | 594 ++++++---------------
 arch/arm/mach-davinci/dm644x.c              | 401 ++++----------
 arch/arm/mach-davinci/dm646x.c              | 451 +++++-----------
 arch/arm/mach-davinci/include/mach/clock.h  |   3 -
 arch/arm/mach-davinci/include/mach/common.h |   9 -
 arch/arm/mach-davinci/include/mach/da8xx.h  |  11 +-
 arch/arm/mach-davinci/psc.c                 | 137 -----
 arch/arm/mach-davinci/psc.h                 |  14 -
 arch/arm/mach-davinci/usb-da8xx.c           | 225 +-------
 drivers/clk/Makefile                        |   1 +
 drivers/clk/davinci/Makefile                |   3 +
 drivers/clk/davinci/da8xx-cfgchip-clk.c     | 380 ++++++++++++++
 drivers/clk/davinci/pll.c                   | 333 ++++++++++++
 drivers/clk/davinci/psc.c                   | 217 ++++++++
 include/linux/clk/davinci.h                 |  46 ++
 include/linux/platform_data/davinci_clk.h   |  25 +
 40 files changed, 1875 insertions(+), 3717 deletions(-)
 delete mode 100644 arch/arm/mach-davinci/clock.c
 delete mode 100644 arch/arm/mach-davinci/psc.c
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
 create mode 100644 drivers/clk/davinci/pll.c
 create mode 100644 drivers/clk/davinci/psc.c
 create mode 100644 include/linux/clk/davinci.h
 create mode 100644 include/linux/platform_data/davinci_clk.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2017-12-31 23:39 ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

This series converts mach-davinci to use the common clock framework.

Basically, this series does some cleanup and rearranging to get things
ready for the conversion. Then there is a patch to add new driver in
drivers/clk and finally a patch to make the conversion from the mach
clock drivers to the new drivers.

I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
that I haven't broken anything (too badly) in da850. But, I don't have
other hardware to test.

The one thing that I know I have broken is CPU frequency scaling on da850.
I don't think it was working with device tree anyway, so I can't really test
it with the hardware I have. I'm hoping that it will be OK to defer fixing
it and add device tree support at the same time.

Dependencies:
* This series applies on top of "ARM: davinici: move watchdog restart from
  mach to drivers?" [1][2]
* On da850, you will also need a patch to prevent problems with the USB PHY
  clocks [3]
* Or get it all at once:
    git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4

[1]: https://patchwork.kernel.org/patch/10105623/
[2]: https://patchwork.kernel.org/patch/10105613/
[3]: https://patchwork.kernel.org/patch/10133193/


v4 changes:
* Basically, the whole series is new/reworked except for the first patch.
* Instead of having an intermediate conversion of the clocks in mach-davinci,
  new clock drivers are introduced in drivers/clk.
* There are a few more cleanup patches added before making the conversion.

v3 changes:
* Remove leftovers from rebasing in "ARM: davinci: don't use static clk_lookup"
  (fixes compile error)

v2 changes:
* Dropped "ARM: davinci: clean up map_io functions" - will resend as separate
  patch series
* Reworked remaining patches so that there is less shuffling around



David Lechner (7):
  ARM: davinci: move davinci_clk_init() to init_time
  ARM: davinci: don't use static clk_lookup
  ARM: davinci: fix duplicate clocks
  ARM: davinci: remove davinci_set_refclk_rate()
  clk: Introduce davinci clocks
  ARM: davinci: convert to common clock framework
  ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS

 arch/arm/Kconfig                            |   2 +-
 arch/arm/configs/davinci_all_defconfig      |   1 -
 arch/arm/mach-davinci/Kconfig               |  12 -
 arch/arm/mach-davinci/Makefile              |   2 +-
 arch/arm/mach-davinci/board-da830-evm.c     |  17 +-
 arch/arm/mach-davinci/board-da850-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm355-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm355-leopard.c |   2 +-
 arch/arm/mach-davinci/board-dm365-evm.c     |   2 +-
 arch/arm/mach-davinci/board-dm644x-evm.c    |   2 +-
 arch/arm/mach-davinci/board-dm646x-evm.c    |  17 +-
 arch/arm/mach-davinci/board-mityomapl138.c  |   2 +-
 arch/arm/mach-davinci/board-neuros-osd2.c   |   2 +-
 arch/arm/mach-davinci/board-omapl138-hawk.c |  17 +-
 arch/arm/mach-davinci/board-sffsdr.c        |   2 +-
 arch/arm/mach-davinci/clock.c               | 745 --------------------------
 arch/arm/mach-davinci/clock.h               |  72 ---
 arch/arm/mach-davinci/common.c              |   1 -
 arch/arm/mach-davinci/da830.c               | 536 +++++--------------
 arch/arm/mach-davinci/da850.c               | 785 ++++++----------------------
 arch/arm/mach-davinci/da8xx-dt.c            |  17 +-
 arch/arm/mach-davinci/davinci.h             |   4 +
 arch/arm/mach-davinci/devices-da8xx.c       |  46 +-
 arch/arm/mach-davinci/dm355.c               | 452 ++++------------
 arch/arm/mach-davinci/dm365.c               | 594 ++++++---------------
 arch/arm/mach-davinci/dm644x.c              | 401 ++++----------
 arch/arm/mach-davinci/dm646x.c              | 451 +++++-----------
 arch/arm/mach-davinci/include/mach/clock.h  |   3 -
 arch/arm/mach-davinci/include/mach/common.h |   9 -
 arch/arm/mach-davinci/include/mach/da8xx.h  |  11 +-
 arch/arm/mach-davinci/psc.c                 | 137 -----
 arch/arm/mach-davinci/psc.h                 |  14 -
 arch/arm/mach-davinci/usb-da8xx.c           | 225 +-------
 drivers/clk/Makefile                        |   1 +
 drivers/clk/davinci/Makefile                |   3 +
 drivers/clk/davinci/da8xx-cfgchip-clk.c     | 380 ++++++++++++++
 drivers/clk/davinci/pll.c                   | 333 ++++++++++++
 drivers/clk/davinci/psc.c                   | 217 ++++++++
 include/linux/clk/davinci.h                 |  46 ++
 include/linux/platform_data/davinci_clk.h   |  25 +
 40 files changed, 1875 insertions(+), 3717 deletions(-)
 delete mode 100644 arch/arm/mach-davinci/clock.c
 delete mode 100644 arch/arm/mach-davinci/psc.c
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
 create mode 100644 drivers/clk/davinci/pll.c
 create mode 100644 drivers/clk/davinci/psc.c
 create mode 100644 include/linux/clk/davinci.h
 create mode 100644 include/linux/platform_data/davinci_clk.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 1/7] ARM: davinci: move davinci_clk_init() to init_time
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

This moves the call of davinci_clk_init() from map_io to init_time for all
boards.

This is the proper place to init clocks. This is also done in preparation
for moving to the common clock framework.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/board-da830-evm.c     |  2 +-
 arch/arm/mach-davinci/board-da850-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm355-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm355-leopard.c |  2 +-
 arch/arm/mach-davinci/board-dm365-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm644x-evm.c    |  2 +-
 arch/arm/mach-davinci/board-dm646x-evm.c    | 11 +++++++----
 arch/arm/mach-davinci/board-mityomapl138.c  |  2 +-
 arch/arm/mach-davinci/board-neuros-osd2.c   |  2 +-
 arch/arm/mach-davinci/board-omapl138-hawk.c |  2 +-
 arch/arm/mach-davinci/board-sffsdr.c        |  2 +-
 arch/arm/mach-davinci/da830.c               |  4 ++++
 arch/arm/mach-davinci/da850.c               |  4 ++++
 arch/arm/mach-davinci/da8xx-dt.c            |  2 +-
 arch/arm/mach-davinci/davinci.h             |  4 ++++
 arch/arm/mach-davinci/dm355.c               |  5 +++++
 arch/arm/mach-davinci/dm365.c               |  5 +++++
 arch/arm/mach-davinci/dm644x.c              |  5 +++++
 arch/arm/mach-davinci/dm646x.c              |  5 +++++
 arch/arm/mach-davinci/include/mach/da8xx.h  |  3 +++
 20 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index a58bfca..7adf009 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -638,7 +638,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da830_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da830_init_time,
 	.init_machine	= da830_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 6039ec1..8602d0d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1481,7 +1481,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da850_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index d60d998..3c15cb7 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -416,7 +416,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 1e7e9b8..3ebc89d 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -271,7 +271,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_leopard_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_leopard_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 17b2c29..3daeac7 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -774,7 +774,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
 	.atag_offset	= 0x100,
 	.map_io		= dm365_evm_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm365_init_time,
 	.init_machine	= dm365_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 5e1afc2..8d8c4ab 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -817,7 +817,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 003bbe5..dafc852 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -721,9 +721,12 @@ static void __init evm_init_i2c(void)
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
+}
 
-	if (machine_is_davinci_dm6467tevm())
-		davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+static void __init dm6467t_evm_init_time(void)
+{
+	dm646x_init_time();
+	davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
 }
 
 #define DM646X_EVM_PHY_ID		"davinci_mdio-0:01"
@@ -797,7 +800,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm646x_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
@@ -807,7 +810,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm6467t_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 0b23cf3..f9a725a 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -570,7 +570,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
 	.atag_offset	= 0x100,
 	.map_io		= mityomapl138_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= mityomapl138_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 1e27baa..ff871a0 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -227,7 +227,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
 	.atag_offset	= 0x100,
 	.map_io		 = davinci_ntosd2_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_ntosd2_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 88ab45c..bc8a747 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -334,7 +334,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
 	.atag_offset	= 0x100,
 	.map_io		= omapl138_hawk_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= omapl138_hawk_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 1f02d4e..2922da9 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -150,7 +150,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_sffsdr_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_sffsdr_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index ed0b700..6a8b6ff 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1220,6 +1220,10 @@ void __init da830_init(void)
 
 	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
 
+void __init da830_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 04a58a3..4da5b25 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1392,6 +1392,10 @@ void __init da850_init(void)
 	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 	v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
 	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
 
+void __init da850_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 779e8ce..ab199f4 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -96,7 +96,7 @@ static const char *const da850_boards_compat[] __initconst = {
 
 DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
 	.map_io		= da850_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_init_machine,
 	.dt_compat	= da850_boards_compat,
 	.init_late	= davinci_init_late,
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c62b90c..d70f4d9 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -83,6 +83,7 @@ int davinci_init_wdt(void);
 
 /* DM355 function declarations */
 void dm355_init(void);
+void dm355_init_time(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		const struct spi_board_info *info, unsigned len);
 void dm355_init_asp1(u32 evt_enable);
@@ -91,6 +92,7 @@ int dm355_gpio_register(void);
 
 /* DM365 function declarations */
 void dm365_init(void);
+void dm365_init_time(void);
 void dm365_init_asp(void);
 void dm365_init_vc(void);
 void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -102,12 +104,14 @@ int dm365_gpio_register(void);
 
 /* DM644x function declarations */
 void dm644x_init(void);
+void dm644x_init_time(void);
 void dm644x_init_asp(void);
 int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
 int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
+void dm646x_init_time(void);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 938747f..40641c0 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1043,7 +1043,12 @@ void __init dm355_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm355);
 	davinci_map_sysmod();
+}
+
+void __init dm355_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+	davinci_timer_init();
 }
 
 int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 5d9f96d..0789ac6 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1168,7 +1168,12 @@ void __init dm365_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm365);
 	davinci_map_sysmod();
+}
+
+void __init dm365_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+	davinci_timer_init();
 }
 
 static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 6b41e1c..a1a2433 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -931,7 +931,12 @@ void __init dm644x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm644x);
 	davinci_map_sysmod();
+}
+
+void __init dm644x_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+	davinci_timer_init();
 }
 
 int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 6fc06a6..c518403 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -956,7 +956,12 @@ void __init dm646x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm646x);
 	davinci_map_sysmod();
+}
+
+void __init dm646x_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+	davinci_timer_init();
 }
 
 static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 751d2ac..3481a0d 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -87,7 +87,10 @@ extern unsigned int da850_max_speed;
 #define DA8XX_ARM_RAM_BASE	0xffff0000
 
 void da830_init(void);
+void da830_init_time(void);
+
 void da850_init(void);
+void da850_init_time(void);
 
 int da830_register_edma(struct edma_rsv_info *rsv);
 int da850_register_edma(struct edma_rsv_info *rsv[2]);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 1/7] ARM: davinci: move davinci_clk_init() to init_time
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

This moves the call of davinci_clk_init() from map_io to init_time for all
boards.

This is the proper place to init clocks. This is also done in preparation
for moving to the common clock framework.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/board-da830-evm.c     |  2 +-
 arch/arm/mach-davinci/board-da850-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm355-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm355-leopard.c |  2 +-
 arch/arm/mach-davinci/board-dm365-evm.c     |  2 +-
 arch/arm/mach-davinci/board-dm644x-evm.c    |  2 +-
 arch/arm/mach-davinci/board-dm646x-evm.c    | 11 +++++++----
 arch/arm/mach-davinci/board-mityomapl138.c  |  2 +-
 arch/arm/mach-davinci/board-neuros-osd2.c   |  2 +-
 arch/arm/mach-davinci/board-omapl138-hawk.c |  2 +-
 arch/arm/mach-davinci/board-sffsdr.c        |  2 +-
 arch/arm/mach-davinci/da830.c               |  4 ++++
 arch/arm/mach-davinci/da850.c               |  4 ++++
 arch/arm/mach-davinci/da8xx-dt.c            |  2 +-
 arch/arm/mach-davinci/davinci.h             |  4 ++++
 arch/arm/mach-davinci/dm355.c               |  5 +++++
 arch/arm/mach-davinci/dm365.c               |  5 +++++
 arch/arm/mach-davinci/dm644x.c              |  5 +++++
 arch/arm/mach-davinci/dm646x.c              |  5 +++++
 arch/arm/mach-davinci/include/mach/da8xx.h  |  3 +++
 20 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index a58bfca..7adf009 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -638,7 +638,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da830_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da830_init_time,
 	.init_machine	= da830_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 6039ec1..8602d0d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1481,7 +1481,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
 	.atag_offset	= 0x100,
 	.map_io		= da850_evm_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index d60d998..3c15cb7 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -416,7 +416,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 1e7e9b8..3ebc89d 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -271,7 +271,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
 	.atag_offset  = 0x100,
 	.map_io	      = dm355_leopard_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm355_init_time,
 	.init_machine = dm355_leopard_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 17b2c29..3daeac7 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -774,7 +774,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
 	.atag_offset	= 0x100,
 	.map_io		= dm365_evm_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm365_init_time,
 	.init_machine	= dm365_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 5e1afc2..8d8c4ab 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -817,7 +817,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_evm_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 003bbe5..dafc852 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -721,9 +721,12 @@ static void __init evm_init_i2c(void)
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
+}
 
-	if (machine_is_davinci_dm6467tevm())
-		davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+static void __init dm6467t_evm_init_time(void)
+{
+	dm646x_init_time();
+	davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
 }
 
 #define DM646X_EVM_PHY_ID		"davinci_mdio-0:01"
@@ -797,7 +800,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm646x_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
@@ -807,7 +810,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm6467t_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 0b23cf3..f9a725a 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -570,7 +570,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
 	.atag_offset	= 0x100,
 	.map_io		= mityomapl138_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= mityomapl138_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 1e27baa..ff871a0 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -227,7 +227,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
 	.atag_offset	= 0x100,
 	.map_io		 = davinci_ntosd2_map_io,
 	.init_irq	= davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_ntosd2_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 88ab45c..bc8a747 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -334,7 +334,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
 	.atag_offset	= 0x100,
 	.map_io		= omapl138_hawk_map_io,
 	.init_irq	= cp_intc_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= omapl138_hawk_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 1f02d4e..2922da9 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -150,7 +150,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_sffsdr_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= dm644x_init_time,
 	.init_machine = davinci_sffsdr_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index ed0b700..6a8b6ff 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1220,6 +1220,10 @@ void __init da830_init(void)
 
 	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
 	WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
 
+void __init da830_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 04a58a3..4da5b25 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1392,6 +1392,10 @@ void __init da850_init(void)
 	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 	v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
 	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
 
+void __init da850_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 779e8ce..ab199f4 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -96,7 +96,7 @@ static const char *const da850_boards_compat[] __initconst = {
 
 DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
 	.map_io		= da850_init,
-	.init_time	= davinci_timer_init,
+	.init_time	= da850_init_time,
 	.init_machine	= da850_init_machine,
 	.dt_compat	= da850_boards_compat,
 	.init_late	= davinci_init_late,
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c62b90c..d70f4d9 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -83,6 +83,7 @@ int davinci_init_wdt(void);
 
 /* DM355 function declarations */
 void dm355_init(void);
+void dm355_init_time(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		const struct spi_board_info *info, unsigned len);
 void dm355_init_asp1(u32 evt_enable);
@@ -91,6 +92,7 @@ int dm355_gpio_register(void);
 
 /* DM365 function declarations */
 void dm365_init(void);
+void dm365_init_time(void);
 void dm365_init_asp(void);
 void dm365_init_vc(void);
 void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -102,12 +104,14 @@ int dm365_gpio_register(void);
 
 /* DM644x function declarations */
 void dm644x_init(void);
+void dm644x_init_time(void);
 void dm644x_init_asp(void);
 int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
 int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
+void dm646x_init_time(void);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 938747f..40641c0 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1043,7 +1043,12 @@ void __init dm355_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm355);
 	davinci_map_sysmod();
+}
+
+void __init dm355_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+	davinci_timer_init();
 }
 
 int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 5d9f96d..0789ac6 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1168,7 +1168,12 @@ void __init dm365_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm365);
 	davinci_map_sysmod();
+}
+
+void __init dm365_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+	davinci_timer_init();
 }
 
 static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 6b41e1c..a1a2433 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -931,7 +931,12 @@ void __init dm644x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm644x);
 	davinci_map_sysmod();
+}
+
+void __init dm644x_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+	davinci_timer_init();
 }
 
 int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 6fc06a6..c518403 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -956,7 +956,12 @@ void __init dm646x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm646x);
 	davinci_map_sysmod();
+}
+
+void __init dm646x_init_time(void)
+{
 	davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+	davinci_timer_init();
 }
 
 static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 751d2ac..3481a0d 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -87,7 +87,10 @@ extern unsigned int da850_max_speed;
 #define DA8XX_ARM_RAM_BASE	0xffff0000
 
 void da830_init(void);
+void da830_init_time(void);
+
 void da850_init(void);
+void da850_init_time(void);
 
 int da830_register_edma(struct edma_rsv_info *rsv);
 int da850_register_edma(struct edma_rsv_info *rsv[2]);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

In preparation of moving to the common clock framework, usage of static
struct clk_lookup is removed. The common clock framework uses an opaque
struct clk, so we won't be able to use static tables as was previously
done.

davinci_clk_init() is changed to init a single clock instead of a table
and an individual clk_register_clkdev() is added for each clock.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/clock.c               |  73 +++++------
 arch/arm/mach-davinci/clock.h               |   9 +-
 arch/arm/mach-davinci/da830.c               | 164 +++++++++++++++--------
 arch/arm/mach-davinci/da850.c               | 197 ++++++++++++++++++----------
 arch/arm/mach-davinci/devices-da8xx.c       |   5 +-
 arch/arm/mach-davinci/dm355.c               | 137 ++++++++++++-------
 arch/arm/mach-davinci/dm365.c               | 182 ++++++++++++++++---------
 arch/arm/mach-davinci/dm644x.c              | 125 ++++++++++++------
 arch/arm/mach-davinci/dm646x.c              | 131 +++++++++++-------
 arch/arm/mach-davinci/include/mach/common.h |   1 -
 arch/arm/mach-davinci/usb-da8xx.c           |  15 +--
 11 files changed, 652 insertions(+), 387 deletions(-)

diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f77a4f7..f82a90c 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -607,62 +607,51 @@ int davinci_set_refclk_rate(unsigned long rate)
 	return 0;
 }
 
-int __init davinci_clk_init(struct clk_lookup *clocks)
+struct clk * __init davinci_clk_init(struct clk *clk)
 {
-	struct clk_lookup *c;
-	struct clk *clk;
-	size_t num_clocks = 0;
-
-	for (c = clocks; c->clk; c++) {
-		clk = c->clk;
+	if (!clk->recalc) {
 
-		if (!clk->recalc) {
+		/* Check if clock is a PLL */
+		if (clk->pll_data)
+			clk->recalc = clk_pllclk_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;
 
-			/* 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;
-		}
+		/* 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 (clk->pll_data) {
+		struct pll_data *pll = clk->pll_data;
 
-			if (!pll->div_ratio_mask)
-				pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+		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 (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->recalc)
+		clk->rate = clk->recalc(clk);
 
-		if (clk->flags & PSC_LRST)
-			clk->reset = davinci_clk_reset;
+	if (clk->lpsc)
+		clk->flags |= CLK_PSC;
 
-		clk_register(clk);
-		num_clocks++;
+	if (clk->flags & PSC_LRST)
+		clk->reset = davinci_clk_reset;
 
-		/* Turn on clocks that Linux doesn't otherwise manage */
-		if (clk->flags & ALWAYS_ENABLED)
-			clk_enable(clk);
-	}
+	clk_register(clk);
 
-	clkdev_add_table(clocks, num_clocks);
+	/* Turn on clocks that Linux doesn't otherwise manage */
+	if (clk->flags & ALWAYS_ENABLED)
+		clk_enable(clk);
 
-	return 0;
+	return clk;
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index cf46781..66c40a2 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -118,14 +118,7 @@ struct clk {
 #define PSC_FORCE		BIT(6) /* Force module state transtition */
 #define PSC_LRST		BIT(8) /* Use local reset on enable/disable */
 
-#define CLK(dev, con, ck) 	\
-	{			\
-		.dev_id = dev,	\
-		.con_id = con,	\
-		.clk = ck,	\
-	}			\
-
-int davinci_clk_init(struct clk_lookup *clocks);
+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);
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 6a8b6ff..73c48f5 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -378,60 +378,113 @@ static struct clk rmii_clk = {
 	.parent		= &pll0_sysclk7,
 };
 
-static struct clk_lookup da830_clks[] = {
-	CLK(NULL,		"ref",		&ref_clk),
-	CLK(NULL,		"pll0",		&pll0_clk),
-	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
-	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
-	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
-	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
-	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
-	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
-	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
-	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
-	CLK(NULL,		"timer0",	&timerp64_0_clk),
-	CLK("davinci-wdt",	NULL,		&timerp64_1_clk),
-	CLK(NULL,		"arm_rom",	&arm_rom_clk),
-	CLK(NULL,		"scr0_ss",	&scr0_ss_clk),
-	CLK(NULL,		"scr1_ss",	&scr1_ss_clk),
-	CLK(NULL,		"scr2_ss",	&scr2_ss_clk),
-	CLK(NULL,		"dmax",		&dmax_clk),
-	CLK(NULL,		"tpcc",		&tpcc_clk),
-	CLK(NULL,		"tptc0",	&tptc0_clk),
-	CLK(NULL,		"tptc1",	&tptc1_clk),
-	CLK("da830-mmc.0",	NULL,		&mmcsd_clk),
-	CLK("serial8250.0",	NULL,		&uart0_clk),
-	CLK("serial8250.1",	NULL,		&uart1_clk),
-	CLK("serial8250.2",	NULL,		&uart2_clk),
-	CLK("spi_davinci.0",	NULL,		&spi0_clk),
-	CLK("spi_davinci.1",	NULL,		&spi1_clk),
-	CLK(NULL,		"ecap0",	&ecap0_clk),
-	CLK(NULL,		"ecap1",	&ecap1_clk),
-	CLK(NULL,		"ecap2",	&ecap2_clk),
-	CLK(NULL,		"pwm0",		&pwm0_clk),
-	CLK(NULL,		"pwm1",		&pwm1_clk),
-	CLK(NULL,		"pwm2",		&pwm2_clk),
-	CLK("eqep.0",		NULL,		&eqep0_clk),
-	CLK("eqep.1",		NULL,		&eqep1_clk),
-	CLK("da8xx_lcdc.0",	"fck",		&lcdc_clk),
-	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
-	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
-	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
-	CLK("musb-da8xx",	"usb20",	&usb20_clk),
-	CLK("cppi41-dmaengine",	NULL,		&cppi41_clk),
-	CLK(NULL,		"aemif",	&aemif_clk),
-	CLK(NULL,		"aintc",	&aintc_clk),
-	CLK(NULL,		"secu_mgr",	&secu_mgr_clk),
-	CLK("davinci_emac.1",	NULL,		&emac_clk),
-	CLK("davinci_mdio.0",   "fck",          &emac_clk),
-	CLK(NULL,		"gpio",		&gpio_clk),
-	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
-	CLK("ohci-da8xx",	"usb11",	&usb11_clk),
-	CLK(NULL,		"emif3",	&emif3_clk),
-	CLK(NULL,		"arm",		&arm_clk),
-	CLK(NULL,		"rmii",		&rmii_clk),
-	CLK(NULL,		NULL,		NULL),
-};
+static __init void da830_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll0_clk);
+	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_sysclk2);
+	clk_register_clkdev(clk, "pll0_sysclk2", NULL);
+	clk = davinci_clk_init(&pll0_sysclk3);
+	clk_register_clkdev(clk, "pll0_sysclk3", NULL);
+	clk = davinci_clk_init(&pll0_sysclk4);
+	clk_register_clkdev(clk, "pll0_sysclk4", NULL);
+	clk = davinci_clk_init(&pll0_sysclk5);
+	clk_register_clkdev(clk, "pll0_sysclk5", NULL);
+	clk = davinci_clk_init(&pll0_sysclk6);
+	clk_register_clkdev(clk, "pll0_sysclk6", NULL);
+	clk = davinci_clk_init(&pll0_sysclk7);
+	clk_register_clkdev(clk, "pll0_sysclk7", NULL);
+	clk = davinci_clk_init(&i2c0_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&timerp64_0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timerp64_1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&arm_rom_clk);
+	clk_register_clkdev(clk, "arm_rom", NULL);
+	clk = davinci_clk_init(&scr0_ss_clk);
+	clk_register_clkdev(clk, "scr0_ss", NULL);
+	clk = davinci_clk_init(&scr1_ss_clk);
+	clk_register_clkdev(clk, "scr1_ss", NULL);
+	clk = davinci_clk_init(&scr2_ss_clk);
+	clk_register_clkdev(clk, "scr2_ss", NULL);
+	clk = davinci_clk_init(&dmax_clk);
+	clk_register_clkdev(clk, "dmax", NULL);
+	clk = davinci_clk_init(&tpcc_clk);
+	clk_register_clkdev(clk, "tpcc", NULL);
+	clk = davinci_clk_init(&tptc0_clk);
+	clk_register_clkdev(clk, "tptc0", NULL);
+	clk = davinci_clk_init(&tptc1_clk);
+	clk_register_clkdev(clk, "tptc1", NULL);
+	clk = davinci_clk_init(&mmcsd_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&ecap0_clk);
+	clk_register_clkdev(clk, "ecap0", NULL);
+	clk = davinci_clk_init(&ecap1_clk);
+	clk_register_clkdev(clk, "ecap1", NULL);
+	clk = davinci_clk_init(&ecap2_clk);
+	clk_register_clkdev(clk, "ecap2", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&eqep0_clk);
+	clk_register_clkdev(clk, NULL, "eqep.0");
+	clk = davinci_clk_init(&eqep1_clk);
+	clk_register_clkdev(clk, NULL, "eqep.1");
+	clk = davinci_clk_init(&lcdc_clk);
+	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
+	clk = davinci_clk_init(&mcasp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcasp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
+	clk = davinci_clk_init(&mcasp2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.2");
+	clk = davinci_clk_init(&usb20_clk);
+	clk_register_clkdev(clk, "usb20", "musb-da8xx");
+	clk = davinci_clk_init(&cppi41_clk);
+	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&aintc_clk);
+	clk_register_clkdev(clk, "aintc", NULL);
+	clk = davinci_clk_init(&secu_mgr_clk);
+	clk_register_clkdev(clk, "secu_mgr", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&i2c1_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.2");
+	clk = davinci_clk_init(&usb11_clk);
+	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
+	clk = davinci_clk_init(&emif3_clk);
+	clk_register_clkdev(clk, "emif3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&rmii_clk);
+	clk_register_clkdev(clk, "rmii", NULL);
+}
 
 /*
  * Device specific mux setup
@@ -1200,7 +1253,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),
-	.cpu_clks		= da830_clks,
 	.psc_bases		= da830_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1224,6 +1276,6 @@ void __init da830_init(void)
 
 void __init da830_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+	da830_clk_init();
 	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 4da5b25..eaa05ac 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -518,71 +518,135 @@ static struct clk ecap2_clk = {
 	.parent		= &ecap_clk,
 };
 
-static struct clk_lookup da850_clks[] = {
-	CLK(NULL,		"ref",		&ref_clk),
-	CLK(NULL,		"pll0",		&pll0_clk),
-	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
-	CLK(NULL,		"pll0_sysclk1",	&pll0_sysclk1),
-	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
-	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
-	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
-	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
-	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
-	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
-	CLK(NULL,		"pll1",		&pll1_clk),
-	CLK(NULL,		"pll1_aux",	&pll1_aux_clk),
-	CLK(NULL,		"pll1_sysclk2",	&pll1_sysclk2),
-	CLK(NULL,		"pll1_sysclk3",	&pll1_sysclk3),
-	CLK(NULL,		"async3",	&async3_clk),
-	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
-	CLK(NULL,		"timer0",	&timerp64_0_clk),
-	CLK("davinci-wdt",	NULL,		&timerp64_1_clk),
-	CLK(NULL,		"arm_rom",	&arm_rom_clk),
-	CLK(NULL,		"tpcc0",	&tpcc0_clk),
-	CLK(NULL,		"tptc0",	&tptc0_clk),
-	CLK(NULL,		"tptc1",	&tptc1_clk),
-	CLK(NULL,		"tpcc1",	&tpcc1_clk),
-	CLK(NULL,		"tptc2",	&tptc2_clk),
-	CLK("pruss_uio",	"pruss",	&pruss_clk),
-	CLK("serial8250.0",	NULL,		&uart0_clk),
-	CLK("serial8250.1",	NULL,		&uart1_clk),
-	CLK("serial8250.2",	NULL,		&uart2_clk),
-	CLK(NULL,		"aintc",	&aintc_clk),
-	CLK(NULL,		"gpio",		&gpio_clk),
-	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
-	CLK(NULL,		"emif3",	&emif3_clk),
-	CLK(NULL,		"arm",		&arm_clk),
-	CLK(NULL,		"rmii",		&rmii_clk),
-	CLK("davinci_emac.1",	NULL,		&emac_clk),
-	CLK("davinci_mdio.0",	"fck",		&mdio_clk),
-	CLK("davinci-mcasp.0",	NULL,		&mcasp_clk),
-	CLK("davinci-mcbsp.0",	NULL,		&mcbsp0_clk),
-	CLK("davinci-mcbsp.1",	NULL,		&mcbsp1_clk),
-	CLK("da8xx_lcdc.0",	"fck",		&lcdc_clk),
-	CLK("da830-mmc.0",	NULL,		&mmcsd0_clk),
-	CLK("da830-mmc.1",	NULL,		&mmcsd1_clk),
-	CLK("ti-aemif",		NULL,		&aemif_clk),
-	CLK("davinci-nand.0",	"aemif",	&aemif_nand_clk),
-	CLK("ohci-da8xx",	"usb11",	&usb11_clk),
-	CLK("musb-da8xx",	"usb20",	&usb20_clk),
-	CLK("cppi41-dmaengine",	NULL,		&cppi41_clk),
-	CLK("spi_davinci.0",	NULL,		&spi0_clk),
-	CLK("spi_davinci.1",	NULL,		&spi1_clk),
-	CLK("vpif",		NULL,		&vpif_clk),
-	CLK("ahci_da850",	"fck",		&sata_clk),
-	CLK("davinci-rproc.0",	NULL,		&dsp_clk),
-	CLK(NULL,		NULL,		&ehrpwm_clk),
-	CLK("ehrpwm.0",		"fck",		&ehrpwm0_clk),
-	CLK("ehrpwm.1",		"fck",		&ehrpwm1_clk),
-	CLK(NULL,		NULL,		&ehrpwm_tbclk),
-	CLK("ehrpwm.0",		"tbclk",	&ehrpwm0_tbclk),
-	CLK("ehrpwm.1",		"tbclk",	&ehrpwm1_tbclk),
-	CLK(NULL,		NULL,		&ecap_clk),
-	CLK("ecap.0",		"fck",		&ecap0_clk),
-	CLK("ecap.1",		"fck",		&ecap1_clk),
-	CLK("ecap.2",		"fck",		&ecap2_clk),
-	CLK(NULL,		NULL,		NULL),
-};
+static __init void da850_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll0_clk);
+	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_register_clkdev(clk, "pll0_sysclk1", NULL);
+	clk = davinci_clk_init(&pll0_sysclk2);
+	clk_register_clkdev(clk, "pll0_sysclk2", NULL);
+	clk = davinci_clk_init(&pll0_sysclk3);
+	clk_register_clkdev(clk, "pll0_sysclk3", NULL);
+	clk = davinci_clk_init(&pll0_sysclk4);
+	clk_register_clkdev(clk, "pll0_sysclk4", NULL);
+	clk = davinci_clk_init(&pll0_sysclk5);
+	clk_register_clkdev(clk, "pll0_sysclk5", NULL);
+	clk = davinci_clk_init(&pll0_sysclk6);
+	clk_register_clkdev(clk, "pll0_sysclk6", NULL);
+	clk = davinci_clk_init(&pll0_sysclk7);
+	clk_register_clkdev(clk, "pll0_sysclk7", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&async3_clk);
+	clk_register_clkdev(clk, "async3", NULL);
+	clk = davinci_clk_init(&i2c0_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&timerp64_0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timerp64_1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&arm_rom_clk);
+	clk_register_clkdev(clk, "arm_rom", NULL);
+	clk = davinci_clk_init(&tpcc0_clk);
+	clk_register_clkdev(clk, "tpcc0", NULL);
+	clk = davinci_clk_init(&tptc0_clk);
+	clk_register_clkdev(clk, "tptc0", NULL);
+	clk = davinci_clk_init(&tptc1_clk);
+	clk_register_clkdev(clk, "tptc1", NULL);
+	clk = davinci_clk_init(&tpcc1_clk);
+	clk_register_clkdev(clk, "tpcc1", NULL);
+	clk = davinci_clk_init(&tptc2_clk);
+	clk_register_clkdev(clk, "tptc2", NULL);
+	clk = davinci_clk_init(&pruss_clk);
+	clk_register_clkdev(clk, "pruss", "pruss_uio");
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&aintc_clk);
+	clk_register_clkdev(clk, "aintc", NULL);
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&i2c1_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.2");
+	clk = davinci_clk_init(&emif3_clk);
+	clk_register_clkdev(clk, "emif3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&rmii_clk);
+	clk_register_clkdev(clk, "rmii", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&mdio_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&mcasp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcbsp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
+	clk = davinci_clk_init(&mcbsp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
+	clk = davinci_clk_init(&lcdc_clk);
+	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.1");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, NULL, "ti-aemif");
+	clk = davinci_clk_init(&aemif_nand_clk);
+	clk_register_clkdev(clk, "aemif", "davinci-nand.0");
+	clk = davinci_clk_init(&usb11_clk);
+	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
+	clk = davinci_clk_init(&usb20_clk);
+	clk_register_clkdev(clk, "usb20", "musb-da8xx");
+	clk = davinci_clk_init(&cppi41_clk);
+	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&vpif_clk);
+	clk_register_clkdev(clk, NULL, "vpif");
+	clk = davinci_clk_init(&sata_clk);
+	clk_register_clkdev(clk, "fck", "ahci_da850");
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-rproc.0");
+	clk = davinci_clk_init(&ehrpwm_clk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ehrpwm0_clk);
+	clk_register_clkdev(clk, "fck", "ehrpwm.0");
+	clk = davinci_clk_init(&ehrpwm1_clk);
+	clk_register_clkdev(clk, "fck", "ehrpwm.1");
+	clk = davinci_clk_init(&ehrpwm_tbclk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ehrpwm0_tbclk);
+	clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
+	clk = davinci_clk_init(&ehrpwm1_tbclk);
+	clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
+	clk = davinci_clk_init(&ecap_clk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ecap0_clk);
+	clk_register_clkdev(clk, "fck", "ecap.0");
+	clk = davinci_clk_init(&ecap1_clk);
+	clk_register_clkdev(clk, "fck", "ecap.1");
+	clk = davinci_clk_init(&ecap2_clk);
+	clk_register_clkdev(clk, "fck", "ecap.2");
+}
 
 /*
  * Device specific mux setup
@@ -1353,7 +1417,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),
-	.cpu_clks		= da850_clks,
 	.psc_bases		= da850_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1396,6 +1459,6 @@ void __init da850_init(void)
 
 void __init da850_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+	da850_clk_init();
 	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index fe5e15a..c9a79b2 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -1046,9 +1046,6 @@ static struct clk sata_refclk = {
 	.set_rate	= davinci_simple_set_rate,
 };
 
-static struct clk_lookup sata_refclk_lookup =
-		CLK("ahci_da850", "refclk", &sata_refclk);
-
 int __init da850_register_sata_refclk(int rate)
 {
 	int ret;
@@ -1058,7 +1055,7 @@ int __init da850_register_sata_refclk(int rate)
 	if (ret)
 		return ret;
 
-	clkdev_add(&sata_refclk_lookup);
+	clk_register_clkdev(&sata_refclk, "refclk", "ahci_da850");
 
 	return 0;
 }
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 40641c0..9e5cfa9 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -337,51 +337,95 @@ static struct clk usb_clk = {
 	.lpsc = DAVINCI_LPSC_USB,
 };
 
-static struct clk_lookup dm355_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "vpss_dac", &vpss_dac_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "clkout1", &clkout1_clk),
-	CLK(NULL, "clkout2", &clkout2_clk),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-	CLK(NULL, "clkout3", &clkout3_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "mjcp", &mjcp_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("davinci-mcbsp.0", NULL, &asp0_clk),
-	CLK("davinci-mcbsp.1", NULL, &asp1_clk),
-	CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
-	CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
-	CLK("spi_davinci.0", NULL, &spi0_clk),
-	CLK("spi_davinci.1", NULL, &spi1_clk),
-	CLK("spi_davinci.2", NULL, &spi2_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "pwm3", &pwm3_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, "timer3", &timer3_clk),
-	CLK(NULL, "rto", &rto_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm355_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk4", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&vpss_dac_clk);
+	clk_register_clkdev(clk, "vpss_dac", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&clkout1_clk);
+	clk_register_clkdev(clk, "clkout1", NULL);
+	clk = davinci_clk_init(&clkout2_clk);
+	clk_register_clkdev(clk, "clkout2", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclkbp);
+	clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
+	clk = davinci_clk_init(&clkout3_clk);
+	clk_register_clkdev(clk, "clkout3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&mjcp_clk);
+	clk_register_clkdev(clk, "mjcp", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&asp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
+	clk = davinci_clk_init(&asp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.1");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&spi2_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.2");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&pwm3_clk);
+	clk_register_clkdev(clk, "pwm3", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&timer3_clk);
+	clk_register_clkdev(clk, "timer3", NULL);
+	clk = davinci_clk_init(&rto_clk);
+	clk_register_clkdev(clk, "rto", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+}
 
 /*----------------------------------------------------------------------*/
 
@@ -1012,7 +1056,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm355_ids,
 	.ids_num		= ARRAY_SIZE(dm355_ids),
-	.cpu_clks		= dm355_clks,
 	.psc_bases		= dm355_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm355_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1047,7 +1090,7 @@ void __init dm355_init(void)
 
 void __init dm355_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+	dm355_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 0789ac6..0cf4ab4 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -425,66 +425,125 @@ static struct clk mjcp_clk = {
 	.lpsc		= DM365_LPSC_MJCP,
 };
 
-static struct clk_lookup dm365_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "clkout0", &clkout0_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-	CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
-	CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
-	CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
-	CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_aux", &pll2_aux_clk),
-	CLK(NULL, "clkout1", &clkout1_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-	CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
-	CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
-	CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
-	CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
-	CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
-	CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
-	CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
-	CLK(NULL, "vpss_dac", &vpss_dac_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("da830-mmc.0", NULL, &mmcsd0_clk),
-	CLK("da830-mmc.1", NULL, &mmcsd1_clk),
-	CLK("spi_davinci.0", NULL, &spi0_clk),
-	CLK("spi_davinci.1", NULL, &spi1_clk),
-	CLK("spi_davinci.2", NULL, &spi2_clk),
-	CLK("spi_davinci.3", NULL, &spi3_clk),
-	CLK("spi_davinci.4", NULL, &spi4_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "pwm3", &pwm3_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, "timer3", &timer3_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK("davinci_voicecodec", NULL, &voicecodec_clk),
-	CLK("davinci-mcbsp", NULL, &asp0_clk),
-	CLK(NULL, "rto", &rto_clk),
-	CLK(NULL, "mjcp", &mjcp_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm365_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&clkout0_clk);
+	clk_register_clkdev(clk, "clkout0", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk4", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk5", NULL);
+	clk = davinci_clk_init(&pll1_sysclk6);
+	clk_register_clkdev(clk, "pll1_sysclk6", NULL);
+	clk = davinci_clk_init(&pll1_sysclk7);
+	clk_register_clkdev(clk, "pll1_sysclk7", NULL);
+	clk = davinci_clk_init(&pll1_sysclk8);
+	clk_register_clkdev(clk, "pll1_sysclk8", NULL);
+	clk = davinci_clk_init(&pll1_sysclk9);
+	clk_register_clkdev(clk, "pll1_sysclk9", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_aux_clk);
+	clk_register_clkdev(clk, "pll2_aux", NULL);
+	clk = davinci_clk_init(&clkout1_clk);
+	clk_register_clkdev(clk, "clkout1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk2);
+	clk_register_clkdev(clk, "pll2_sysclk2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk3);
+	clk_register_clkdev(clk, "pll2_sysclk3", NULL);
+	clk = davinci_clk_init(&pll2_sysclk4);
+	clk_register_clkdev(clk, "pll2_sysclk4", NULL);
+	clk = davinci_clk_init(&pll2_sysclk5);
+	clk_register_clkdev(clk, "pll2_sysclk5", NULL);
+	clk = davinci_clk_init(&pll2_sysclk6);
+	clk_register_clkdev(clk, "pll2_sysclk6", NULL);
+	clk = davinci_clk_init(&pll2_sysclk7);
+	clk_register_clkdev(clk, "pll2_sysclk7", NULL);
+	clk = davinci_clk_init(&pll2_sysclk8);
+	clk_register_clkdev(clk, "pll2_sysclk8", NULL);
+	clk = davinci_clk_init(&pll2_sysclk9);
+	clk_register_clkdev(clk, "pll2_sysclk9", NULL);
+	clk = davinci_clk_init(&vpss_dac_clk);
+	clk_register_clkdev(clk, "vpss_dac", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.1");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&spi2_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.2");
+	clk = davinci_clk_init(&spi3_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.3");
+	clk = davinci_clk_init(&spi4_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.4");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&pwm3_clk);
+	clk_register_clkdev(clk, "pwm3", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&timer3_clk);
+	clk_register_clkdev(clk, "timer3", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&voicecodec_clk);
+	clk_register_clkdev(clk, NULL, "davinci_voicecodec");
+	clk = davinci_clk_init(&asp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp");
+	clk = davinci_clk_init(&rto_clk);
+	clk_register_clkdev(clk, "rto", NULL);
+	clk = davinci_clk_init(&mjcp_clk);
+	clk_register_clkdev(clk, "mjcp", NULL);
+}
 
 /*----------------------------------------------------------------------*/
 
@@ -1116,7 +1175,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm365_ids,
 	.ids_num		= ARRAY_SIZE(dm365_ids),
-	.cpu_clks		= dm365_clks,
 	.psc_bases		= dm365_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm365_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1172,7 +1230,7 @@ void __init dm365_init(void)
 
 void __init dm365_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+	dm365_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index a1a2433..769ce29 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -285,47 +285,87 @@ static struct clk timer2_clk = {
 	.usecount = 1,              /* REVISIT: why can't this be disabled? */
 };
 
-static struct clk_lookup dm644x_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-	CLK(NULL, "dsp", &dsp_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "vicp", &vicp_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK("davinci-mcbsp", NULL, &asp_clk),
-	CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
-	CLK(NULL, "spi", &spi_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK(NULL, "vlynq", &vlynq_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm644x_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk5", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk2);
+	clk_register_clkdev(clk, "pll2_sysclk2", NULL);
+	clk = davinci_clk_init(&pll2_sysclkbp);
+	clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, "dsp", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&vicp_clk);
+	clk_register_clkdev(clk, "vicp", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&ide_clk);
+	clk_register_clkdev(clk, NULL, "palm_bk3710");
+	clk = davinci_clk_init(&asp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp");
+	clk = davinci_clk_init(&mmcsd_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
+	clk = davinci_clk_init(&spi_clk);
+	clk_register_clkdev(clk, "spi", NULL);
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+	clk = davinci_clk_init(&vlynq_clk);
+	clk_register_clkdev(clk, "vlynq", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+}
 
 static struct emac_platform_data dm644x_emac_pdata = {
 	.ctrl_reg_offset	= DM644X_EMAC_CNTRL_OFFSET,
@@ -905,7 +945,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm644x_ids,
 	.ids_num		= ARRAY_SIZE(dm644x_ids),
-	.cpu_clks		= dm644x_clks,
 	.psc_bases		= dm644x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm644x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -935,7 +974,7 @@ void __init dm644x_init(void)
 
 void __init dm644x_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+	dm644x_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index c518403..d75b4bc09 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -320,49 +320,91 @@ static struct clk vpif1_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
-static struct clk_lookup dm646x_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "aux", &aux_clkin),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "dsp", &dsp_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "edma_cc", &edma_cc_clk),
-	CLK(NULL, "edma_tc0", &edma_tc0_clk),
-	CLK(NULL, "edma_tc1", &edma_tc1_clk),
-	CLK(NULL, "edma_tc2", &edma_tc2_clk),
-	CLK(NULL, "edma_tc3", &edma_tc3_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
-	CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK(NULL, "vpif0", &vpif0_clk),
-	CLK(NULL, "vpif1", &vpif1_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm646x_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&aux_clkin);
+	clk_register_clkdev(clk, "aux", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk6);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk8);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk9);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, "dsp", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&edma_cc_clk);
+	clk_register_clkdev(clk, "edma_cc", NULL);
+	clk = davinci_clk_init(&edma_tc0_clk);
+	clk_register_clkdev(clk, "edma_tc0", NULL);
+	clk = davinci_clk_init(&edma_tc1_clk);
+	clk_register_clkdev(clk, "edma_tc1", NULL);
+	clk = davinci_clk_init(&edma_tc2_clk);
+	clk_register_clkdev(clk, "edma_tc2", NULL);
+	clk = davinci_clk_init(&edma_tc3_clk);
+	clk_register_clkdev(clk, "edma_tc3", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&mcasp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcasp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&ide_clk);
+	clk_register_clkdev(clk, NULL, "palm_bk3710");
+	clk = davinci_clk_init(&vpif0_clk);
+	clk_register_clkdev(clk, "vpif0", NULL);
+	clk = davinci_clk_init(&vpif1_clk);
+	clk_register_clkdev(clk, "vpif1", NULL);
+}
 
 static struct emac_platform_data dm646x_emac_pdata = {
 	.ctrl_reg_offset	= DM646X_EMAC_CNTRL_OFFSET,
@@ -888,7 +930,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm646x_ids,
 	.ids_num		= ARRAY_SIZE(dm646x_ids),
-	.cpu_clks		= dm646x_clks,
 	.psc_bases		= dm646x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm646x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -960,7 +1001,7 @@ void __init dm646x_init(void)
 
 void __init dm646x_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+	dm646x_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 19b9346..f0d5e858 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,7 +53,6 @@ struct davinci_soc_info {
 	u32				jtag_id_reg;
 	struct davinci_id		*ids;
 	unsigned long			ids_num;
-	struct clk_lookup		*cpu_clks;
 	u32				*psc_bases;
 	unsigned long			psc_bases_num;
 	u32				pinmux_base;
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index d480a02..a2e575e 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -133,9 +133,6 @@ static struct clk usb_refclkin = {
 	.set_rate	= davinci_simple_set_rate,
 };
 
-static struct clk_lookup usb_refclkin_lookup =
-	CLK(NULL, "usb_refclkin", &usb_refclkin);
-
 /**
  * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
  *
@@ -154,7 +151,7 @@ int __init da8xx_register_usb_refclkin(int rate)
 	if (ret)
 		return ret;
 
-	clkdev_add(&usb_refclkin_lookup);
+	clk_register_clkdev(&usb_refclkin, "usb_refclkin", NULL);
 
 	return 0;
 }
@@ -262,9 +259,6 @@ static struct clk usb20_phy_clk = {
 	.set_parent	= usb20_phy_clk_set_parent,
 };
 
-static struct clk_lookup usb20_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
-
 /**
  * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
  *
@@ -291,7 +285,7 @@ int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
 	usb20_phy_clk.parent = parent;
 	ret = clk_register(&usb20_phy_clk);
 	if (!ret)
-		clkdev_add(&usb20_phy_clk_lookup);
+		clk_register_clkdev(&usb20_phy_clk, "usb20_phy", "da8xx-usb-phy");
 
 	clk_put(parent);
 
@@ -324,9 +318,6 @@ static struct clk usb11_phy_clk = {
 	.set_parent	= usb11_phy_clk_set_parent,
 };
 
-static struct clk_lookup usb11_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
-
 /**
  * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
  *
@@ -348,7 +339,7 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
 	usb11_phy_clk.parent = parent;
 	ret = clk_register(&usb11_phy_clk);
 	if (!ret)
-		clkdev_add(&usb11_phy_clk_lookup);
+		clk_register_clkdev(&usb11_phy_clk, "usb11_phy", "da8xx-usb-phy");
 
 	clk_put(parent);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

In preparation of moving to the common clock framework, usage of static
struct clk_lookup is removed. The common clock framework uses an opaque
struct clk, so we won't be able to use static tables as was previously
done.

davinci_clk_init() is changed to init a single clock instead of a table
and an individual clk_register_clkdev() is added for each clock.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/clock.c               |  73 +++++------
 arch/arm/mach-davinci/clock.h               |   9 +-
 arch/arm/mach-davinci/da830.c               | 164 +++++++++++++++--------
 arch/arm/mach-davinci/da850.c               | 197 ++++++++++++++++++----------
 arch/arm/mach-davinci/devices-da8xx.c       |   5 +-
 arch/arm/mach-davinci/dm355.c               | 137 ++++++++++++-------
 arch/arm/mach-davinci/dm365.c               | 182 ++++++++++++++++---------
 arch/arm/mach-davinci/dm644x.c              | 125 ++++++++++++------
 arch/arm/mach-davinci/dm646x.c              | 131 +++++++++++-------
 arch/arm/mach-davinci/include/mach/common.h |   1 -
 arch/arm/mach-davinci/usb-da8xx.c           |  15 +--
 11 files changed, 652 insertions(+), 387 deletions(-)

diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f77a4f7..f82a90c 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -607,62 +607,51 @@ int davinci_set_refclk_rate(unsigned long rate)
 	return 0;
 }
 
-int __init davinci_clk_init(struct clk_lookup *clocks)
+struct clk * __init davinci_clk_init(struct clk *clk)
 {
-	struct clk_lookup *c;
-	struct clk *clk;
-	size_t num_clocks = 0;
-
-	for (c = clocks; c->clk; c++) {
-		clk = c->clk;
+	if (!clk->recalc) {
 
-		if (!clk->recalc) {
+		/* Check if clock is a PLL */
+		if (clk->pll_data)
+			clk->recalc = clk_pllclk_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;
 
-			/* 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;
-		}
+		/* 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 (clk->pll_data) {
+		struct pll_data *pll = clk->pll_data;
 
-			if (!pll->div_ratio_mask)
-				pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+		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 (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->recalc)
+		clk->rate = clk->recalc(clk);
 
-		if (clk->flags & PSC_LRST)
-			clk->reset = davinci_clk_reset;
+	if (clk->lpsc)
+		clk->flags |= CLK_PSC;
 
-		clk_register(clk);
-		num_clocks++;
+	if (clk->flags & PSC_LRST)
+		clk->reset = davinci_clk_reset;
 
-		/* Turn on clocks that Linux doesn't otherwise manage */
-		if (clk->flags & ALWAYS_ENABLED)
-			clk_enable(clk);
-	}
+	clk_register(clk);
 
-	clkdev_add_table(clocks, num_clocks);
+	/* Turn on clocks that Linux doesn't otherwise manage */
+	if (clk->flags & ALWAYS_ENABLED)
+		clk_enable(clk);
 
-	return 0;
+	return clk;
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index cf46781..66c40a2 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -118,14 +118,7 @@ struct clk {
 #define PSC_FORCE		BIT(6) /* Force module state transtition */
 #define PSC_LRST		BIT(8) /* Use local reset on enable/disable */
 
-#define CLK(dev, con, ck) 	\
-	{			\
-		.dev_id = dev,	\
-		.con_id = con,	\
-		.clk = ck,	\
-	}			\
-
-int davinci_clk_init(struct clk_lookup *clocks);
+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);
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 6a8b6ff..73c48f5 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -378,60 +378,113 @@ static struct clk rmii_clk = {
 	.parent		= &pll0_sysclk7,
 };
 
-static struct clk_lookup da830_clks[] = {
-	CLK(NULL,		"ref",		&ref_clk),
-	CLK(NULL,		"pll0",		&pll0_clk),
-	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
-	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
-	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
-	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
-	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
-	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
-	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
-	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
-	CLK(NULL,		"timer0",	&timerp64_0_clk),
-	CLK("davinci-wdt",	NULL,		&timerp64_1_clk),
-	CLK(NULL,		"arm_rom",	&arm_rom_clk),
-	CLK(NULL,		"scr0_ss",	&scr0_ss_clk),
-	CLK(NULL,		"scr1_ss",	&scr1_ss_clk),
-	CLK(NULL,		"scr2_ss",	&scr2_ss_clk),
-	CLK(NULL,		"dmax",		&dmax_clk),
-	CLK(NULL,		"tpcc",		&tpcc_clk),
-	CLK(NULL,		"tptc0",	&tptc0_clk),
-	CLK(NULL,		"tptc1",	&tptc1_clk),
-	CLK("da830-mmc.0",	NULL,		&mmcsd_clk),
-	CLK("serial8250.0",	NULL,		&uart0_clk),
-	CLK("serial8250.1",	NULL,		&uart1_clk),
-	CLK("serial8250.2",	NULL,		&uart2_clk),
-	CLK("spi_davinci.0",	NULL,		&spi0_clk),
-	CLK("spi_davinci.1",	NULL,		&spi1_clk),
-	CLK(NULL,		"ecap0",	&ecap0_clk),
-	CLK(NULL,		"ecap1",	&ecap1_clk),
-	CLK(NULL,		"ecap2",	&ecap2_clk),
-	CLK(NULL,		"pwm0",		&pwm0_clk),
-	CLK(NULL,		"pwm1",		&pwm1_clk),
-	CLK(NULL,		"pwm2",		&pwm2_clk),
-	CLK("eqep.0",		NULL,		&eqep0_clk),
-	CLK("eqep.1",		NULL,		&eqep1_clk),
-	CLK("da8xx_lcdc.0",	"fck",		&lcdc_clk),
-	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
-	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
-	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
-	CLK("musb-da8xx",	"usb20",	&usb20_clk),
-	CLK("cppi41-dmaengine",	NULL,		&cppi41_clk),
-	CLK(NULL,		"aemif",	&aemif_clk),
-	CLK(NULL,		"aintc",	&aintc_clk),
-	CLK(NULL,		"secu_mgr",	&secu_mgr_clk),
-	CLK("davinci_emac.1",	NULL,		&emac_clk),
-	CLK("davinci_mdio.0",   "fck",          &emac_clk),
-	CLK(NULL,		"gpio",		&gpio_clk),
-	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
-	CLK("ohci-da8xx",	"usb11",	&usb11_clk),
-	CLK(NULL,		"emif3",	&emif3_clk),
-	CLK(NULL,		"arm",		&arm_clk),
-	CLK(NULL,		"rmii",		&rmii_clk),
-	CLK(NULL,		NULL,		NULL),
-};
+static __init void da830_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll0_clk);
+	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_sysclk2);
+	clk_register_clkdev(clk, "pll0_sysclk2", NULL);
+	clk = davinci_clk_init(&pll0_sysclk3);
+	clk_register_clkdev(clk, "pll0_sysclk3", NULL);
+	clk = davinci_clk_init(&pll0_sysclk4);
+	clk_register_clkdev(clk, "pll0_sysclk4", NULL);
+	clk = davinci_clk_init(&pll0_sysclk5);
+	clk_register_clkdev(clk, "pll0_sysclk5", NULL);
+	clk = davinci_clk_init(&pll0_sysclk6);
+	clk_register_clkdev(clk, "pll0_sysclk6", NULL);
+	clk = davinci_clk_init(&pll0_sysclk7);
+	clk_register_clkdev(clk, "pll0_sysclk7", NULL);
+	clk = davinci_clk_init(&i2c0_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&timerp64_0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timerp64_1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&arm_rom_clk);
+	clk_register_clkdev(clk, "arm_rom", NULL);
+	clk = davinci_clk_init(&scr0_ss_clk);
+	clk_register_clkdev(clk, "scr0_ss", NULL);
+	clk = davinci_clk_init(&scr1_ss_clk);
+	clk_register_clkdev(clk, "scr1_ss", NULL);
+	clk = davinci_clk_init(&scr2_ss_clk);
+	clk_register_clkdev(clk, "scr2_ss", NULL);
+	clk = davinci_clk_init(&dmax_clk);
+	clk_register_clkdev(clk, "dmax", NULL);
+	clk = davinci_clk_init(&tpcc_clk);
+	clk_register_clkdev(clk, "tpcc", NULL);
+	clk = davinci_clk_init(&tptc0_clk);
+	clk_register_clkdev(clk, "tptc0", NULL);
+	clk = davinci_clk_init(&tptc1_clk);
+	clk_register_clkdev(clk, "tptc1", NULL);
+	clk = davinci_clk_init(&mmcsd_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&ecap0_clk);
+	clk_register_clkdev(clk, "ecap0", NULL);
+	clk = davinci_clk_init(&ecap1_clk);
+	clk_register_clkdev(clk, "ecap1", NULL);
+	clk = davinci_clk_init(&ecap2_clk);
+	clk_register_clkdev(clk, "ecap2", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&eqep0_clk);
+	clk_register_clkdev(clk, NULL, "eqep.0");
+	clk = davinci_clk_init(&eqep1_clk);
+	clk_register_clkdev(clk, NULL, "eqep.1");
+	clk = davinci_clk_init(&lcdc_clk);
+	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
+	clk = davinci_clk_init(&mcasp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcasp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
+	clk = davinci_clk_init(&mcasp2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.2");
+	clk = davinci_clk_init(&usb20_clk);
+	clk_register_clkdev(clk, "usb20", "musb-da8xx");
+	clk = davinci_clk_init(&cppi41_clk);
+	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&aintc_clk);
+	clk_register_clkdev(clk, "aintc", NULL);
+	clk = davinci_clk_init(&secu_mgr_clk);
+	clk_register_clkdev(clk, "secu_mgr", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&i2c1_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.2");
+	clk = davinci_clk_init(&usb11_clk);
+	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
+	clk = davinci_clk_init(&emif3_clk);
+	clk_register_clkdev(clk, "emif3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&rmii_clk);
+	clk_register_clkdev(clk, "rmii", NULL);
+}
 
 /*
  * Device specific mux setup
@@ -1200,7 +1253,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),
-	.cpu_clks		= da830_clks,
 	.psc_bases		= da830_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1224,6 +1276,6 @@ void __init da830_init(void)
 
 void __init da830_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+	da830_clk_init();
 	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 4da5b25..eaa05ac 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -518,71 +518,135 @@ static struct clk ecap2_clk = {
 	.parent		= &ecap_clk,
 };
 
-static struct clk_lookup da850_clks[] = {
-	CLK(NULL,		"ref",		&ref_clk),
-	CLK(NULL,		"pll0",		&pll0_clk),
-	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
-	CLK(NULL,		"pll0_sysclk1",	&pll0_sysclk1),
-	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
-	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
-	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
-	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
-	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
-	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
-	CLK(NULL,		"pll1",		&pll1_clk),
-	CLK(NULL,		"pll1_aux",	&pll1_aux_clk),
-	CLK(NULL,		"pll1_sysclk2",	&pll1_sysclk2),
-	CLK(NULL,		"pll1_sysclk3",	&pll1_sysclk3),
-	CLK(NULL,		"async3",	&async3_clk),
-	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
-	CLK(NULL,		"timer0",	&timerp64_0_clk),
-	CLK("davinci-wdt",	NULL,		&timerp64_1_clk),
-	CLK(NULL,		"arm_rom",	&arm_rom_clk),
-	CLK(NULL,		"tpcc0",	&tpcc0_clk),
-	CLK(NULL,		"tptc0",	&tptc0_clk),
-	CLK(NULL,		"tptc1",	&tptc1_clk),
-	CLK(NULL,		"tpcc1",	&tpcc1_clk),
-	CLK(NULL,		"tptc2",	&tptc2_clk),
-	CLK("pruss_uio",	"pruss",	&pruss_clk),
-	CLK("serial8250.0",	NULL,		&uart0_clk),
-	CLK("serial8250.1",	NULL,		&uart1_clk),
-	CLK("serial8250.2",	NULL,		&uart2_clk),
-	CLK(NULL,		"aintc",	&aintc_clk),
-	CLK(NULL,		"gpio",		&gpio_clk),
-	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
-	CLK(NULL,		"emif3",	&emif3_clk),
-	CLK(NULL,		"arm",		&arm_clk),
-	CLK(NULL,		"rmii",		&rmii_clk),
-	CLK("davinci_emac.1",	NULL,		&emac_clk),
-	CLK("davinci_mdio.0",	"fck",		&mdio_clk),
-	CLK("davinci-mcasp.0",	NULL,		&mcasp_clk),
-	CLK("davinci-mcbsp.0",	NULL,		&mcbsp0_clk),
-	CLK("davinci-mcbsp.1",	NULL,		&mcbsp1_clk),
-	CLK("da8xx_lcdc.0",	"fck",		&lcdc_clk),
-	CLK("da830-mmc.0",	NULL,		&mmcsd0_clk),
-	CLK("da830-mmc.1",	NULL,		&mmcsd1_clk),
-	CLK("ti-aemif",		NULL,		&aemif_clk),
-	CLK("davinci-nand.0",	"aemif",	&aemif_nand_clk),
-	CLK("ohci-da8xx",	"usb11",	&usb11_clk),
-	CLK("musb-da8xx",	"usb20",	&usb20_clk),
-	CLK("cppi41-dmaengine",	NULL,		&cppi41_clk),
-	CLK("spi_davinci.0",	NULL,		&spi0_clk),
-	CLK("spi_davinci.1",	NULL,		&spi1_clk),
-	CLK("vpif",		NULL,		&vpif_clk),
-	CLK("ahci_da850",	"fck",		&sata_clk),
-	CLK("davinci-rproc.0",	NULL,		&dsp_clk),
-	CLK(NULL,		NULL,		&ehrpwm_clk),
-	CLK("ehrpwm.0",		"fck",		&ehrpwm0_clk),
-	CLK("ehrpwm.1",		"fck",		&ehrpwm1_clk),
-	CLK(NULL,		NULL,		&ehrpwm_tbclk),
-	CLK("ehrpwm.0",		"tbclk",	&ehrpwm0_tbclk),
-	CLK("ehrpwm.1",		"tbclk",	&ehrpwm1_tbclk),
-	CLK(NULL,		NULL,		&ecap_clk),
-	CLK("ecap.0",		"fck",		&ecap0_clk),
-	CLK("ecap.1",		"fck",		&ecap1_clk),
-	CLK("ecap.2",		"fck",		&ecap2_clk),
-	CLK(NULL,		NULL,		NULL),
-};
+static __init void da850_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll0_clk);
+	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_register_clkdev(clk, "pll0_sysclk1", NULL);
+	clk = davinci_clk_init(&pll0_sysclk2);
+	clk_register_clkdev(clk, "pll0_sysclk2", NULL);
+	clk = davinci_clk_init(&pll0_sysclk3);
+	clk_register_clkdev(clk, "pll0_sysclk3", NULL);
+	clk = davinci_clk_init(&pll0_sysclk4);
+	clk_register_clkdev(clk, "pll0_sysclk4", NULL);
+	clk = davinci_clk_init(&pll0_sysclk5);
+	clk_register_clkdev(clk, "pll0_sysclk5", NULL);
+	clk = davinci_clk_init(&pll0_sysclk6);
+	clk_register_clkdev(clk, "pll0_sysclk6", NULL);
+	clk = davinci_clk_init(&pll0_sysclk7);
+	clk_register_clkdev(clk, "pll0_sysclk7", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&async3_clk);
+	clk_register_clkdev(clk, "async3", NULL);
+	clk = davinci_clk_init(&i2c0_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&timerp64_0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timerp64_1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&arm_rom_clk);
+	clk_register_clkdev(clk, "arm_rom", NULL);
+	clk = davinci_clk_init(&tpcc0_clk);
+	clk_register_clkdev(clk, "tpcc0", NULL);
+	clk = davinci_clk_init(&tptc0_clk);
+	clk_register_clkdev(clk, "tptc0", NULL);
+	clk = davinci_clk_init(&tptc1_clk);
+	clk_register_clkdev(clk, "tptc1", NULL);
+	clk = davinci_clk_init(&tpcc1_clk);
+	clk_register_clkdev(clk, "tpcc1", NULL);
+	clk = davinci_clk_init(&tptc2_clk);
+	clk_register_clkdev(clk, "tptc2", NULL);
+	clk = davinci_clk_init(&pruss_clk);
+	clk_register_clkdev(clk, "pruss", "pruss_uio");
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&aintc_clk);
+	clk_register_clkdev(clk, "aintc", NULL);
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&i2c1_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.2");
+	clk = davinci_clk_init(&emif3_clk);
+	clk_register_clkdev(clk, "emif3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&rmii_clk);
+	clk_register_clkdev(clk, "rmii", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&mdio_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&mcasp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcbsp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
+	clk = davinci_clk_init(&mcbsp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
+	clk = davinci_clk_init(&lcdc_clk);
+	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.1");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, NULL, "ti-aemif");
+	clk = davinci_clk_init(&aemif_nand_clk);
+	clk_register_clkdev(clk, "aemif", "davinci-nand.0");
+	clk = davinci_clk_init(&usb11_clk);
+	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
+	clk = davinci_clk_init(&usb20_clk);
+	clk_register_clkdev(clk, "usb20", "musb-da8xx");
+	clk = davinci_clk_init(&cppi41_clk);
+	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&vpif_clk);
+	clk_register_clkdev(clk, NULL, "vpif");
+	clk = davinci_clk_init(&sata_clk);
+	clk_register_clkdev(clk, "fck", "ahci_da850");
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-rproc.0");
+	clk = davinci_clk_init(&ehrpwm_clk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ehrpwm0_clk);
+	clk_register_clkdev(clk, "fck", "ehrpwm.0");
+	clk = davinci_clk_init(&ehrpwm1_clk);
+	clk_register_clkdev(clk, "fck", "ehrpwm.1");
+	clk = davinci_clk_init(&ehrpwm_tbclk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ehrpwm0_tbclk);
+	clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
+	clk = davinci_clk_init(&ehrpwm1_tbclk);
+	clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
+	clk = davinci_clk_init(&ecap_clk);
+	clk_register_clkdev(clk, NULL, NULL);
+	clk = davinci_clk_init(&ecap0_clk);
+	clk_register_clkdev(clk, "fck", "ecap.0");
+	clk = davinci_clk_init(&ecap1_clk);
+	clk_register_clkdev(clk, "fck", "ecap.1");
+	clk = davinci_clk_init(&ecap2_clk);
+	clk_register_clkdev(clk, "fck", "ecap.2");
+}
 
 /*
  * Device specific mux setup
@@ -1353,7 +1417,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),
-	.cpu_clks		= da850_clks,
 	.psc_bases		= da850_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
 	.pinmux_base		= DA8XX_SYSCFG0_BASE + 0x120,
@@ -1396,6 +1459,6 @@ void __init da850_init(void)
 
 void __init da850_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+	da850_clk_init();
 	davinci_timer_init();
 }
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index fe5e15a..c9a79b2 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -1046,9 +1046,6 @@ static struct clk sata_refclk = {
 	.set_rate	= davinci_simple_set_rate,
 };
 
-static struct clk_lookup sata_refclk_lookup =
-		CLK("ahci_da850", "refclk", &sata_refclk);
-
 int __init da850_register_sata_refclk(int rate)
 {
 	int ret;
@@ -1058,7 +1055,7 @@ int __init da850_register_sata_refclk(int rate)
 	if (ret)
 		return ret;
 
-	clkdev_add(&sata_refclk_lookup);
+	clk_register_clkdev(&sata_refclk, "refclk", "ahci_da850");
 
 	return 0;
 }
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 40641c0..9e5cfa9 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -337,51 +337,95 @@ static struct clk usb_clk = {
 	.lpsc = DAVINCI_LPSC_USB,
 };
 
-static struct clk_lookup dm355_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "vpss_dac", &vpss_dac_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "clkout1", &clkout1_clk),
-	CLK(NULL, "clkout2", &clkout2_clk),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-	CLK(NULL, "clkout3", &clkout3_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "mjcp", &mjcp_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("davinci-mcbsp.0", NULL, &asp0_clk),
-	CLK("davinci-mcbsp.1", NULL, &asp1_clk),
-	CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
-	CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
-	CLK("spi_davinci.0", NULL, &spi0_clk),
-	CLK("spi_davinci.1", NULL, &spi1_clk),
-	CLK("spi_davinci.2", NULL, &spi2_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "pwm3", &pwm3_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, "timer3", &timer3_clk),
-	CLK(NULL, "rto", &rto_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm355_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk4", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&vpss_dac_clk);
+	clk_register_clkdev(clk, "vpss_dac", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&clkout1_clk);
+	clk_register_clkdev(clk, "clkout1", NULL);
+	clk = davinci_clk_init(&clkout2_clk);
+	clk_register_clkdev(clk, "clkout2", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclkbp);
+	clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
+	clk = davinci_clk_init(&clkout3_clk);
+	clk_register_clkdev(clk, "clkout3", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&mjcp_clk);
+	clk_register_clkdev(clk, "mjcp", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&asp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.0");
+	clk = davinci_clk_init(&asp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp.1");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.1");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&spi2_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.2");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&pwm3_clk);
+	clk_register_clkdev(clk, "pwm3", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&timer3_clk);
+	clk_register_clkdev(clk, "timer3", NULL);
+	clk = davinci_clk_init(&rto_clk);
+	clk_register_clkdev(clk, "rto", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+}
 
 /*----------------------------------------------------------------------*/
 
@@ -1012,7 +1056,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm355_ids,
 	.ids_num		= ARRAY_SIZE(dm355_ids),
-	.cpu_clks		= dm355_clks,
 	.psc_bases		= dm355_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm355_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1047,7 +1090,7 @@ void __init dm355_init(void)
 
 void __init dm355_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+	dm355_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 0789ac6..0cf4ab4 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -425,66 +425,125 @@ static struct clk mjcp_clk = {
 	.lpsc		= DM365_LPSC_MJCP,
 };
 
-static struct clk_lookup dm365_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "clkout0", &clkout0_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-	CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
-	CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
-	CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
-	CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_aux", &pll2_aux_clk),
-	CLK(NULL, "clkout1", &clkout1_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-	CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
-	CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
-	CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
-	CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
-	CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
-	CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
-	CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
-	CLK(NULL, "vpss_dac", &vpss_dac_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("da830-mmc.0", NULL, &mmcsd0_clk),
-	CLK("da830-mmc.1", NULL, &mmcsd1_clk),
-	CLK("spi_davinci.0", NULL, &spi0_clk),
-	CLK("spi_davinci.1", NULL, &spi1_clk),
-	CLK("spi_davinci.2", NULL, &spi2_clk),
-	CLK("spi_davinci.3", NULL, &spi3_clk),
-	CLK("spi_davinci.4", NULL, &spi4_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "pwm3", &pwm3_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, "timer3", &timer3_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK("davinci_voicecodec", NULL, &voicecodec_clk),
-	CLK("davinci-mcbsp", NULL, &asp0_clk),
-	CLK(NULL, "rto", &rto_clk),
-	CLK(NULL, "mjcp", &mjcp_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm365_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&clkout0_clk);
+	clk_register_clkdev(clk, "clkout0", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk4", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk5", NULL);
+	clk = davinci_clk_init(&pll1_sysclk6);
+	clk_register_clkdev(clk, "pll1_sysclk6", NULL);
+	clk = davinci_clk_init(&pll1_sysclk7);
+	clk_register_clkdev(clk, "pll1_sysclk7", NULL);
+	clk = davinci_clk_init(&pll1_sysclk8);
+	clk_register_clkdev(clk, "pll1_sysclk8", NULL);
+	clk = davinci_clk_init(&pll1_sysclk9);
+	clk_register_clkdev(clk, "pll1_sysclk9", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_aux_clk);
+	clk_register_clkdev(clk, "pll2_aux", NULL);
+	clk = davinci_clk_init(&clkout1_clk);
+	clk_register_clkdev(clk, "clkout1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk2);
+	clk_register_clkdev(clk, "pll2_sysclk2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk3);
+	clk_register_clkdev(clk, "pll2_sysclk3", NULL);
+	clk = davinci_clk_init(&pll2_sysclk4);
+	clk_register_clkdev(clk, "pll2_sysclk4", NULL);
+	clk = davinci_clk_init(&pll2_sysclk5);
+	clk_register_clkdev(clk, "pll2_sysclk5", NULL);
+	clk = davinci_clk_init(&pll2_sysclk6);
+	clk_register_clkdev(clk, "pll2_sysclk6", NULL);
+	clk = davinci_clk_init(&pll2_sysclk7);
+	clk_register_clkdev(clk, "pll2_sysclk7", NULL);
+	clk = davinci_clk_init(&pll2_sysclk8);
+	clk_register_clkdev(clk, "pll2_sysclk8", NULL);
+	clk = davinci_clk_init(&pll2_sysclk9);
+	clk_register_clkdev(clk, "pll2_sysclk9", NULL);
+	clk = davinci_clk_init(&vpss_dac_clk);
+	clk_register_clkdev(clk, "vpss_dac", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&mmcsd0_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.0");
+	clk = davinci_clk_init(&mmcsd1_clk);
+	clk_register_clkdev(clk, NULL, "da830-mmc.1");
+	clk = davinci_clk_init(&spi0_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.0");
+	clk = davinci_clk_init(&spi1_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.1");
+	clk = davinci_clk_init(&spi2_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.2");
+	clk = davinci_clk_init(&spi3_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.3");
+	clk = davinci_clk_init(&spi4_clk);
+	clk_register_clkdev(clk, NULL, "spi_davinci.4");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&pwm3_clk);
+	clk_register_clkdev(clk, "pwm3", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&timer3_clk);
+	clk_register_clkdev(clk, "timer3", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&voicecodec_clk);
+	clk_register_clkdev(clk, NULL, "davinci_voicecodec");
+	clk = davinci_clk_init(&asp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp");
+	clk = davinci_clk_init(&rto_clk);
+	clk_register_clkdev(clk, "rto", NULL);
+	clk = davinci_clk_init(&mjcp_clk);
+	clk_register_clkdev(clk, "mjcp", NULL);
+}
 
 /*----------------------------------------------------------------------*/
 
@@ -1116,7 +1175,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm365_ids,
 	.ids_num		= ARRAY_SIZE(dm365_ids),
-	.cpu_clks		= dm365_clks,
 	.psc_bases		= dm365_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm365_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -1172,7 +1230,7 @@ void __init dm365_init(void)
 
 void __init dm365_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+	dm365_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index a1a2433..769ce29 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -285,47 +285,87 @@ static struct clk timer2_clk = {
 	.usecount = 1,              /* REVISIT: why can't this be disabled? */
 };
 
-static struct clk_lookup dm644x_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-	CLK(NULL, "dsp", &dsp_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "vicp", &vicp_clk),
-	CLK("vpss", "master", &vpss_master_clk),
-	CLK("vpss", "slave", &vpss_slave_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK("davinci-mcbsp", NULL, &asp_clk),
-	CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
-	CLK(NULL, "spi", &spi_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK(NULL, "usb", &usb_clk),
-	CLK(NULL, "vlynq", &vlynq_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "pwm2", &pwm2_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm644x_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk2", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk3", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk5", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclkbp", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&pll2_sysclk2);
+	clk_register_clkdev(clk, "pll2_sysclk2", NULL);
+	clk = davinci_clk_init(&pll2_sysclkbp);
+	clk_register_clkdev(clk, "pll2_sysclkbp", NULL);
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, "dsp", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&vicp_clk);
+	clk_register_clkdev(clk, "vicp", NULL);
+	clk = davinci_clk_init(&vpss_master_clk);
+	clk_register_clkdev(clk, "master", "vpss");
+	clk = davinci_clk_init(&vpss_slave_clk);
+	clk_register_clkdev(clk, "slave", "vpss");
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&ide_clk);
+	clk_register_clkdev(clk, NULL, "palm_bk3710");
+	clk = davinci_clk_init(&asp_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcbsp");
+	clk = davinci_clk_init(&mmcsd_clk);
+	clk_register_clkdev(clk, NULL, "dm6441-mmc.0");
+	clk = davinci_clk_init(&spi_clk);
+	clk_register_clkdev(clk, "spi", NULL);
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&usb_clk);
+	clk_register_clkdev(clk, "usb", NULL);
+	clk = davinci_clk_init(&vlynq_clk);
+	clk_register_clkdev(clk, "vlynq", NULL);
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&pwm2_clk);
+	clk_register_clkdev(clk, "pwm2", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+}
 
 static struct emac_platform_data dm644x_emac_pdata = {
 	.ctrl_reg_offset	= DM644X_EMAC_CNTRL_OFFSET,
@@ -905,7 +945,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm644x_ids,
 	.ids_num		= ARRAY_SIZE(dm644x_ids),
-	.cpu_clks		= dm644x_clks,
 	.psc_bases		= dm644x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm644x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -935,7 +974,7 @@ void __init dm644x_init(void)
 
 void __init dm644x_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+	dm644x_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index c518403..d75b4bc09 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -320,49 +320,91 @@ static struct clk vpif1_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
-static struct clk_lookup dm646x_clks[] = {
-	CLK(NULL, "ref", &ref_clk),
-	CLK(NULL, "aux", &aux_clkin),
-	CLK(NULL, "pll1", &pll1_clk),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
-	CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
-	CLK(NULL, "pll1_aux", &pll1_aux_clk),
-	CLK(NULL, "pll2", &pll2_clk),
-	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-	CLK(NULL, "dsp", &dsp_clk),
-	CLK(NULL, "arm", &arm_clk),
-	CLK(NULL, "edma_cc", &edma_cc_clk),
-	CLK(NULL, "edma_tc0", &edma_tc0_clk),
-	CLK(NULL, "edma_tc1", &edma_tc1_clk),
-	CLK(NULL, "edma_tc2", &edma_tc2_clk),
-	CLK(NULL, "edma_tc3", &edma_tc3_clk),
-	CLK("serial8250.0", NULL, &uart0_clk),
-	CLK("serial8250.1", NULL, &uart1_clk),
-	CLK("serial8250.2", NULL, &uart2_clk),
-	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK(NULL, "gpio", &gpio_clk),
-	CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
-	CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
-	CLK(NULL, "aemif", &aemif_clk),
-	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("davinci_mdio.0", "fck", &emac_clk),
-	CLK(NULL, "pwm0", &pwm0_clk),
-	CLK(NULL, "pwm1", &pwm1_clk),
-	CLK(NULL, "timer0", &timer0_clk),
-	CLK(NULL, "timer1", &timer1_clk),
-	CLK("davinci-wdt", NULL, &timer2_clk),
-	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK(NULL, "vpif0", &vpif0_clk),
-	CLK(NULL, "vpif1", &vpif1_clk),
-	CLK(NULL, NULL, NULL),
-};
+static __init void dm646x_clk_init(void)
+{
+	struct clk *clk;
+
+	clk = davinci_clk_init(&ref_clk);
+	clk_register_clkdev(clk, "ref", NULL);
+	clk = davinci_clk_init(&aux_clkin);
+	clk_register_clkdev(clk, "aux", NULL);
+	clk = davinci_clk_init(&pll1_clk);
+	clk_register_clkdev(clk, "pll1", NULL);
+	clk = davinci_clk_init(&pll1_sysclk1);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk2);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk3);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk4);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk5);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk6);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk8);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclk9);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_sysclkbp);
+	clk_register_clkdev(clk, "pll1_sysclk", NULL);
+	clk = davinci_clk_init(&pll1_aux_clk);
+	clk_register_clkdev(clk, "pll1_aux", NULL);
+	clk = davinci_clk_init(&pll2_clk);
+	clk_register_clkdev(clk, "pll2", NULL);
+	clk = davinci_clk_init(&pll2_sysclk1);
+	clk_register_clkdev(clk, "pll2_sysclk1", NULL);
+	clk = davinci_clk_init(&dsp_clk);
+	clk_register_clkdev(clk, "dsp", NULL);
+	clk = davinci_clk_init(&arm_clk);
+	clk_register_clkdev(clk, "arm", NULL);
+	clk = davinci_clk_init(&edma_cc_clk);
+	clk_register_clkdev(clk, "edma_cc", NULL);
+	clk = davinci_clk_init(&edma_tc0_clk);
+	clk_register_clkdev(clk, "edma_tc0", NULL);
+	clk = davinci_clk_init(&edma_tc1_clk);
+	clk_register_clkdev(clk, "edma_tc1", NULL);
+	clk = davinci_clk_init(&edma_tc2_clk);
+	clk_register_clkdev(clk, "edma_tc2", NULL);
+	clk = davinci_clk_init(&edma_tc3_clk);
+	clk_register_clkdev(clk, "edma_tc3", NULL);
+	clk = davinci_clk_init(&uart0_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.0");
+	clk = davinci_clk_init(&uart1_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.1");
+	clk = davinci_clk_init(&uart2_clk);
+	clk_register_clkdev(clk, NULL, "serial8250.2");
+	clk = davinci_clk_init(&i2c_clk);
+	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+	clk = davinci_clk_init(&gpio_clk);
+	clk_register_clkdev(clk, "gpio", NULL);
+	clk = davinci_clk_init(&mcasp0_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
+	clk = davinci_clk_init(&mcasp1_clk);
+	clk_register_clkdev(clk, NULL, "davinci-mcasp.1");
+	clk = davinci_clk_init(&aemif_clk);
+	clk_register_clkdev(clk, "aemif", NULL);
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, NULL, "davinci_emac.1");
+	clk = davinci_clk_init(&emac_clk);
+	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
+	clk = davinci_clk_init(&pwm0_clk);
+	clk_register_clkdev(clk, "pwm0", NULL);
+	clk = davinci_clk_init(&pwm1_clk);
+	clk_register_clkdev(clk, "pwm1", NULL);
+	clk = davinci_clk_init(&timer0_clk);
+	clk_register_clkdev(clk, "timer0", NULL);
+	clk = davinci_clk_init(&timer1_clk);
+	clk_register_clkdev(clk, "timer1", NULL);
+	clk = davinci_clk_init(&timer2_clk);
+	clk_register_clkdev(clk, NULL, "davinci-wdt");
+	clk = davinci_clk_init(&ide_clk);
+	clk_register_clkdev(clk, NULL, "palm_bk3710");
+	clk = davinci_clk_init(&vpif0_clk);
+	clk_register_clkdev(clk, "vpif0", NULL);
+	clk = davinci_clk_init(&vpif1_clk);
+	clk_register_clkdev(clk, "vpif1", NULL);
+}
 
 static struct emac_platform_data dm646x_emac_pdata = {
 	.ctrl_reg_offset	= DM646X_EMAC_CNTRL_OFFSET,
@@ -888,7 +930,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
 	.jtag_id_reg		= 0x01c40028,
 	.ids			= dm646x_ids,
 	.ids_num		= ARRAY_SIZE(dm646x_ids),
-	.cpu_clks		= dm646x_clks,
 	.psc_bases		= dm646x_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm646x_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -960,7 +1001,7 @@ void __init dm646x_init(void)
 
 void __init dm646x_init_time(void)
 {
-	davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+	dm646x_clk_init();
 	davinci_timer_init();
 }
 
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 19b9346..f0d5e858 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,7 +53,6 @@ struct davinci_soc_info {
 	u32				jtag_id_reg;
 	struct davinci_id		*ids;
 	unsigned long			ids_num;
-	struct clk_lookup		*cpu_clks;
 	u32				*psc_bases;
 	unsigned long			psc_bases_num;
 	u32				pinmux_base;
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index d480a02..a2e575e 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -133,9 +133,6 @@ static struct clk usb_refclkin = {
 	.set_rate	= davinci_simple_set_rate,
 };
 
-static struct clk_lookup usb_refclkin_lookup =
-	CLK(NULL, "usb_refclkin", &usb_refclkin);
-
 /**
  * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
  *
@@ -154,7 +151,7 @@ int __init da8xx_register_usb_refclkin(int rate)
 	if (ret)
 		return ret;
 
-	clkdev_add(&usb_refclkin_lookup);
+	clk_register_clkdev(&usb_refclkin, "usb_refclkin", NULL);
 
 	return 0;
 }
@@ -262,9 +259,6 @@ static struct clk usb20_phy_clk = {
 	.set_parent	= usb20_phy_clk_set_parent,
 };
 
-static struct clk_lookup usb20_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
-
 /**
  * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
  *
@@ -291,7 +285,7 @@ int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
 	usb20_phy_clk.parent = parent;
 	ret = clk_register(&usb20_phy_clk);
 	if (!ret)
-		clkdev_add(&usb20_phy_clk_lookup);
+		clk_register_clkdev(&usb20_phy_clk, "usb20_phy", "da8xx-usb-phy");
 
 	clk_put(parent);
 
@@ -324,9 +318,6 @@ static struct clk usb11_phy_clk = {
 	.set_parent	= usb11_phy_clk_set_parent,
 };
 
-static struct clk_lookup usb11_phy_clk_lookup =
-	CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
-
 /**
  * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
  *
@@ -348,7 +339,7 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
 	usb11_phy_clk.parent = parent;
 	ret = clk_register(&usb11_phy_clk);
 	if (!ret)
-		clkdev_add(&usb11_phy_clk_lookup);
+		clk_register_clkdev(&usb11_phy_clk, "usb11_phy", "da8xx-usb-phy");
 
 	clk_put(parent);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

There are a number of clocks that were duplicated because they are used by
more than one device. It is no longer necessary to do this since we are
explicitly calling clk_register_clkdev() for each clock. In da830.c, some
clocks were using the same LPSC, which would cause problems with reference
counting, so these are combinded into one clock each. In da850.c the
duplicate clocks had already been fixed by creating dummy child clocks, so
these clocks are removed.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/da830.c  | 65 ++++++--------------------------------
 arch/arm/mach-davinci/da850.c  | 72 ------------------------------------------
 arch/arm/mach-davinci/dm365.c  |  1 -
 arch/arm/mach-davinci/dm644x.c |  3 --
 arch/arm/mach-davinci/dm646x.c |  1 -
 5 files changed, 9 insertions(+), 133 deletions(-)

diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 73c48f5..b0e54a1 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -213,57 +213,22 @@ static struct clk spi1_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ecap0_clk = {
-	.name		= "ecap0",
+static struct clk ecap_clk = {
+	.name		= "ecap",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
 	.gpsc		= 1,
 };
 
-static struct clk ecap1_clk = {
-	.name		= "ecap1",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_ECAP,
-	.gpsc		= 1,
-};
-
-static struct clk ecap2_clk = {
-	.name		= "ecap2",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_ECAP,
-	.gpsc		= 1,
-};
-
-static struct clk pwm0_clk = {
-	.name		= "pwm0",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_PWM,
-	.gpsc		= 1,
-};
-
-static struct clk pwm1_clk = {
-	.name		= "pwm1",
+static struct clk pwm_clk = {
+	.name		= "pwm",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
 	.gpsc		= 1,
 };
 
-static struct clk pwm2_clk = {
-	.name		= "pwm2",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_PWM,
-	.gpsc		= 1,
-};
-
-static struct clk eqep0_clk = {
-	.name		= "eqep0",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA830_LPSC1_EQEP,
-	.gpsc		= 1,
-};
-
-static struct clk eqep1_clk = {
-	.name		= "eqep1",
+static struct clk eqep_clk = {
+	.name		= "eqep",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
 	.gpsc		= 1,
@@ -304,11 +269,6 @@ static struct clk usb20_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk cppi41_clk = {
-	.name		= "cppi41",
-	.parent		= &usb20_clk,
-};
-
 static struct clk aemif_clk = {
 	.name		= "aemif",
 	.parent		= &pll0_sysclk3,
@@ -434,21 +394,16 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, NULL, "spi_davinci.0");
 	clk = davinci_clk_init(&spi1_clk);
 	clk_register_clkdev(clk, NULL, "spi_davinci.1");
-	clk = davinci_clk_init(&ecap0_clk);
+	clk = davinci_clk_init(&ecap_clk);
 	clk_register_clkdev(clk, "ecap0", NULL);
-	clk = davinci_clk_init(&ecap1_clk);
 	clk_register_clkdev(clk, "ecap1", NULL);
-	clk = davinci_clk_init(&ecap2_clk);
 	clk_register_clkdev(clk, "ecap2", NULL);
-	clk = davinci_clk_init(&pwm0_clk);
+	clk = davinci_clk_init(&pwm_clk);
 	clk_register_clkdev(clk, "pwm0", NULL);
-	clk = davinci_clk_init(&pwm1_clk);
 	clk_register_clkdev(clk, "pwm1", NULL);
-	clk = davinci_clk_init(&pwm2_clk);
 	clk_register_clkdev(clk, "pwm2", NULL);
-	clk = davinci_clk_init(&eqep0_clk);
+	clk = davinci_clk_init(&eqep_clk);
 	clk_register_clkdev(clk, NULL, "eqep.0");
-	clk = davinci_clk_init(&eqep1_clk);
 	clk_register_clkdev(clk, NULL, "eqep.1");
 	clk = davinci_clk_init(&lcdc_clk);
 	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
@@ -460,7 +415,6 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, NULL, "davinci-mcasp.2");
 	clk = davinci_clk_init(&usb20_clk);
 	clk_register_clkdev(clk, "usb20", "musb-da8xx");
-	clk = davinci_clk_init(&cppi41_clk);
 	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
 	clk = davinci_clk_init(&aemif_clk);
 	clk_register_clkdev(clk, "aemif", NULL);
@@ -470,7 +424,6 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, "secu_mgr", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&gpio_clk);
 	clk_register_clkdev(clk, "gpio", NULL);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index eaa05ac..0975edb 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -319,16 +319,6 @@ static struct clk emac_clk = {
 	.gpsc		= 1,
 };
 
-/*
- * In order to avoid adding the emac_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * mdio inheriting the rate from emac_clk.
- */
-static struct clk mdio_clk = {
-	.name		= "mdio",
-	.parent		= &emac_clk,
-};
-
 static struct clk mcasp_clk = {
 	.name		= "mcasp",
 	.parent		= &async3_clk,
@@ -377,16 +367,6 @@ static struct clk aemif_clk = {
 	.flags		= ALWAYS_ENABLED,
 };
 
-/*
- * In order to avoid adding the aemif_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * nand inheriting the rate from aemif_clk.
- */
-static struct clk aemif_nand_clk = {
-	.name		= "nand",
-	.parent		= &aemif_clk,
-};
-
 static struct clk usb11_clk = {
 	.name		= "usb11",
 	.parent		= &pll0_sysclk4,
@@ -401,11 +381,6 @@ static struct clk usb20_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk cppi41_clk = {
-	.name		= "cppi41",
-	.parent		= &usb20_clk,
-};
-
 static struct clk spi0_clk = {
 	.name		= "spi0",
 	.parent		= &pll0_sysclk2,
@@ -449,16 +424,6 @@ static struct clk ehrpwm_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ehrpwm0_clk = {
-	.name		= "ehrpwm0",
-	.parent		= &ehrpwm_clk,
-};
-
-static struct clk ehrpwm1_clk = {
-	.name		= "ehrpwm1",
-	.parent		= &ehrpwm_clk,
-};
-
 #define DA8XX_EHRPWM_TBCLKSYNC	BIT(12)
 
 static void ehrpwm_tblck_enable(struct clk *clk)
@@ -486,15 +451,6 @@ static struct clk ehrpwm_tbclk = {
 	.clk_disable	= ehrpwm_tblck_disable,
 };
 
-static struct clk ehrpwm0_tbclk = {
-	.name		= "ehrpwm0_tbclk",
-	.parent		= &ehrpwm_tbclk,
-};
-
-static struct clk ehrpwm1_tbclk = {
-	.name		= "ehrpwm1_tbclk",
-	.parent		= &ehrpwm_tbclk,
-};
 
 static struct clk ecap_clk = {
 	.name		= "ecap",
@@ -503,21 +459,6 @@ static struct clk ecap_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ecap0_clk = {
-	.name		= "ecap0_clk",
-	.parent		= &ecap_clk,
-};
-
-static struct clk ecap1_clk = {
-	.name		= "ecap1_clk",
-	.parent		= &ecap_clk,
-};
-
-static struct clk ecap2_clk = {
-	.name		= "ecap2_clk",
-	.parent		= &ecap_clk,
-};
-
 static __init void da850_clk_init(void)
 {
 	struct clk *clk;
@@ -592,7 +533,6 @@ static __init void da850_clk_init(void)
 	clk_register_clkdev(clk, "rmii", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&mdio_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&mcasp_clk);
 	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
@@ -608,13 +548,11 @@ static __init void da850_clk_init(void)
 	clk_register_clkdev(clk, NULL, "da830-mmc.1");
 	clk = davinci_clk_init(&aemif_clk);
 	clk_register_clkdev(clk, NULL, "ti-aemif");
-	clk = davinci_clk_init(&aemif_nand_clk);
 	clk_register_clkdev(clk, "aemif", "davinci-nand.0");
 	clk = davinci_clk_init(&usb11_clk);
 	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
 	clk = davinci_clk_init(&usb20_clk);
 	clk_register_clkdev(clk, "usb20", "musb-da8xx");
-	clk = davinci_clk_init(&cppi41_clk);
 	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
 	clk = davinci_clk_init(&spi0_clk);
 	clk_register_clkdev(clk, NULL, "spi_davinci.0");
@@ -627,24 +565,14 @@ static __init void da850_clk_init(void)
 	clk = davinci_clk_init(&dsp_clk);
 	clk_register_clkdev(clk, NULL, "davinci-rproc.0");
 	clk = davinci_clk_init(&ehrpwm_clk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ehrpwm0_clk);
 	clk_register_clkdev(clk, "fck", "ehrpwm.0");
-	clk = davinci_clk_init(&ehrpwm1_clk);
 	clk_register_clkdev(clk, "fck", "ehrpwm.1");
 	clk = davinci_clk_init(&ehrpwm_tbclk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ehrpwm0_tbclk);
 	clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
-	clk = davinci_clk_init(&ehrpwm1_tbclk);
 	clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
 	clk = davinci_clk_init(&ecap_clk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ecap0_clk);
 	clk_register_clkdev(clk, "fck", "ecap.0");
-	clk = davinci_clk_init(&ecap1_clk);
 	clk_register_clkdev(clk, "fck", "ecap.1");
-	clk = davinci_clk_init(&ecap2_clk);
 	clk_register_clkdev(clk, "fck", "ecap.2");
 }
 
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 0cf4ab4..430fb1e 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -533,7 +533,6 @@ static __init void dm365_clk_init(void)
 	clk_register_clkdev(clk, "usb", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&voicecodec_clk);
 	clk_register_clkdev(clk, NULL, "davinci_voicecodec");
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 769ce29..58120f4 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -323,8 +323,6 @@ static __init void dm644x_clk_init(void)
 	clk_register_clkdev(clk, "master", "vpss");
 	clk = davinci_clk_init(&vpss_slave_clk);
 	clk_register_clkdev(clk, "slave", "vpss");
-	clk = davinci_clk_init(&arm_clk);
-	clk_register_clkdev(clk, "arm", NULL);
 	clk = davinci_clk_init(&uart0_clk);
 	clk_register_clkdev(clk, NULL, "serial8250.0");
 	clk = davinci_clk_init(&uart1_clk);
@@ -333,7 +331,6 @@ static __init void dm644x_clk_init(void)
 	clk_register_clkdev(clk, NULL, "serial8250.2");
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&i2c_clk);
 	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index d75b4bc09..0cd5d51 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -386,7 +386,6 @@ static __init void dm646x_clk_init(void)
 	clk_register_clkdev(clk, "aemif", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&pwm0_clk);
 	clk_register_clkdev(clk, "pwm0", NULL);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

There are a number of clocks that were duplicated because they are used by
more than one device. It is no longer necessary to do this since we are
explicitly calling clk_register_clkdev() for each clock. In da830.c, some
clocks were using the same LPSC, which would cause problems with reference
counting, so these are combinded into one clock each. In da850.c the
duplicate clocks had already been fixed by creating dummy child clocks, so
these clocks are removed.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/da830.c  | 65 ++++++--------------------------------
 arch/arm/mach-davinci/da850.c  | 72 ------------------------------------------
 arch/arm/mach-davinci/dm365.c  |  1 -
 arch/arm/mach-davinci/dm644x.c |  3 --
 arch/arm/mach-davinci/dm646x.c |  1 -
 5 files changed, 9 insertions(+), 133 deletions(-)

diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 73c48f5..b0e54a1 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -213,57 +213,22 @@ static struct clk spi1_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ecap0_clk = {
-	.name		= "ecap0",
+static struct clk ecap_clk = {
+	.name		= "ecap",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
 	.gpsc		= 1,
 };
 
-static struct clk ecap1_clk = {
-	.name		= "ecap1",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_ECAP,
-	.gpsc		= 1,
-};
-
-static struct clk ecap2_clk = {
-	.name		= "ecap2",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_ECAP,
-	.gpsc		= 1,
-};
-
-static struct clk pwm0_clk = {
-	.name		= "pwm0",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_PWM,
-	.gpsc		= 1,
-};
-
-static struct clk pwm1_clk = {
-	.name		= "pwm1",
+static struct clk pwm_clk = {
+	.name		= "pwm",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
 	.gpsc		= 1,
 };
 
-static struct clk pwm2_clk = {
-	.name		= "pwm2",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA8XX_LPSC1_PWM,
-	.gpsc		= 1,
-};
-
-static struct clk eqep0_clk = {
-	.name		= "eqep0",
-	.parent		= &pll0_sysclk2,
-	.lpsc		= DA830_LPSC1_EQEP,
-	.gpsc		= 1,
-};
-
-static struct clk eqep1_clk = {
-	.name		= "eqep1",
+static struct clk eqep_clk = {
+	.name		= "eqep",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
 	.gpsc		= 1,
@@ -304,11 +269,6 @@ static struct clk usb20_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk cppi41_clk = {
-	.name		= "cppi41",
-	.parent		= &usb20_clk,
-};
-
 static struct clk aemif_clk = {
 	.name		= "aemif",
 	.parent		= &pll0_sysclk3,
@@ -434,21 +394,16 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, NULL, "spi_davinci.0");
 	clk = davinci_clk_init(&spi1_clk);
 	clk_register_clkdev(clk, NULL, "spi_davinci.1");
-	clk = davinci_clk_init(&ecap0_clk);
+	clk = davinci_clk_init(&ecap_clk);
 	clk_register_clkdev(clk, "ecap0", NULL);
-	clk = davinci_clk_init(&ecap1_clk);
 	clk_register_clkdev(clk, "ecap1", NULL);
-	clk = davinci_clk_init(&ecap2_clk);
 	clk_register_clkdev(clk, "ecap2", NULL);
-	clk = davinci_clk_init(&pwm0_clk);
+	clk = davinci_clk_init(&pwm_clk);
 	clk_register_clkdev(clk, "pwm0", NULL);
-	clk = davinci_clk_init(&pwm1_clk);
 	clk_register_clkdev(clk, "pwm1", NULL);
-	clk = davinci_clk_init(&pwm2_clk);
 	clk_register_clkdev(clk, "pwm2", NULL);
-	clk = davinci_clk_init(&eqep0_clk);
+	clk = davinci_clk_init(&eqep_clk);
 	clk_register_clkdev(clk, NULL, "eqep.0");
-	clk = davinci_clk_init(&eqep1_clk);
 	clk_register_clkdev(clk, NULL, "eqep.1");
 	clk = davinci_clk_init(&lcdc_clk);
 	clk_register_clkdev(clk, "fck", "da8xx_lcdc.0");
@@ -460,7 +415,6 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, NULL, "davinci-mcasp.2");
 	clk = davinci_clk_init(&usb20_clk);
 	clk_register_clkdev(clk, "usb20", "musb-da8xx");
-	clk = davinci_clk_init(&cppi41_clk);
 	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
 	clk = davinci_clk_init(&aemif_clk);
 	clk_register_clkdev(clk, "aemif", NULL);
@@ -470,7 +424,6 @@ static __init void da830_clk_init(void)
 	clk_register_clkdev(clk, "secu_mgr", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&gpio_clk);
 	clk_register_clkdev(clk, "gpio", NULL);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index eaa05ac..0975edb 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -319,16 +319,6 @@ static struct clk emac_clk = {
 	.gpsc		= 1,
 };
 
-/*
- * In order to avoid adding the emac_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * mdio inheriting the rate from emac_clk.
- */
-static struct clk mdio_clk = {
-	.name		= "mdio",
-	.parent		= &emac_clk,
-};
-
 static struct clk mcasp_clk = {
 	.name		= "mcasp",
 	.parent		= &async3_clk,
@@ -377,16 +367,6 @@ static struct clk aemif_clk = {
 	.flags		= ALWAYS_ENABLED,
 };
 
-/*
- * In order to avoid adding the aemif_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * nand inheriting the rate from aemif_clk.
- */
-static struct clk aemif_nand_clk = {
-	.name		= "nand",
-	.parent		= &aemif_clk,
-};
-
 static struct clk usb11_clk = {
 	.name		= "usb11",
 	.parent		= &pll0_sysclk4,
@@ -401,11 +381,6 @@ static struct clk usb20_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk cppi41_clk = {
-	.name		= "cppi41",
-	.parent		= &usb20_clk,
-};
-
 static struct clk spi0_clk = {
 	.name		= "spi0",
 	.parent		= &pll0_sysclk2,
@@ -449,16 +424,6 @@ static struct clk ehrpwm_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ehrpwm0_clk = {
-	.name		= "ehrpwm0",
-	.parent		= &ehrpwm_clk,
-};
-
-static struct clk ehrpwm1_clk = {
-	.name		= "ehrpwm1",
-	.parent		= &ehrpwm_clk,
-};
-
 #define DA8XX_EHRPWM_TBCLKSYNC	BIT(12)
 
 static void ehrpwm_tblck_enable(struct clk *clk)
@@ -486,15 +451,6 @@ static struct clk ehrpwm_tbclk = {
 	.clk_disable	= ehrpwm_tblck_disable,
 };
 
-static struct clk ehrpwm0_tbclk = {
-	.name		= "ehrpwm0_tbclk",
-	.parent		= &ehrpwm_tbclk,
-};
-
-static struct clk ehrpwm1_tbclk = {
-	.name		= "ehrpwm1_tbclk",
-	.parent		= &ehrpwm_tbclk,
-};
 
 static struct clk ecap_clk = {
 	.name		= "ecap",
@@ -503,21 +459,6 @@ static struct clk ecap_clk = {
 	.gpsc		= 1,
 };
 
-static struct clk ecap0_clk = {
-	.name		= "ecap0_clk",
-	.parent		= &ecap_clk,
-};
-
-static struct clk ecap1_clk = {
-	.name		= "ecap1_clk",
-	.parent		= &ecap_clk,
-};
-
-static struct clk ecap2_clk = {
-	.name		= "ecap2_clk",
-	.parent		= &ecap_clk,
-};
-
 static __init void da850_clk_init(void)
 {
 	struct clk *clk;
@@ -592,7 +533,6 @@ static __init void da850_clk_init(void)
 	clk_register_clkdev(clk, "rmii", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&mdio_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&mcasp_clk);
 	clk_register_clkdev(clk, NULL, "davinci-mcasp.0");
@@ -608,13 +548,11 @@ static __init void da850_clk_init(void)
 	clk_register_clkdev(clk, NULL, "da830-mmc.1");
 	clk = davinci_clk_init(&aemif_clk);
 	clk_register_clkdev(clk, NULL, "ti-aemif");
-	clk = davinci_clk_init(&aemif_nand_clk);
 	clk_register_clkdev(clk, "aemif", "davinci-nand.0");
 	clk = davinci_clk_init(&usb11_clk);
 	clk_register_clkdev(clk, "usb11", "ohci-da8xx");
 	clk = davinci_clk_init(&usb20_clk);
 	clk_register_clkdev(clk, "usb20", "musb-da8xx");
-	clk = davinci_clk_init(&cppi41_clk);
 	clk_register_clkdev(clk, NULL, "cppi41-dmaengine");
 	clk = davinci_clk_init(&spi0_clk);
 	clk_register_clkdev(clk, NULL, "spi_davinci.0");
@@ -627,24 +565,14 @@ static __init void da850_clk_init(void)
 	clk = davinci_clk_init(&dsp_clk);
 	clk_register_clkdev(clk, NULL, "davinci-rproc.0");
 	clk = davinci_clk_init(&ehrpwm_clk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ehrpwm0_clk);
 	clk_register_clkdev(clk, "fck", "ehrpwm.0");
-	clk = davinci_clk_init(&ehrpwm1_clk);
 	clk_register_clkdev(clk, "fck", "ehrpwm.1");
 	clk = davinci_clk_init(&ehrpwm_tbclk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ehrpwm0_tbclk);
 	clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
-	clk = davinci_clk_init(&ehrpwm1_tbclk);
 	clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
 	clk = davinci_clk_init(&ecap_clk);
-	clk_register_clkdev(clk, NULL, NULL);
-	clk = davinci_clk_init(&ecap0_clk);
 	clk_register_clkdev(clk, "fck", "ecap.0");
-	clk = davinci_clk_init(&ecap1_clk);
 	clk_register_clkdev(clk, "fck", "ecap.1");
-	clk = davinci_clk_init(&ecap2_clk);
 	clk_register_clkdev(clk, "fck", "ecap.2");
 }
 
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 0cf4ab4..430fb1e 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -533,7 +533,6 @@ static __init void dm365_clk_init(void)
 	clk_register_clkdev(clk, "usb", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&voicecodec_clk);
 	clk_register_clkdev(clk, NULL, "davinci_voicecodec");
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 769ce29..58120f4 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -323,8 +323,6 @@ static __init void dm644x_clk_init(void)
 	clk_register_clkdev(clk, "master", "vpss");
 	clk = davinci_clk_init(&vpss_slave_clk);
 	clk_register_clkdev(clk, "slave", "vpss");
-	clk = davinci_clk_init(&arm_clk);
-	clk_register_clkdev(clk, "arm", NULL);
 	clk = davinci_clk_init(&uart0_clk);
 	clk_register_clkdev(clk, NULL, "serial8250.0");
 	clk = davinci_clk_init(&uart1_clk);
@@ -333,7 +331,6 @@ static __init void dm644x_clk_init(void)
 	clk_register_clkdev(clk, NULL, "serial8250.2");
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&i2c_clk);
 	clk_register_clkdev(clk, NULL, "i2c_davinci.1");
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index d75b4bc09..0cd5d51 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -386,7 +386,6 @@ static __init void dm646x_clk_init(void)
 	clk_register_clkdev(clk, "aemif", NULL);
 	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, NULL, "davinci_emac.1");
-	clk = davinci_clk_init(&emac_clk);
 	clk_register_clkdev(clk, "fck", "davinci_mdio.0");
 	clk = davinci_clk_init(&pwm0_clk);
 	clk_register_clkdev(clk, "pwm0", NULL);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 4/7] ARM: davinci: remove davinci_set_refclk_rate()
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

This removes the davinci_set_refclk_rate() function. This was used to set
the ref_clk rate after all clocks had been registered when clocks were
registered from a static table.

However, now it is possible to modify the rate before registering the
clocks in the first place by passing the rate as a function parameter.
The aux_clkin rate is also passed as a parameter since technically it is
also board-specific.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/board-dm646x-evm.c | 12 +++++++-----
 arch/arm/mach-davinci/clock.c            | 32 --------------------------------
 arch/arm/mach-davinci/clock.h            |  1 -
 arch/arm/mach-davinci/davinci.h          |  2 +-
 arch/arm/mach-davinci/dm646x.c           | 18 +++++++-----------
 5 files changed, 15 insertions(+), 50 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index dafc852..c8f517b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -716,17 +716,19 @@ static void __init evm_init_i2c(void)
 }
 #endif
 
-#define DM6467T_EVM_REF_FREQ		33000000
-
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
 }
 
+static void __init dm6467_evm_init_time(void)
+{
+	dm646x_init_time(27000000, 24000000);
+}
+
 static void __init dm6467t_evm_init_time(void)
 {
-	dm646x_init_time();
-	davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+	dm646x_init_time(33000000, 24000000);
 }
 
 #define DM646X_EVM_PHY_ID		"davinci_mdio-0:01"
@@ -800,7 +802,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= dm646x_init_time,
+	.init_time	= dm6467_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f82a90c..52b95e2 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -575,38 +575,6 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
 }
 EXPORT_SYMBOL(davinci_set_pllrate);
 
-/**
- * davinci_set_refclk_rate() - Set the reference clock rate
- * @rate:	The new rate.
- *
- * Sets the reference clock rate to a given value. This will most likely
- * result in the entire clock tree getting updated.
- *
- * This is used to support boards which use a reference clock different
- * than that used by default in <soc>.c file. The reference clock rate
- * should be updated early in the boot process; ideally soon after the
- * clock tree has been initialized once with the default reference clock
- * rate (davinci_clk_init()).
- *
- * Returns 0 on success, error otherwise.
- */
-int davinci_set_refclk_rate(unsigned long rate)
-{
-	struct clk *refclk;
-
-	refclk = clk_get(NULL, "ref");
-	if (IS_ERR(refclk)) {
-		pr_err("%s: failed to get reference clock\n", __func__);
-		return PTR_ERR(refclk);
-	}
-
-	clk_set_rate(refclk, rate);
-
-	clk_put(refclk);
-
-	return 0;
-}
-
 struct clk * __init davinci_clk_init(struct clk *clk)
 {
 	if (!clk->recalc) {
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 66c40a2..61fcdaa 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -122,7 +122,6 @@ 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_set_refclk_rate(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);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index d70f4d9..270cef8 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -111,7 +111,7 @@ int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
-void dm646x_init_time(void);
+void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 0cd5d51..31dbe93 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -39,12 +39,6 @@
 #define VSCLKDIS_MASK		(BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
 					BIT_MASK(8))
 
-/*
- * Device specific clocks
- */
-#define DM646X_REF_FREQ		27000000
-#define DM646X_AUX_FREQ		24000000
-
 #define DM646X_EMAC_BASE		0x01c80000
 #define DM646X_EMAC_MDIO_BASE		(DM646X_EMAC_BASE + 0x4000)
 #define DM646X_EMAC_CNTRL_OFFSET	0x0000
@@ -64,13 +58,11 @@ static struct pll_data pll2_data = {
 
 static struct clk ref_clk = {
 	.name = "ref_clk",
-	.rate = DM646X_REF_FREQ,
 	.set_rate = davinci_simple_set_rate,
 };
 
 static struct clk aux_clkin = {
 	.name = "aux_clkin",
-	.rate = DM646X_AUX_FREQ,
 };
 
 static struct clk pll1_clk = {
@@ -320,10 +312,13 @@ static struct clk vpif1_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
-static __init void dm646x_clk_init(void)
+static __init void dm646x_clk_init(unsigned long ref_clk_rate,
+				   unsigned long aux_clkin_rate)
 {
 	struct clk *clk;
 
+	ref_clk.rate = ref_clk_rate;
+	aux_clkin.rate = aux_clkin_rate;
 	clk = davinci_clk_init(&ref_clk);
 	clk_register_clkdev(clk, "ref", NULL);
 	clk = davinci_clk_init(&aux_clkin);
@@ -998,9 +993,10 @@ void __init dm646x_init(void)
 	davinci_map_sysmod();
 }
 
-void __init dm646x_init_time(void)
+void __init dm646x_init_time(unsigned long ref_clk_rate,
+			     unsigned long aux_clkin_rate)
 {
-	dm646x_clk_init();
+	dm646x_clk_init(ref_clk_rate, aux_clkin_rate);
 	davinci_timer_init();
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 4/7] ARM: davinci: remove davinci_set_refclk_rate()
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

This removes the davinci_set_refclk_rate() function. This was used to set
the ref_clk rate after all clocks had been registered when clocks were
registered from a static table.

However, now it is possible to modify the rate before registering the
clocks in the first place by passing the rate as a function parameter.
The aux_clkin rate is also passed as a parameter since technically it is
also board-specific.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/mach-davinci/board-dm646x-evm.c | 12 +++++++-----
 arch/arm/mach-davinci/clock.c            | 32 --------------------------------
 arch/arm/mach-davinci/clock.h            |  1 -
 arch/arm/mach-davinci/davinci.h          |  2 +-
 arch/arm/mach-davinci/dm646x.c           | 18 +++++++-----------
 5 files changed, 15 insertions(+), 50 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index dafc852..c8f517b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -716,17 +716,19 @@ static void __init evm_init_i2c(void)
 }
 #endif
 
-#define DM6467T_EVM_REF_FREQ		33000000
-
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
 }
 
+static void __init dm6467_evm_init_time(void)
+{
+	dm646x_init_time(27000000, 24000000);
+}
+
 static void __init dm6467t_evm_init_time(void)
 {
-	dm646x_init_time();
-	davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+	dm646x_init_time(33000000, 24000000);
 }
 
 #define DM646X_EVM_PHY_ID		"davinci_mdio-0:01"
@@ -800,7 +802,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.atag_offset  = 0x100,
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_irq_init,
-	.init_time	= dm646x_init_time,
+	.init_time	= dm6467_evm_init_time,
 	.init_machine = evm_init,
 	.init_late	= davinci_init_late,
 	.dma_zone_size	= SZ_128M,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f82a90c..52b95e2 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -575,38 +575,6 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
 }
 EXPORT_SYMBOL(davinci_set_pllrate);
 
-/**
- * davinci_set_refclk_rate() - Set the reference clock rate
- * @rate:	The new rate.
- *
- * Sets the reference clock rate to a given value. This will most likely
- * result in the entire clock tree getting updated.
- *
- * This is used to support boards which use a reference clock different
- * than that used by default in <soc>.c file. The reference clock rate
- * should be updated early in the boot process; ideally soon after the
- * clock tree has been initialized once with the default reference clock
- * rate (davinci_clk_init()).
- *
- * Returns 0 on success, error otherwise.
- */
-int davinci_set_refclk_rate(unsigned long rate)
-{
-	struct clk *refclk;
-
-	refclk = clk_get(NULL, "ref");
-	if (IS_ERR(refclk)) {
-		pr_err("%s: failed to get reference clock\n", __func__);
-		return PTR_ERR(refclk);
-	}
-
-	clk_set_rate(refclk, rate);
-
-	clk_put(refclk);
-
-	return 0;
-}
-
 struct clk * __init davinci_clk_init(struct clk *clk)
 {
 	if (!clk->recalc) {
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 66c40a2..61fcdaa 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -122,7 +122,6 @@ 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_set_refclk_rate(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);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index d70f4d9..270cef8 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -111,7 +111,7 @@ int dm644x_gpio_register(void);
 
 /* DM646x function declarations */
 void dm646x_init(void);
-void dm646x_init_time(void);
+void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 0cd5d51..31dbe93 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -39,12 +39,6 @@
 #define VSCLKDIS_MASK		(BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
 					BIT_MASK(8))
 
-/*
- * Device specific clocks
- */
-#define DM646X_REF_FREQ		27000000
-#define DM646X_AUX_FREQ		24000000
-
 #define DM646X_EMAC_BASE		0x01c80000
 #define DM646X_EMAC_MDIO_BASE		(DM646X_EMAC_BASE + 0x4000)
 #define DM646X_EMAC_CNTRL_OFFSET	0x0000
@@ -64,13 +58,11 @@ static struct pll_data pll2_data = {
 
 static struct clk ref_clk = {
 	.name = "ref_clk",
-	.rate = DM646X_REF_FREQ,
 	.set_rate = davinci_simple_set_rate,
 };
 
 static struct clk aux_clkin = {
 	.name = "aux_clkin",
-	.rate = DM646X_AUX_FREQ,
 };
 
 static struct clk pll1_clk = {
@@ -320,10 +312,13 @@ static struct clk vpif1_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
-static __init void dm646x_clk_init(void)
+static __init void dm646x_clk_init(unsigned long ref_clk_rate,
+				   unsigned long aux_clkin_rate)
 {
 	struct clk *clk;
 
+	ref_clk.rate = ref_clk_rate;
+	aux_clkin.rate = aux_clkin_rate;
 	clk = davinci_clk_init(&ref_clk);
 	clk_register_clkdev(clk, "ref", NULL);
 	clk = davinci_clk_init(&aux_clkin);
@@ -998,9 +993,10 @@ void __init dm646x_init(void)
 	davinci_map_sysmod();
 }
 
-void __init dm646x_init_time(void)
+void __init dm646x_init_time(unsigned long ref_clk_rate,
+			     unsigned long aux_clkin_rate)
 {
-	dm646x_clk_init();
+	dm646x_clk_init(ref_clk_rate, aux_clkin_rate);
 	davinci_timer_init();
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

This introduces new drivers for arch/arm/mach-davinci. The code is based
on the clock drivers from there and adapted to use the common clock
framework.

Signed-off-by: David Lechner <david@lechnology.com>
---
 drivers/clk/Makefile                      |   1 +
 drivers/clk/davinci/Makefile              |   3 +
 drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380 ++++++++++++++++++++++++++++++
 drivers/clk/davinci/pll.c                 | 333 ++++++++++++++++++++++++++
 drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
 include/linux/clk/davinci.h               |  46 ++++
 include/linux/platform_data/davinci_clk.h |  25 ++
 7 files changed, 1005 insertions(+)
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
 create mode 100644 drivers/clk/davinci/pll.c
 create mode 100644 drivers/clk/davinci/psc.c
 create mode 100644 include/linux/clk/davinci.h
 create mode 100644 include/linux/platform_data/davinci_clk.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7f761b..c865fd0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
 obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
 obj-y					+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
+obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
 obj-$(CONFIG_H8300)			+= h8300/
 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
 obj-y					+= imgtec/
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
new file mode 100644
index 0000000..5efbdcd
--- /dev/null
+++ b/drivers/clk/davinci/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PHY_DA8XX_USB) += da8xx-cfgchip-clk.o
+obj-y += pll.o
+obj-y += psc.o
\ No newline at end of file
diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
new file mode 100644
index 0000000..780bb25
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * da8xx-cfgchip-clk - TI DaVinci DA8xx CFGCHIP clocks driver
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * This driver exposes the USB PHY clocks on DA8xx/AM18xx/OMAP-L13x SoCs.
+ * The clocks consist of two muxes and a PLL. The USB 2.0 PHY mux and PLL are
+ * combined into a single clock in Linux. The USB 1.0 PHY clock just consists
+ * of a mux. These clocks are controlled through CFGCHIP2, which is accessed
+ * as a syscon regmap since it is shared with other devices.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_data/davinci_clk.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/**
+ * da8xx_cfgchip_clk
+ * @usb0_hw: The USB 2.0 PHY clock (mux + PLL)
+ * @usb1_hw: The USB 1.1 PHY clock (mux)
+ * @usb0_clk: The USB 2.0 subsystem PSC clock
+ * @regmap: The CFGCHIP syscon regmap
+ */
+struct da8xx_cfgchip_clk {
+	struct clk_hw usb0_hw;
+	struct clk_hw usb1_hw;
+	struct clk *usb0_clk;
+	struct regmap *regmap;
+};
+
+/* The USB 2.0 PHY can use either USB_REFCLKIN or AUXCLK */
+enum usb0_phy_clk_parent {
+	USB20_PHY_CLK_PARENT_USB_REFCLKIN,
+	USB20_PHY_CLK_PARENT_PLL0_AUX,
+};
+
+/* The USB 1.1 PHY can use either the PLL output from the USB 2.0 PHY or
+ * USB_REFCLKIN
+ */
+enum usb1_phy_clk_parent {
+	USB1_PHY_CLK_PARENT_USB_REFCLKIN,
+	USB1_PHY_CLK_PARENT_USB0_PHY_PLL,
+};
+
+/* --- USB 2.0 PHY clock --- */
+
+static int usb0_phy_clk_prepare(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+
+	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
+	 * PHY clock enable, but since clk_prepare() can't be called in an
+	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
+	 */
+	return clk_prepare(clk->usb0_clk);
+}
+
+static void usb0_phy_clk_unprepare(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+
+	clk_unprepare(clk->usb0_clk);
+}
+
+static int usb0_phy_clk_enable(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+	int ret;
+
+	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
+	 * temporaily. It can be turned back off once the PLL is locked.
+	 */
+	clk_enable(clk->usb0_clk);
+
+	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
+	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
+	 */
+	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
+	val = CFGCHIP2_PHY_PLLON;
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+	ret = regmap_read_poll_timeout(clk->regmap, CFGCHIP(2), val,
+				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
+
+	clk_disable(clk->usb0_clk);
+
+	return ret;
+}
+
+static void usb0_phy_clk_disable(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int val;
+
+	val = CFGCHIP2_PHYPWRDN;
+	regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
+}
+
+static unsigned long usb0_phy_clk_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+
+	/* The parent clock rate must be one of the following */
+	mask = CFGCHIP2_REFFREQ_MASK;
+	switch (parent_rate) {
+	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:
+		return 0;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	/* USB 2.0 PLL always supplies 48MHz */
+	return 48000000;
+}
+
+static long usb0_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	return 48000000;
+}
+
+static int usb0_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+
+	/* Set the mux depending on the parent clock. */
+	mask = CFGCHIP2_USB2PHYCLKMUX;
+	switch (index) {
+	case USB20_PHY_CLK_PARENT_USB_REFCLKIN:
+		val = 0;
+		break;
+	case USB20_PHY_CLK_PARENT_PLL0_AUX:
+		val = CFGCHIP2_USB2PHYCLKMUX;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	return 0;
+}
+
+static u8 usb0_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int val;
+
+	regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+	if (val & CFGCHIP2_USB2PHYCLKMUX)
+		return USB20_PHY_CLK_PARENT_PLL0_AUX;
+
+	return USB20_PHY_CLK_PARENT_USB_REFCLKIN;
+}
+
+static const struct clk_ops usb0_phy_clk_ops = {
+	.prepare	= usb0_phy_clk_prepare,
+	.unprepare	= usb0_phy_clk_unprepare,
+	.enable		= usb0_phy_clk_enable,
+	.disable	= usb0_phy_clk_disable,
+	.recalc_rate	= usb0_phy_clk_recalc_rate,
+	.round_rate	= usb0_phy_clk_round_rate,
+	.set_parent	= usb0_phy_clk_set_parent,
+	.get_parent	= usb0_phy_clk_get_parent,
+};
+
+static const char * const usb0_phy_clk_parent_names[] = {
+	[USB20_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
+	[USB20_PHY_CLK_PARENT_PLL0_AUX]		= "pll0_aux_clk",
+};
+
+static const struct clk_init_data usb0_phy_clk_init_data = {
+	.name		= "usb0_phy_clk",
+	.ops		= &usb0_phy_clk_ops,
+	.parent_names	= usb0_phy_clk_parent_names,
+	.num_parents	= ARRAY_SIZE(usb0_phy_clk_parent_names),
+};
+
+/* --- USB 1.1 PHY clock --- */
+
+static int usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
+	unsigned int mask, val;
+
+	/* Set the USB 1.1 PHY clock mux based on the parent clock. */
+	mask = CFGCHIP2_USB1PHYCLKMUX;
+	switch (index) {
+	case USB1_PHY_CLK_PARENT_USB_REFCLKIN:
+		val = CFGCHIP2_USB1PHYCLKMUX;
+		break;
+	case USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
+		val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	return 0;
+}
+
+static u8 usb1_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
+	unsigned int val;
+
+	regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+	if (val & CFGCHIP2_USB1PHYCLKMUX)
+		return USB1_PHY_CLK_PARENT_USB_REFCLKIN;
+
+	return USB1_PHY_CLK_PARENT_USB0_PHY_PLL;
+}
+
+static const struct clk_ops usb1_phy_clk_ops = {
+	.set_parent	= usb1_phy_clk_set_parent,
+	.get_parent	= usb1_phy_clk_get_parent,
+};
+
+static const char * const usb1_phy_clk_parent_names[] = {
+	[USB1_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
+	[USB1_PHY_CLK_PARENT_USB0_PHY_PLL]	= "usb0_phy_clk",
+};
+
+static struct clk_init_data usb1_phy_clk_init_data = {
+	.name		= "usb1_phy_clk",
+	.ops		= &usb1_phy_clk_ops,
+	.parent_names	= usb1_phy_clk_parent_names,
+	.num_parents	= ARRAY_SIZE(usb1_phy_clk_parent_names),
+};
+
+/* --- platform driver --- */
+
+static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
+	struct da8xx_cfgchip_clk *phy_clk;
+	const char *parent_name;
+	struct clk *parent;
+	int ret;
+
+	if (!pdata)
+		return -EINVAL;
+
+	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
+	if (!phy_clk)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, phy_clk);
+
+	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");
+	if (IS_ERR(phy_clk->regmap)) {
+		dev_err(dev, "Failed to get syscon\n");
+		return PTR_ERR(phy_clk->regmap);
+	}
+
+	/* USB 2.0 subsystem PSC clock - needed to lock PLL */
+	phy_clk->usb0_clk = clk_get(dev, "usb20");
+	if (IS_ERR(phy_clk->usb0_clk)) {
+		dev_err(dev, "Failed to get usb20 clock\n");
+		return PTR_ERR(phy_clk->usb0_clk);
+	}
+
+	phy_clk->usb0_hw.init = &usb0_phy_clk_init_data;
+	ret = devm_clk_hw_register(dev, &phy_clk->usb0_hw);
+	if (ret) {
+		dev_err(dev, "Failed to register usb0_phy_clk\n");
+		return ret;
+	}
+
+	phy_clk->usb1_hw.init = &usb1_phy_clk_init_data;
+	ret = devm_clk_hw_register(dev, &phy_clk->usb1_hw);
+	if (ret) {
+		dev_err(dev, "Failed to register usb1_phy_clk\n");
+		return ret;
+	}
+
+	parent_name = pdata->usb0_use_refclkin ? "usb_refclkin" : "pll0_aux";
+	parent = devm_clk_get(dev, parent_name);
+	if (IS_ERR(parent)) {
+		dev_err(dev, "Failed to get usb0 parent clock %s\n",
+			parent_name);
+		return PTR_ERR(parent);
+	}
+
+	ret = clk_set_parent(phy_clk->usb0_hw.clk, parent);
+	if (ret) {
+		dev_err(dev, "Failed to set usb0 parent clock to %s\n",
+			parent_name);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(&phy_clk->usb0_hw, NULL, "da8xx-cfgchip-clk");
+
+	parent_name = pdata->usb1_use_refclkin ? "usb_refclkin" : "usb0_phy_clk";
+	parent = devm_clk_get(dev, parent_name);
+	if (IS_ERR(parent)) {
+		dev_err(dev, "Failed to get usb1 parent clock %s\n",
+			parent_name);
+		return PTR_ERR(parent);
+	}
+
+	ret = clk_set_parent(phy_clk->usb1_hw.clk, parent);
+	if (ret) {
+		dev_err(dev, "Failed to set usb1 parent clock to %s\n",
+			parent_name);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(&phy_clk->usb0_hw, "usb20_phy", "da8xx-usb-phy");
+	clk_hw_register_clkdev(&phy_clk->usb1_hw, "usb11_phy", "da8xx-usb-phy");
+
+	return 0;
+}
+
+static struct platform_driver da8xx_cfgchip_clk_driver = {
+	.probe = da8xx_cfgchip_clk_probe,
+	.driver = {
+		.name = "da8xx-cfgchip-clk",
+	},
+};
+module_platform_driver(da8xx_cfgchip_clk_driver);
+
+MODULE_ALIAS("platform:da8xx-cfgchip-clk");
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI DA8xx CFGCHIP clock driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
new file mode 100644
index 0000000..035cd91
--- /dev/null
+++ b/drivers/clk/davinci/pll.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for Davinci devices
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on drivers/clk/keystone/pll.c
+ * Copyright (C) 2013 Texas Instruments Inc.
+ *	Murali Karicheri <m-karicheri2@ti.com>
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define REVID		0x000
+#define PLLCTL		0x100
+#define OCSEL		0x104
+#define PLLSECCTL	0x108
+#define PLLM		0x110
+#define PREDIV		0x114
+#define PLLDIV1		0x118
+#define PLLDIV2		0x11c
+#define PLLDIV3		0x120
+#define OSCDIV		0x124
+#define POSTDIV		0x128
+#define BPDIV		0x12c
+#define PLLCMD		0x138
+#define PLLSTAT		0x13c
+#define ALNCTL		0x140
+#define DCHANGE		0x144
+#define CKEN		0x148
+#define CKSTAT		0x14c
+#define SYSTAT		0x150
+#define PLLDIV4		0x160
+#define PLLDIV5		0x164
+#define PLLDIV6		0x168
+#define PLLDIV7		0x16c
+#define PLLDIV8		0x170
+#define PLLDIV9		0x174
+
+#define PLLM_MASK		0x1f
+#define PREDIV_RATIO_MASK	0x1f
+#define PLLDIV_RATIO_WIDTH	5
+#define PLLDIV_ENABLE_SHIFT	15
+#define OSCDIV_RATIO_WIDTH	5
+#define POSTDIV_RATIO_MASK	0x1f
+#define BPDIV_RATIO_SHIFT	0
+#define BPDIV_RATIO_WIDTH	5
+#define CKEN_OBSCLK_SHIFT	1
+#define CKEN_AUXEN_SHIFT	0
+
+/**
+ * struct davinci_pll_clk - Main PLL clock
+ * @hw: clk_hw for the pll
+ * @base: Base memory address
+ * @parent_rate: Saved parent rate used by some child clocks
+ */
+struct davinci_pll_clk {
+	struct clk_hw hw;
+	void __iomem *base;
+};
+
+#define to_davinci_pll_clk(_hw) container_of((_hw), struct davinci_pll_clk, hw)
+
+static unsigned long davinci_pll_clk_recalc(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	unsigned long rate = parent_rate;
+	u32 prediv, mult, postdiv;
+
+	prediv = readl(pll->base + PREDIV) & PREDIV_RATIO_MASK;
+	mult = readl(pll->base + PLLM) & PLLM_MASK;
+	postdiv = readl(pll->base + POSTDIV) & POSTDIV_RATIO_MASK;
+
+	rate /= prediv + 1;
+	rate *= mult + 1;
+	rate /= postdiv + 1;
+
+	return rate;
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+#define DEBUG_REG(n)	\
+{			\
+	.name	= #n,	\
+	.offset	= n,	\
+}
+
+static const struct debugfs_reg32 davinci_pll_regs[] = {
+	DEBUG_REG(REVID),
+	DEBUG_REG(PLLCTL),
+	DEBUG_REG(OCSEL),
+	DEBUG_REG(PLLSECCTL),
+	DEBUG_REG(PLLM),
+	DEBUG_REG(PREDIV),
+	DEBUG_REG(PLLDIV1),
+	DEBUG_REG(PLLDIV2),
+	DEBUG_REG(PLLDIV3),
+	DEBUG_REG(OSCDIV),
+	DEBUG_REG(POSTDIV),
+	DEBUG_REG(BPDIV),
+	DEBUG_REG(PLLCMD),
+	DEBUG_REG(PLLSTAT),
+	DEBUG_REG(ALNCTL),
+	DEBUG_REG(DCHANGE),
+	DEBUG_REG(CKEN),
+	DEBUG_REG(CKSTAT),
+	DEBUG_REG(SYSTAT),
+	DEBUG_REG(PLLDIV4),
+	DEBUG_REG(PLLDIV5),
+	DEBUG_REG(PLLDIV6),
+	DEBUG_REG(PLLDIV7),
+	DEBUG_REG(PLLDIV8),
+	DEBUG_REG(PLLDIV9),
+};
+
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	struct debugfs_regset32 *regset;
+	struct dentry *d;
+
+	regset = kzalloc(sizeof(regset), GFP_KERNEL);
+	if (!regset)
+		return -ENOMEM;
+
+	regset->regs = davinci_pll_regs;
+	regset->nregs = ARRAY_SIZE(davinci_pll_regs);
+	regset->base = pll->base;
+
+	d = debugfs_create_regset32("registers", 0400, dentry, regset);
+	if (IS_ERR(d)) {
+		kfree(regset);
+		return PTR_ERR(d);
+	}
+
+	return 0;
+}
+#else
+#define davinci_pll_debug_init NULL
+#endif
+
+static const struct clk_ops davinci_pll_clk_ops = {
+	.recalc_rate	= davinci_pll_clk_recalc,
+	.debug_init	= davinci_pll_debug_init,
+};
+
+/**
+ * davinci_pll_clk_register - Register a PLL clock
+ * @name: The clock name
+ * @parent_name: The parent clock name
+ * @base: The PLL's memory region
+ */
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base)
+{
+	struct clk_init_data init;
+	struct davinci_pll_clk *pll;
+	struct clk *clk;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &davinci_pll_clk_ops;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	pll->base = base;
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+struct davinci_pll_aux_clk {
+	struct clk_hw hw;
+	struct davinci_pll_clk *pll;
+};
+
+/**
+ * davinci_pll_aux_clk_register - Register bypass clock (AUXCLK)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base)
+{
+	return clk_register_gate(NULL, name, parent_name, 0, base + CKEN,
+				 CKEN_AUXEN_SHIFT, 0, NULL);
+}
+
+/**
+ * davinci_pll_bpdiv_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base)
+{
+	return clk_register_divider(NULL, name, parent_name, 0, base + BPDIV,
+				    BPDIV_RATIO_SHIFT, BPDIV_RATIO_WIDTH,
+				    CLK_DIVIDER_READ_ONLY, NULL);
+}
+
+/**
+ * davinci_pll_obs_clk_register - Register oscillator divider clock (OBSCLK)
+ * @name: The clock name
+ * @parent_names: The parent clock names
+ * @num_parents: The number of paren clocks
+ * @base: The PLL memory region
+ * @table: A table of values cooresponding to the parent clocks (see OCSEL
+ *         register in SRM for values)
+ */
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table)
+{
+	struct clk_mux *mux;
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->reg = base + OCSEL;
+	mux->table = table;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = base + CKEN;
+	gate->bit_idx = CKEN_OBSCLK_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + OSCDIV;
+	divider->width = OSCDIV_RATIO_WIDTH;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     &mux->hw, &clk_mux_ops,
+				     &divider->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+		kfree(mux);
+	}
+
+	return clk;
+}
+
+/**
+ * davinci_pll_div_clk_register - Register a PLLDIV (SYSCLK) clock
+ * @name: The clock name
+ * @parent_name: The parent clock name
+ * @base: The PLL memory region
+ * @id: The id of the divider (n in PLLDIVn)
+ */
+struct clk *davinci_pll_div_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base,
+					 u32 id)
+{
+	const char * const *parent_names = (parent_name ? &parent_name : NULL);
+	int num_parents = (parent_name ? 1 : 0);
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+	u32 reg;
+
+	/* PLLDIVn registers are not entirely consecutive */
+	if (id < 4)
+		reg = PLLDIV1 + 4 * (id - 1);
+	else
+		reg = PLLDIV4 + 4 * (id - 4);
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = base + reg;
+	gate->bit_idx = PLLDIV_ENABLE_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + reg;
+	divider->width = PLLDIV_RATIO_WIDTH;
+	divider->flags = CLK_DIVIDER_READ_ONLY;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     NULL, NULL, &divider->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
new file mode 100644
index 0000000..8ae85ee
--- /dev/null
+++ b/drivers/clk/davinci/psc.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on: drivers/clk/keystone/gate.c
+ * Copyright (C) 2013 Texas Instruments.
+ *	Murali Karicheri <m-karicheri2@ti.com>
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * And: arch/arm/mach-davinci/psc.c
+ * Copyright (C) 2006 Texas Instruments.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+/* PSC register offsets */
+#define EPCPR			0x070
+#define PTCMD			0x120
+#define PTSTAT			0x128
+#define PDSTAT			0x200
+#define PDCTL			0x300
+#define MDSTAT			0x800
+#define MDCTL			0xa00
+
+/* PSC module states */
+enum davinci_psc_state {
+	PSC_STATE_SWRSTDISABLE	= 0,
+	PSC_STATE_SYNCRST	= 1,
+	PSC_STATE_DISABLE	= 2,
+	PSC_STATE_ENABLE	= 3,
+};
+
+#define MDSTAT_STATE_MASK	0x3f
+#define MDSTAT_MCKOUT		BIT(12)
+#define PDSTAT_STATE_MASK	0x1f
+#define MDCTL_FORCE		BIT(31)
+#define MDCTL_LRESET		BIT(8)
+#define PDCTL_EPCGOOD		BIT(8)
+#define PDCTL_NEXT		BIT(0)
+
+/**
+ * struct davinci_psc_clk - PSC clock structure
+ * @hw: clk_hw for the psc
+ * @psc_data: PSC driver specific data
+ * @lpsc: Local PSC number (module id)
+ * @pd: Power domain
+ */
+struct davinci_psc_clk {
+	struct clk_hw hw;
+	void __iomem *base;
+	u32 lpsc;
+	u32 pd;
+};
+
+#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
+
+static void psc_config(struct davinci_psc_clk *psc,
+		       enum davinci_psc_state next_state)
+{
+	u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
+
+	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
+	mdctl &= ~MDSTAT_STATE_MASK;
+	mdctl |= next_state;
+	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
+	 * dsp here. Is this really needed?
+	 */
+	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
+
+	pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
+	if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+		pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
+		pdctl |= PDCTL_NEXT;
+		writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
+
+		ptcmd = BIT(psc->pd);
+		writel(ptcmd, psc->base + PTCMD);
+
+		do {
+			epcpr = __raw_readl(psc->base + EPCPR);
+		} while (!(epcpr & BIT(psc->pd)));
+
+		pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
+		pdctl |= PDCTL_EPCGOOD;
+		__raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
+	} else {
+		ptcmd = BIT(psc->pd);
+		writel(ptcmd, psc->base + PTCMD);
+	}
+
+	do {
+		ptstat = readl(psc->base + PTSTAT);
+	} while (ptstat & BIT(psc->pd));
+
+	do {
+		mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
+	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+}
+
+static int davinci_psc_clk_enable(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+	psc_config(psc, PSC_STATE_ENABLE);
+
+	return 0;
+}
+
+static void davinci_psc_clk_disable(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+	psc_config(psc, PSC_STATE_DISABLE);
+}
+
+static int davinci_psc_clk_is_enabled(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+	u32 mdstat;
+
+	mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
+
+	return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
+}
+
+static const struct clk_ops davinci_psc_clk_ops = {
+	.enable		= davinci_psc_clk_enable,
+	.disable	= davinci_psc_clk_disable,
+	.is_enabled	= davinci_psc_clk_is_enabled,
+};
+
+/**
+ * davinci_psc_clk_register - register psc clock
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @base: memory mapped register for the PSC
+ * @lpsc: local PSC number
+ * @pd: power domain
+ */
+struct clk *davinci_psc_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base,
+				     u32 lpsc, u32 pd)
+{
+	struct clk_init_data init;
+	struct davinci_psc_clk *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &davinci_psc_clk_ops;
+	init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	psc->base = base;
+	psc->hw.init = &init;
+	psc->lpsc = lpsc;
+	psc->pd = pd;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return clk;
+}
+
+/* FIXME: This needs to be converted to a reset controller. But, the reset
+ * framework is currently device tree only.
+ */
+
+DEFINE_SPINLOCK(davinci_psc_reset_lock);
+
+static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
+{
+	unsigned long flags;
+	u32 mdctl;
+
+	if (IS_ERR_OR_NULL(psc))
+		return -EINVAL;
+
+	spin_lock_irqsave(&davinci_psc_reset_lock, flags);
+	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
+	if (reset)
+		mdctl &= ~MDCTL_LRESET;
+	else
+		mdctl |= MDCTL_LRESET;
+	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
+	spin_unlock_irqrestore(&davinci_psc_reset_lock, flags);
+
+	return 0;
+}
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+	return davinci_psc_clk_reset(psc, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+	return davinci_psc_clk_reset(psc, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
new file mode 100644
index 0000000..c5d2181
--- /dev/null
+++ b/include/linux/clk/davinci.h
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI Davinci clocks
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+#ifndef __LINUX_CLK_DAVINCI_H__
+#define __LINUX_CLK_DAVINCI_H__
+
+#include <linux/clk-provider.h>
+#include <linux/types.h>
+
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base);
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base);
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base);
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table);
+struct clk *davinci_pll_div_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base,
+					 u32 id);
+struct clk *davinci_psc_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base,
+				     u32 lpsc, u32 pd);
+
+/* convience macros for board declaration files */
+#define EXT_CLK(n, r) clk_register_fixed_rate(NULL, (n), NULL, 0, (r))
+#define FIX_CLK(n, p) clk_register_fixed_factor(NULL, (n), (p), 0, 1, 1)
+#define PLL_CLK davinci_pll_clk_register
+#define PLL_DIV_CLK davinci_pll_div_clk_register
+#define PLL_AUX_CLK davinci_pll_aux_clk_register
+#define PLL_BP_CLK davinci_pll_bpdiv_clk_register
+#define PLL_OBS_CLK davinci_pll_obs_clk_register
+#define PSC_CLK davinci_psc_clk_register
+
+#endif /* __LINUX_CLK_DAVINCI_H__ */
diff --git a/include/linux/platform_data/davinci_clk.h b/include/linux/platform_data/davinci_clk.h
new file mode 100644
index 0000000..7576ace
--- /dev/null
+++ b/include/linux/platform_data/davinci_clk.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI DaVinci Clock support
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#ifndef __PLATFORM_DATA_DAVINCI_CLK_H
+#define __PLATFORM_DATA_DAVINCI_CLK_H
+
+#include <linux/types.h>
+
+/**
+ * da8xx_cfgchip_clk_data - DA8xx CFGCHIP clock platform data
+ * @usb0_use_refclkin: when true, use USB_REFCLKIN, otherwise use AUXCLK for
+ *                     USB 2.0 PHY clock
+ * @usb1_use_refclkin: when true, use USB_REFCLKIN, otherwise use USB 2.0 PHY
+ *                     PLL for USB 1.1 PHY clock
+ */
+struct da8xx_cfgchip_clk_data {
+	bool usb0_use_refclkin;
+	bool usb1_use_refclkin;
+};
+
+#endif /* __PLATFORM_DATA_DAVINCI_CLK_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

This introduces new drivers for arch/arm/mach-davinci. The code is based
on the clock drivers from there and adapted to use the common clock
framework.

Signed-off-by: David Lechner <david@lechnology.com>
---
 drivers/clk/Makefile                      |   1 +
 drivers/clk/davinci/Makefile              |   3 +
 drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380 ++++++++++++++++++++++++++++++
 drivers/clk/davinci/pll.c                 | 333 ++++++++++++++++++++++++++
 drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
 include/linux/clk/davinci.h               |  46 ++++
 include/linux/platform_data/davinci_clk.h |  25 ++
 7 files changed, 1005 insertions(+)
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
 create mode 100644 drivers/clk/davinci/pll.c
 create mode 100644 drivers/clk/davinci/psc.c
 create mode 100644 include/linux/clk/davinci.h
 create mode 100644 include/linux/platform_data/davinci_clk.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7f761b..c865fd0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
 obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
 obj-y					+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
+obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
 obj-$(CONFIG_H8300)			+= h8300/
 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
 obj-y					+= imgtec/
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
new file mode 100644
index 0000000..5efbdcd
--- /dev/null
+++ b/drivers/clk/davinci/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PHY_DA8XX_USB) += da8xx-cfgchip-clk.o
+obj-y += pll.o
+obj-y += psc.o
\ No newline at end of file
diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
new file mode 100644
index 0000000..780bb25
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * da8xx-cfgchip-clk - TI DaVinci DA8xx CFGCHIP clocks driver
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * This driver exposes the USB PHY clocks on DA8xx/AM18xx/OMAP-L13x SoCs.
+ * The clocks consist of two muxes and a PLL. The USB 2.0 PHY mux and PLL are
+ * combined into a single clock in Linux. The USB 1.0 PHY clock just consists
+ * of a mux. These clocks are controlled through CFGCHIP2, which is accessed
+ * as a syscon regmap since it is shared with other devices.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_data/davinci_clk.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/**
+ * da8xx_cfgchip_clk
+ * @usb0_hw: The USB 2.0 PHY clock (mux + PLL)
+ * @usb1_hw: The USB 1.1 PHY clock (mux)
+ * @usb0_clk: The USB 2.0 subsystem PSC clock
+ * @regmap: The CFGCHIP syscon regmap
+ */
+struct da8xx_cfgchip_clk {
+	struct clk_hw usb0_hw;
+	struct clk_hw usb1_hw;
+	struct clk *usb0_clk;
+	struct regmap *regmap;
+};
+
+/* The USB 2.0 PHY can use either USB_REFCLKIN or AUXCLK */
+enum usb0_phy_clk_parent {
+	USB20_PHY_CLK_PARENT_USB_REFCLKIN,
+	USB20_PHY_CLK_PARENT_PLL0_AUX,
+};
+
+/* The USB 1.1 PHY can use either the PLL output from the USB 2.0 PHY or
+ * USB_REFCLKIN
+ */
+enum usb1_phy_clk_parent {
+	USB1_PHY_CLK_PARENT_USB_REFCLKIN,
+	USB1_PHY_CLK_PARENT_USB0_PHY_PLL,
+};
+
+/* --- USB 2.0 PHY clock --- */
+
+static int usb0_phy_clk_prepare(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+
+	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
+	 * PHY clock enable, but since clk_prepare() can't be called in an
+	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
+	 */
+	return clk_prepare(clk->usb0_clk);
+}
+
+static void usb0_phy_clk_unprepare(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+
+	clk_unprepare(clk->usb0_clk);
+}
+
+static int usb0_phy_clk_enable(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+	int ret;
+
+	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
+	 * temporaily. It can be turned back off once the PLL is locked.
+	 */
+	clk_enable(clk->usb0_clk);
+
+	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
+	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
+	 */
+	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
+	val = CFGCHIP2_PHY_PLLON;
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+	ret = regmap_read_poll_timeout(clk->regmap, CFGCHIP(2), val,
+				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
+
+	clk_disable(clk->usb0_clk);
+
+	return ret;
+}
+
+static void usb0_phy_clk_disable(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int val;
+
+	val = CFGCHIP2_PHYPWRDN;
+	regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
+}
+
+static unsigned long usb0_phy_clk_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+
+	/* The parent clock rate must be one of the following */
+	mask = CFGCHIP2_REFFREQ_MASK;
+	switch (parent_rate) {
+	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:
+		return 0;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	/* USB 2.0 PLL always supplies 48MHz */
+	return 48000000;
+}
+
+static long usb0_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	return 48000000;
+}
+
+static int usb0_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int mask, val;
+
+	/* Set the mux depending on the parent clock. */
+	mask = CFGCHIP2_USB2PHYCLKMUX;
+	switch (index) {
+	case USB20_PHY_CLK_PARENT_USB_REFCLKIN:
+		val = 0;
+		break;
+	case USB20_PHY_CLK_PARENT_PLL0_AUX:
+		val = CFGCHIP2_USB2PHYCLKMUX;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	return 0;
+}
+
+static u8 usb0_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
+	unsigned int val;
+
+	regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+	if (val & CFGCHIP2_USB2PHYCLKMUX)
+		return USB20_PHY_CLK_PARENT_PLL0_AUX;
+
+	return USB20_PHY_CLK_PARENT_USB_REFCLKIN;
+}
+
+static const struct clk_ops usb0_phy_clk_ops = {
+	.prepare	= usb0_phy_clk_prepare,
+	.unprepare	= usb0_phy_clk_unprepare,
+	.enable		= usb0_phy_clk_enable,
+	.disable	= usb0_phy_clk_disable,
+	.recalc_rate	= usb0_phy_clk_recalc_rate,
+	.round_rate	= usb0_phy_clk_round_rate,
+	.set_parent	= usb0_phy_clk_set_parent,
+	.get_parent	= usb0_phy_clk_get_parent,
+};
+
+static const char * const usb0_phy_clk_parent_names[] = {
+	[USB20_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
+	[USB20_PHY_CLK_PARENT_PLL0_AUX]		= "pll0_aux_clk",
+};
+
+static const struct clk_init_data usb0_phy_clk_init_data = {
+	.name		= "usb0_phy_clk",
+	.ops		= &usb0_phy_clk_ops,
+	.parent_names	= usb0_phy_clk_parent_names,
+	.num_parents	= ARRAY_SIZE(usb0_phy_clk_parent_names),
+};
+
+/* --- USB 1.1 PHY clock --- */
+
+static int usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
+	unsigned int mask, val;
+
+	/* Set the USB 1.1 PHY clock mux based on the parent clock. */
+	mask = CFGCHIP2_USB1PHYCLKMUX;
+	switch (index) {
+	case USB1_PHY_CLK_PARENT_USB_REFCLKIN:
+		val = CFGCHIP2_USB1PHYCLKMUX;
+		break;
+	case USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
+		val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+	return 0;
+}
+
+static u8 usb1_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct da8xx_cfgchip_clk *clk =
+			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
+	unsigned int val;
+
+	regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+	if (val & CFGCHIP2_USB1PHYCLKMUX)
+		return USB1_PHY_CLK_PARENT_USB_REFCLKIN;
+
+	return USB1_PHY_CLK_PARENT_USB0_PHY_PLL;
+}
+
+static const struct clk_ops usb1_phy_clk_ops = {
+	.set_parent	= usb1_phy_clk_set_parent,
+	.get_parent	= usb1_phy_clk_get_parent,
+};
+
+static const char * const usb1_phy_clk_parent_names[] = {
+	[USB1_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
+	[USB1_PHY_CLK_PARENT_USB0_PHY_PLL]	= "usb0_phy_clk",
+};
+
+static struct clk_init_data usb1_phy_clk_init_data = {
+	.name		= "usb1_phy_clk",
+	.ops		= &usb1_phy_clk_ops,
+	.parent_names	= usb1_phy_clk_parent_names,
+	.num_parents	= ARRAY_SIZE(usb1_phy_clk_parent_names),
+};
+
+/* --- platform driver --- */
+
+static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
+	struct da8xx_cfgchip_clk *phy_clk;
+	const char *parent_name;
+	struct clk *parent;
+	int ret;
+
+	if (!pdata)
+		return -EINVAL;
+
+	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
+	if (!phy_clk)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, phy_clk);
+
+	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");
+	if (IS_ERR(phy_clk->regmap)) {
+		dev_err(dev, "Failed to get syscon\n");
+		return PTR_ERR(phy_clk->regmap);
+	}
+
+	/* USB 2.0 subsystem PSC clock - needed to lock PLL */
+	phy_clk->usb0_clk = clk_get(dev, "usb20");
+	if (IS_ERR(phy_clk->usb0_clk)) {
+		dev_err(dev, "Failed to get usb20 clock\n");
+		return PTR_ERR(phy_clk->usb0_clk);
+	}
+
+	phy_clk->usb0_hw.init = &usb0_phy_clk_init_data;
+	ret = devm_clk_hw_register(dev, &phy_clk->usb0_hw);
+	if (ret) {
+		dev_err(dev, "Failed to register usb0_phy_clk\n");
+		return ret;
+	}
+
+	phy_clk->usb1_hw.init = &usb1_phy_clk_init_data;
+	ret = devm_clk_hw_register(dev, &phy_clk->usb1_hw);
+	if (ret) {
+		dev_err(dev, "Failed to register usb1_phy_clk\n");
+		return ret;
+	}
+
+	parent_name = pdata->usb0_use_refclkin ? "usb_refclkin" : "pll0_aux";
+	parent = devm_clk_get(dev, parent_name);
+	if (IS_ERR(parent)) {
+		dev_err(dev, "Failed to get usb0 parent clock %s\n",
+			parent_name);
+		return PTR_ERR(parent);
+	}
+
+	ret = clk_set_parent(phy_clk->usb0_hw.clk, parent);
+	if (ret) {
+		dev_err(dev, "Failed to set usb0 parent clock to %s\n",
+			parent_name);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(&phy_clk->usb0_hw, NULL, "da8xx-cfgchip-clk");
+
+	parent_name = pdata->usb1_use_refclkin ? "usb_refclkin" : "usb0_phy_clk";
+	parent = devm_clk_get(dev, parent_name);
+	if (IS_ERR(parent)) {
+		dev_err(dev, "Failed to get usb1 parent clock %s\n",
+			parent_name);
+		return PTR_ERR(parent);
+	}
+
+	ret = clk_set_parent(phy_clk->usb1_hw.clk, parent);
+	if (ret) {
+		dev_err(dev, "Failed to set usb1 parent clock to %s\n",
+			parent_name);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(&phy_clk->usb0_hw, "usb20_phy", "da8xx-usb-phy");
+	clk_hw_register_clkdev(&phy_clk->usb1_hw, "usb11_phy", "da8xx-usb-phy");
+
+	return 0;
+}
+
+static struct platform_driver da8xx_cfgchip_clk_driver = {
+	.probe = da8xx_cfgchip_clk_probe,
+	.driver = {
+		.name = "da8xx-cfgchip-clk",
+	},
+};
+module_platform_driver(da8xx_cfgchip_clk_driver);
+
+MODULE_ALIAS("platform:da8xx-cfgchip-clk");
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI DA8xx CFGCHIP clock driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
new file mode 100644
index 0000000..035cd91
--- /dev/null
+++ b/drivers/clk/davinci/pll.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for Davinci devices
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on drivers/clk/keystone/pll.c
+ * Copyright (C) 2013 Texas Instruments Inc.
+ *	Murali Karicheri <m-karicheri2@ti.com>
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define REVID		0x000
+#define PLLCTL		0x100
+#define OCSEL		0x104
+#define PLLSECCTL	0x108
+#define PLLM		0x110
+#define PREDIV		0x114
+#define PLLDIV1		0x118
+#define PLLDIV2		0x11c
+#define PLLDIV3		0x120
+#define OSCDIV		0x124
+#define POSTDIV		0x128
+#define BPDIV		0x12c
+#define PLLCMD		0x138
+#define PLLSTAT		0x13c
+#define ALNCTL		0x140
+#define DCHANGE		0x144
+#define CKEN		0x148
+#define CKSTAT		0x14c
+#define SYSTAT		0x150
+#define PLLDIV4		0x160
+#define PLLDIV5		0x164
+#define PLLDIV6		0x168
+#define PLLDIV7		0x16c
+#define PLLDIV8		0x170
+#define PLLDIV9		0x174
+
+#define PLLM_MASK		0x1f
+#define PREDIV_RATIO_MASK	0x1f
+#define PLLDIV_RATIO_WIDTH	5
+#define PLLDIV_ENABLE_SHIFT	15
+#define OSCDIV_RATIO_WIDTH	5
+#define POSTDIV_RATIO_MASK	0x1f
+#define BPDIV_RATIO_SHIFT	0
+#define BPDIV_RATIO_WIDTH	5
+#define CKEN_OBSCLK_SHIFT	1
+#define CKEN_AUXEN_SHIFT	0
+
+/**
+ * struct davinci_pll_clk - Main PLL clock
+ * @hw: clk_hw for the pll
+ * @base: Base memory address
+ * @parent_rate: Saved parent rate used by some child clocks
+ */
+struct davinci_pll_clk {
+	struct clk_hw hw;
+	void __iomem *base;
+};
+
+#define to_davinci_pll_clk(_hw) container_of((_hw), struct davinci_pll_clk, hw)
+
+static unsigned long davinci_pll_clk_recalc(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	unsigned long rate = parent_rate;
+	u32 prediv, mult, postdiv;
+
+	prediv = readl(pll->base + PREDIV) & PREDIV_RATIO_MASK;
+	mult = readl(pll->base + PLLM) & PLLM_MASK;
+	postdiv = readl(pll->base + POSTDIV) & POSTDIV_RATIO_MASK;
+
+	rate /= prediv + 1;
+	rate *= mult + 1;
+	rate /= postdiv + 1;
+
+	return rate;
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+#define DEBUG_REG(n)	\
+{			\
+	.name	= #n,	\
+	.offset	= n,	\
+}
+
+static const struct debugfs_reg32 davinci_pll_regs[] = {
+	DEBUG_REG(REVID),
+	DEBUG_REG(PLLCTL),
+	DEBUG_REG(OCSEL),
+	DEBUG_REG(PLLSECCTL),
+	DEBUG_REG(PLLM),
+	DEBUG_REG(PREDIV),
+	DEBUG_REG(PLLDIV1),
+	DEBUG_REG(PLLDIV2),
+	DEBUG_REG(PLLDIV3),
+	DEBUG_REG(OSCDIV),
+	DEBUG_REG(POSTDIV),
+	DEBUG_REG(BPDIV),
+	DEBUG_REG(PLLCMD),
+	DEBUG_REG(PLLSTAT),
+	DEBUG_REG(ALNCTL),
+	DEBUG_REG(DCHANGE),
+	DEBUG_REG(CKEN),
+	DEBUG_REG(CKSTAT),
+	DEBUG_REG(SYSTAT),
+	DEBUG_REG(PLLDIV4),
+	DEBUG_REG(PLLDIV5),
+	DEBUG_REG(PLLDIV6),
+	DEBUG_REG(PLLDIV7),
+	DEBUG_REG(PLLDIV8),
+	DEBUG_REG(PLLDIV9),
+};
+
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	struct debugfs_regset32 *regset;
+	struct dentry *d;
+
+	regset = kzalloc(sizeof(regset), GFP_KERNEL);
+	if (!regset)
+		return -ENOMEM;
+
+	regset->regs = davinci_pll_regs;
+	regset->nregs = ARRAY_SIZE(davinci_pll_regs);
+	regset->base = pll->base;
+
+	d = debugfs_create_regset32("registers", 0400, dentry, regset);
+	if (IS_ERR(d)) {
+		kfree(regset);
+		return PTR_ERR(d);
+	}
+
+	return 0;
+}
+#else
+#define davinci_pll_debug_init NULL
+#endif
+
+static const struct clk_ops davinci_pll_clk_ops = {
+	.recalc_rate	= davinci_pll_clk_recalc,
+	.debug_init	= davinci_pll_debug_init,
+};
+
+/**
+ * davinci_pll_clk_register - Register a PLL clock
+ * @name: The clock name
+ * @parent_name: The parent clock name
+ * @base: The PLL's memory region
+ */
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base)
+{
+	struct clk_init_data init;
+	struct davinci_pll_clk *pll;
+	struct clk *clk;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &davinci_pll_clk_ops;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	pll->base = base;
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+struct davinci_pll_aux_clk {
+	struct clk_hw hw;
+	struct davinci_pll_clk *pll;
+};
+
+/**
+ * davinci_pll_aux_clk_register - Register bypass clock (AUXCLK)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base)
+{
+	return clk_register_gate(NULL, name, parent_name, 0, base + CKEN,
+				 CKEN_AUXEN_SHIFT, 0, NULL);
+}
+
+/**
+ * davinci_pll_bpdiv_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base)
+{
+	return clk_register_divider(NULL, name, parent_name, 0, base + BPDIV,
+				    BPDIV_RATIO_SHIFT, BPDIV_RATIO_WIDTH,
+				    CLK_DIVIDER_READ_ONLY, NULL);
+}
+
+/**
+ * davinci_pll_obs_clk_register - Register oscillator divider clock (OBSCLK)
+ * @name: The clock name
+ * @parent_names: The parent clock names
+ * @num_parents: The number of paren clocks
+ * @base: The PLL memory region
+ * @table: A table of values cooresponding to the parent clocks (see OCSEL
+ *         register in SRM for values)
+ */
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table)
+{
+	struct clk_mux *mux;
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->reg = base + OCSEL;
+	mux->table = table;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = base + CKEN;
+	gate->bit_idx = CKEN_OBSCLK_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + OSCDIV;
+	divider->width = OSCDIV_RATIO_WIDTH;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     &mux->hw, &clk_mux_ops,
+				     &divider->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+		kfree(mux);
+	}
+
+	return clk;
+}
+
+/**
+ * davinci_pll_div_clk_register - Register a PLLDIV (SYSCLK) clock
+ * @name: The clock name
+ * @parent_name: The parent clock name
+ * @base: The PLL memory region
+ * @id: The id of the divider (n in PLLDIVn)
+ */
+struct clk *davinci_pll_div_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base,
+					 u32 id)
+{
+	const char * const *parent_names = (parent_name ? &parent_name : NULL);
+	int num_parents = (parent_name ? 1 : 0);
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+	u32 reg;
+
+	/* PLLDIVn registers are not entirely consecutive */
+	if (id < 4)
+		reg = PLLDIV1 + 4 * (id - 1);
+	else
+		reg = PLLDIV4 + 4 * (id - 4);
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = base + reg;
+	gate->bit_idx = PLLDIV_ENABLE_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + reg;
+	divider->width = PLLDIV_RATIO_WIDTH;
+	divider->flags = CLK_DIVIDER_READ_ONLY;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     NULL, NULL, &divider->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
new file mode 100644
index 0000000..8ae85ee
--- /dev/null
+++ b/drivers/clk/davinci/psc.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on: drivers/clk/keystone/gate.c
+ * Copyright (C) 2013 Texas Instruments.
+ *	Murali Karicheri <m-karicheri2@ti.com>
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * And: arch/arm/mach-davinci/psc.c
+ * Copyright (C) 2006 Texas Instruments.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+/* PSC register offsets */
+#define EPCPR			0x070
+#define PTCMD			0x120
+#define PTSTAT			0x128
+#define PDSTAT			0x200
+#define PDCTL			0x300
+#define MDSTAT			0x800
+#define MDCTL			0xa00
+
+/* PSC module states */
+enum davinci_psc_state {
+	PSC_STATE_SWRSTDISABLE	= 0,
+	PSC_STATE_SYNCRST	= 1,
+	PSC_STATE_DISABLE	= 2,
+	PSC_STATE_ENABLE	= 3,
+};
+
+#define MDSTAT_STATE_MASK	0x3f
+#define MDSTAT_MCKOUT		BIT(12)
+#define PDSTAT_STATE_MASK	0x1f
+#define MDCTL_FORCE		BIT(31)
+#define MDCTL_LRESET		BIT(8)
+#define PDCTL_EPCGOOD		BIT(8)
+#define PDCTL_NEXT		BIT(0)
+
+/**
+ * struct davinci_psc_clk - PSC clock structure
+ * @hw: clk_hw for the psc
+ * @psc_data: PSC driver specific data
+ * @lpsc: Local PSC number (module id)
+ * @pd: Power domain
+ */
+struct davinci_psc_clk {
+	struct clk_hw hw;
+	void __iomem *base;
+	u32 lpsc;
+	u32 pd;
+};
+
+#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
+
+static void psc_config(struct davinci_psc_clk *psc,
+		       enum davinci_psc_state next_state)
+{
+	u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
+
+	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
+	mdctl &= ~MDSTAT_STATE_MASK;
+	mdctl |= next_state;
+	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
+	 * dsp here. Is this really needed?
+	 */
+	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
+
+	pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
+	if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+		pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
+		pdctl |= PDCTL_NEXT;
+		writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
+
+		ptcmd = BIT(psc->pd);
+		writel(ptcmd, psc->base + PTCMD);
+
+		do {
+			epcpr = __raw_readl(psc->base + EPCPR);
+		} while (!(epcpr & BIT(psc->pd)));
+
+		pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
+		pdctl |= PDCTL_EPCGOOD;
+		__raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
+	} else {
+		ptcmd = BIT(psc->pd);
+		writel(ptcmd, psc->base + PTCMD);
+	}
+
+	do {
+		ptstat = readl(psc->base + PTSTAT);
+	} while (ptstat & BIT(psc->pd));
+
+	do {
+		mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
+	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+}
+
+static int davinci_psc_clk_enable(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+	psc_config(psc, PSC_STATE_ENABLE);
+
+	return 0;
+}
+
+static void davinci_psc_clk_disable(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+	psc_config(psc, PSC_STATE_DISABLE);
+}
+
+static int davinci_psc_clk_is_enabled(struct clk_hw *hw)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+	u32 mdstat;
+
+	mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
+
+	return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
+}
+
+static const struct clk_ops davinci_psc_clk_ops = {
+	.enable		= davinci_psc_clk_enable,
+	.disable	= davinci_psc_clk_disable,
+	.is_enabled	= davinci_psc_clk_is_enabled,
+};
+
+/**
+ * davinci_psc_clk_register - register psc clock
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @base: memory mapped register for the PSC
+ * @lpsc: local PSC number
+ * @pd: power domain
+ */
+struct clk *davinci_psc_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base,
+				     u32 lpsc, u32 pd)
+{
+	struct clk_init_data init;
+	struct davinci_psc_clk *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &davinci_psc_clk_ops;
+	init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	psc->base = base;
+	psc->hw.init = &init;
+	psc->lpsc = lpsc;
+	psc->pd = pd;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return clk;
+}
+
+/* FIXME: This needs to be converted to a reset controller. But, the reset
+ * framework is currently device tree only.
+ */
+
+DEFINE_SPINLOCK(davinci_psc_reset_lock);
+
+static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
+{
+	unsigned long flags;
+	u32 mdctl;
+
+	if (IS_ERR_OR_NULL(psc))
+		return -EINVAL;
+
+	spin_lock_irqsave(&davinci_psc_reset_lock, flags);
+	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
+	if (reset)
+		mdctl &= ~MDCTL_LRESET;
+	else
+		mdctl |= MDCTL_LRESET;
+	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
+	spin_unlock_irqrestore(&davinci_psc_reset_lock, flags);
+
+	return 0;
+}
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+	return davinci_psc_clk_reset(psc, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+	return davinci_psc_clk_reset(psc, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
new file mode 100644
index 0000000..c5d2181
--- /dev/null
+++ b/include/linux/clk/davinci.h
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI Davinci clocks
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+#ifndef __LINUX_CLK_DAVINCI_H__
+#define __LINUX_CLK_DAVINCI_H__
+
+#include <linux/clk-provider.h>
+#include <linux/types.h>
+
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base);
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base);
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base);
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table);
+struct clk *davinci_pll_div_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base,
+					 u32 id);
+struct clk *davinci_psc_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base,
+				     u32 lpsc, u32 pd);
+
+/* convience macros for board declaration files */
+#define EXT_CLK(n, r) clk_register_fixed_rate(NULL, (n), NULL, 0, (r))
+#define FIX_CLK(n, p) clk_register_fixed_factor(NULL, (n), (p), 0, 1, 1)
+#define PLL_CLK davinci_pll_clk_register
+#define PLL_DIV_CLK davinci_pll_div_clk_register
+#define PLL_AUX_CLK davinci_pll_aux_clk_register
+#define PLL_BP_CLK davinci_pll_bpdiv_clk_register
+#define PLL_OBS_CLK davinci_pll_obs_clk_register
+#define PSC_CLK davinci_psc_clk_register
+
+#endif /* __LINUX_CLK_DAVINCI_H__ */
diff --git a/include/linux/platform_data/davinci_clk.h b/include/linux/platform_data/davinci_clk.h
new file mode 100644
index 0000000..7576ace
--- /dev/null
+++ b/include/linux/platform_data/davinci_clk.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI DaVinci Clock support
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#ifndef __PLATFORM_DATA_DAVINCI_CLK_H
+#define __PLATFORM_DATA_DAVINCI_CLK_H
+
+#include <linux/types.h>
+
+/**
+ * da8xx_cfgchip_clk_data - DA8xx CFGCHIP clock platform data
+ * @usb0_use_refclkin: when true, use USB_REFCLKIN, otherwise use AUXCLK for
+ *                     USB 2.0 PHY clock
+ * @usb1_use_refclkin: when true, use USB_REFCLKIN, otherwise use USB 2.0 PHY
+ *                     PLL for USB 1.1 PHY clock
+ */
+struct da8xx_cfgchip_clk_data {
+	bool usb0_use_refclkin;
+	bool usb1_use_refclkin;
+};
+
+#endif /* __PLATFORM_DATA_DAVINCI_CLK_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2017-12-31 23:39 ` David Lechner
                   ` (5 preceding siblings ...)
  (?)
@ 2017-12-31 23:39 ` David Lechner
  2018-01-04 12:39     ` Sekhar Nori
  -1 siblings, 1 reply; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

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 <david@lechnology.com>
---
 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

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 7/7] ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
  2017-12-31 23:39 ` David Lechner
@ 2017-12-31 23:39   ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: David Lechner, Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

This removes CONFIG_DAVINCI_RESET_CLOCKS. The option has been removed from
the kernel.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/configs/davinci_all_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 026154c..94d8946 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -31,7 +31,6 @@ CONFIG_MACH_MITYOMAPL138=y
 CONFIG_MACH_OMAPL138_HAWKBOARD=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_CMA=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v4 7/7] ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
@ 2017-12-31 23:39   ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2017-12-31 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

This removes CONFIG_DAVINCI_RESET_CLOCKS. The option has been removed from
the kernel.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/configs/davinci_all_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 026154c..94d8946 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -31,7 +31,6 @@ CONFIG_MACH_MITYOMAPL138=y
 CONFIG_MACH_OMAPL138_HAWKBOARD=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_CMA=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2017-12-31 23:39   ` David Lechner
@ 2018-01-01  0:23     ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-01  0:23 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel

On 12/31/2017 05:39 PM, David Lechner wrote:
> This introduces new drivers for arch/arm/mach-davinci. The code is based
> on the clock drivers from there and adapted to use the common clock
> framework.
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---

...

> diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> new file mode 100644
> index 0000000..780bb25
> --- /dev/null
> +++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> @@ -0,0 +1,380 @@

...

> +static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
> +	struct da8xx_cfgchip_clk *phy_clk;
> +	const char *parent_name;
> +	struct clk *parent;
> +	int ret;
> +
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
> +	if (!phy_clk)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy_clk);
> +
> +	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");

There is a mistake here. Device tree boards will fail to find "syscon".

It should be:

	/* try device tree, then fall back to platform device */
	phy_clk->regmap = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
	if (IS_ERR(phy_clk->regmap))
		phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");


> +	if (IS_ERR(phy_clk->regmap)) {
> +		dev_err(dev, "Failed to get syscon\n");
> +		return PTR_ERR(phy_clk->regmap);
> +	}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-01  0:23     ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-01  0:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/31/2017 05:39 PM, David Lechner wrote:
> This introduces new drivers for arch/arm/mach-davinci. The code is based
> on the clock drivers from there and adapted to use the common clock
> framework.
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---

...

> diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> new file mode 100644
> index 0000000..780bb25
> --- /dev/null
> +++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> @@ -0,0 +1,380 @@

...

> +static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
> +	struct da8xx_cfgchip_clk *phy_clk;
> +	const char *parent_name;
> +	struct clk *parent;
> +	int ret;
> +
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
> +	if (!phy_clk)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy_clk);
> +
> +	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");

There is a mistake here. Device tree boards will fail to find "syscon".

It should be:

	/* try device tree, then fall back to platform device */
	phy_clk->regmap = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
	if (IS_ERR(phy_clk->regmap))
		phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");


> +	if (IS_ERR(phy_clk->regmap)) {
> +		dev_err(dev, "Failed to get syscon\n");
> +		return PTR_ERR(phy_clk->regmap);
> +	}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
  2017-12-31 23:39 ` David Lechner
@ 2018-01-02 15:10   ` Adam Ford
  -1 siblings, 0 replies; 59+ messages in thread
From: Adam Ford @ 2018-01-02 15:10 UTC (permalink / raw)
  To: David Lechner; +Cc: linux-arm-kernel, Sekhar Nori, Kevin Hilman, linux-kernel

On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
> This series converts mach-davinci to use the common clock framework.
>
> Basically, this series does some cleanup and rearranging to get things
> ready for the conversion. Then there is a patch to add new driver in
> drivers/clk and finally a patch to make the conversion from the mach
> clock drivers to the new drivers.
>
> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
> that I haven't broken anything (too badly) in da850. But, I don't have
> other hardware to test.

I tested this on a DA850-EVM, but I was not able to successfully get it to boot.

It hangs during boot with no errors, oops's, or panics, but the
standard 4.15.0-rc5 from linux-stable booted just fine.

Maybe one of the TI guys will have some suggestions, but as-is, it
appears to break at least the DA850-evm.


>
> The one thing that I know I have broken is CPU frequency scaling on da850.
> I don't think it was working with device tree anyway, so I can't really test
> it with the hardware I have. I'm hoping that it will be OK to defer fixing
> it and add device tree support at the same time.
>

I agree with you that it's broken in the device tree, but I don't
think it ever worked.

> Dependencies:
> * This series applies on top of "ARM: davinici: move watchdog restart from
>   mach to drivers" [1][2]
> * On da850, you will also need a patch to prevent problems with the USB PHY
>   clocks [3]
> * Or get it all at once:
>     git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4

That is what I pulled to test.

adam

>
> [1]: https://patchwork.kernel.org/patch/10105623/
> [2]: https://patchwork.kernel.org/patch/10105613/
> [3]: https://patchwork.kernel.org/patch/10133193/
>
>
> v4 changes:
> * Basically, the whole series is new/reworked except for the first patch.
> * Instead of having an intermediate conversion of the clocks in mach-davinci,
>   new clock drivers are introduced in drivers/clk.
> * There are a few more cleanup patches added before making the conversion.
>
> v3 changes:
> * Remove leftovers from rebasing in "ARM: davinci: don't use static clk_lookup"
>   (fixes compile error)
>
> v2 changes:
> * Dropped "ARM: davinci: clean up map_io functions" - will resend as separate
>   patch series
> * Reworked remaining patches so that there is less shuffling around
>
>
>
> David Lechner (7):
>   ARM: davinci: move davinci_clk_init() to init_time
>   ARM: davinci: don't use static clk_lookup
>   ARM: davinci: fix duplicate clocks
>   ARM: davinci: remove davinci_set_refclk_rate()
>   clk: Introduce davinci clocks
>   ARM: davinci: convert to common clock framework
>   ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
>
>  arch/arm/Kconfig                            |   2 +-
>  arch/arm/configs/davinci_all_defconfig      |   1 -
>  arch/arm/mach-davinci/Kconfig               |  12 -
>  arch/arm/mach-davinci/Makefile              |   2 +-
>  arch/arm/mach-davinci/board-da830-evm.c     |  17 +-
>  arch/arm/mach-davinci/board-da850-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm355-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm355-leopard.c |   2 +-
>  arch/arm/mach-davinci/board-dm365-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm644x-evm.c    |   2 +-
>  arch/arm/mach-davinci/board-dm646x-evm.c    |  17 +-
>  arch/arm/mach-davinci/board-mityomapl138.c  |   2 +-
>  arch/arm/mach-davinci/board-neuros-osd2.c   |   2 +-
>  arch/arm/mach-davinci/board-omapl138-hawk.c |  17 +-
>  arch/arm/mach-davinci/board-sffsdr.c        |   2 +-
>  arch/arm/mach-davinci/clock.c               | 745 --------------------------
>  arch/arm/mach-davinci/clock.h               |  72 ---
>  arch/arm/mach-davinci/common.c              |   1 -
>  arch/arm/mach-davinci/da830.c               | 536 +++++--------------
>  arch/arm/mach-davinci/da850.c               | 785 ++++++----------------------
>  arch/arm/mach-davinci/da8xx-dt.c            |  17 +-
>  arch/arm/mach-davinci/davinci.h             |   4 +
>  arch/arm/mach-davinci/devices-da8xx.c       |  46 +-
>  arch/arm/mach-davinci/dm355.c               | 452 ++++------------
>  arch/arm/mach-davinci/dm365.c               | 594 ++++++---------------
>  arch/arm/mach-davinci/dm644x.c              | 401 ++++----------
>  arch/arm/mach-davinci/dm646x.c              | 451 +++++-----------
>  arch/arm/mach-davinci/include/mach/clock.h  |   3 -
>  arch/arm/mach-davinci/include/mach/common.h |   9 -
>  arch/arm/mach-davinci/include/mach/da8xx.h  |  11 +-
>  arch/arm/mach-davinci/psc.c                 | 137 -----
>  arch/arm/mach-davinci/psc.h                 |  14 -
>  arch/arm/mach-davinci/usb-da8xx.c           | 225 +-------
>  drivers/clk/Makefile                        |   1 +
>  drivers/clk/davinci/Makefile                |   3 +
>  drivers/clk/davinci/da8xx-cfgchip-clk.c     | 380 ++++++++++++++
>  drivers/clk/davinci/pll.c                   | 333 ++++++++++++
>  drivers/clk/davinci/psc.c                   | 217 ++++++++
>  include/linux/clk/davinci.h                 |  46 ++
>  include/linux/platform_data/davinci_clk.h   |  25 +
>  40 files changed, 1875 insertions(+), 3717 deletions(-)
>  delete mode 100644 arch/arm/mach-davinci/clock.c
>  delete mode 100644 arch/arm/mach-davinci/psc.c
>  create mode 100644 drivers/clk/davinci/Makefile
>  create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
>  create mode 100644 drivers/clk/davinci/pll.c
>  create mode 100644 drivers/clk/davinci/psc.c
>  create mode 100644 include/linux/clk/davinci.h
>  create mode 100644 include/linux/platform_data/davinci_clk.h
>
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2018-01-02 15:10   ` Adam Ford
  0 siblings, 0 replies; 59+ messages in thread
From: Adam Ford @ 2018-01-02 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
> This series converts mach-davinci to use the common clock framework.
>
> Basically, this series does some cleanup and rearranging to get things
> ready for the conversion. Then there is a patch to add new driver in
> drivers/clk and finally a patch to make the conversion from the mach
> clock drivers to the new drivers.
>
> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
> that I haven't broken anything (too badly) in da850. But, I don't have
> other hardware to test.

I tested this on a DA850-EVM, but I was not able to successfully get it to boot.

It hangs during boot with no errors, oops's, or panics, but the
standard 4.15.0-rc5 from linux-stable booted just fine.

Maybe one of the TI guys will have some suggestions, but as-is, it
appears to break at least the DA850-evm.


>
> The one thing that I know I have broken is CPU frequency scaling on da850.
> I don't think it was working with device tree anyway, so I can't really test
> it with the hardware I have. I'm hoping that it will be OK to defer fixing
> it and add device tree support at the same time.
>

I agree with you that it's broken in the device tree, but I don't
think it ever worked.

> Dependencies:
> * This series applies on top of "ARM: davinici: move watchdog restart from
>   mach to drivers" [1][2]
> * On da850, you will also need a patch to prevent problems with the USB PHY
>   clocks [3]
> * Or get it all at once:
>     git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4

That is what I pulled to test.

adam

>
> [1]: https://patchwork.kernel.org/patch/10105623/
> [2]: https://patchwork.kernel.org/patch/10105613/
> [3]: https://patchwork.kernel.org/patch/10133193/
>
>
> v4 changes:
> * Basically, the whole series is new/reworked except for the first patch.
> * Instead of having an intermediate conversion of the clocks in mach-davinci,
>   new clock drivers are introduced in drivers/clk.
> * There are a few more cleanup patches added before making the conversion.
>
> v3 changes:
> * Remove leftovers from rebasing in "ARM: davinci: don't use static clk_lookup"
>   (fixes compile error)
>
> v2 changes:
> * Dropped "ARM: davinci: clean up map_io functions" - will resend as separate
>   patch series
> * Reworked remaining patches so that there is less shuffling around
>
>
>
> David Lechner (7):
>   ARM: davinci: move davinci_clk_init() to init_time
>   ARM: davinci: don't use static clk_lookup
>   ARM: davinci: fix duplicate clocks
>   ARM: davinci: remove davinci_set_refclk_rate()
>   clk: Introduce davinci clocks
>   ARM: davinci: convert to common clock framework
>   ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
>
>  arch/arm/Kconfig                            |   2 +-
>  arch/arm/configs/davinci_all_defconfig      |   1 -
>  arch/arm/mach-davinci/Kconfig               |  12 -
>  arch/arm/mach-davinci/Makefile              |   2 +-
>  arch/arm/mach-davinci/board-da830-evm.c     |  17 +-
>  arch/arm/mach-davinci/board-da850-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm355-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm355-leopard.c |   2 +-
>  arch/arm/mach-davinci/board-dm365-evm.c     |   2 +-
>  arch/arm/mach-davinci/board-dm644x-evm.c    |   2 +-
>  arch/arm/mach-davinci/board-dm646x-evm.c    |  17 +-
>  arch/arm/mach-davinci/board-mityomapl138.c  |   2 +-
>  arch/arm/mach-davinci/board-neuros-osd2.c   |   2 +-
>  arch/arm/mach-davinci/board-omapl138-hawk.c |  17 +-
>  arch/arm/mach-davinci/board-sffsdr.c        |   2 +-
>  arch/arm/mach-davinci/clock.c               | 745 --------------------------
>  arch/arm/mach-davinci/clock.h               |  72 ---
>  arch/arm/mach-davinci/common.c              |   1 -
>  arch/arm/mach-davinci/da830.c               | 536 +++++--------------
>  arch/arm/mach-davinci/da850.c               | 785 ++++++----------------------
>  arch/arm/mach-davinci/da8xx-dt.c            |  17 +-
>  arch/arm/mach-davinci/davinci.h             |   4 +
>  arch/arm/mach-davinci/devices-da8xx.c       |  46 +-
>  arch/arm/mach-davinci/dm355.c               | 452 ++++------------
>  arch/arm/mach-davinci/dm365.c               | 594 ++++++---------------
>  arch/arm/mach-davinci/dm644x.c              | 401 ++++----------
>  arch/arm/mach-davinci/dm646x.c              | 451 +++++-----------
>  arch/arm/mach-davinci/include/mach/clock.h  |   3 -
>  arch/arm/mach-davinci/include/mach/common.h |   9 -
>  arch/arm/mach-davinci/include/mach/da8xx.h  |  11 +-
>  arch/arm/mach-davinci/psc.c                 | 137 -----
>  arch/arm/mach-davinci/psc.h                 |  14 -
>  arch/arm/mach-davinci/usb-da8xx.c           | 225 +-------
>  drivers/clk/Makefile                        |   1 +
>  drivers/clk/davinci/Makefile                |   3 +
>  drivers/clk/davinci/da8xx-cfgchip-clk.c     | 380 ++++++++++++++
>  drivers/clk/davinci/pll.c                   | 333 ++++++++++++
>  drivers/clk/davinci/psc.c                   | 217 ++++++++
>  include/linux/clk/davinci.h                 |  46 ++
>  include/linux/platform_data/davinci_clk.h   |  25 +
>  40 files changed, 1875 insertions(+), 3717 deletions(-)
>  delete mode 100644 arch/arm/mach-davinci/clock.c
>  delete mode 100644 arch/arm/mach-davinci/psc.c
>  create mode 100644 drivers/clk/davinci/Makefile
>  create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
>  create mode 100644 drivers/clk/davinci/pll.c
>  create mode 100644 drivers/clk/davinci/psc.c
>  create mode 100644 include/linux/clk/davinci.h
>  create mode 100644 include/linux/platform_data/davinci_clk.h
>
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
  2018-01-02 15:10   ` Adam Ford
@ 2018-01-02 17:10     ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 17:10 UTC (permalink / raw)
  To: Adam Ford; +Cc: linux-arm-kernel, Sekhar Nori, Kevin Hilman, linux-kernel

On 01/02/2018 09:10 AM, Adam Ford wrote:
> On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
>> This series converts mach-davinci to use the common clock framework.
>>
>> Basically, this series does some cleanup and rearranging to get things
>> ready for the conversion. Then there is a patch to add new driver in
>> drivers/clk and finally a patch to make the conversion from the mach
>> clock drivers to the new drivers.
>>
>> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
>> that I haven't broken anything (too badly) in da850. But, I don't have
>> other hardware to test.
> 
> I tested this on a DA850-EVM, but I was not able to successfully get it to boot.
> 
> It hangs during boot with no errors, oops's, or panics, but the
> standard 4.15.0-rc5 from linux-stable booted just fine.
> 
> Maybe one of the TI guys will have some suggestions, but as-is, it
> appears to break at least the DA850-evm.
> 

Thanks for testing. Unfortunately, the only hardware I have is the LEGO
MINDSTORMS, so I will have to rely on others to help with the debugging.
If you or anyone else with one of these boards can make the time, please
compile with:

CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y

and add "earlyprintk" to the kernel command line options. You may need to
select a different UART for this depending on your board. I think UART1 is
the default in the kernel configuration.

On da850 devices comment out the line:

	clk_set_parent(clk, pll1_sysclk2_clk);

in da850.c when doing earlyprintk, otherwise the UART1 and UART2 clock source
will change during boot and cause garbled output after a point.

>>
>> The one thing that I know I have broken is CPU frequency scaling on da850.
>> I don't think it was working with device tree anyway, so I can't really test
>> it with the hardware I have. I'm hoping that it will be OK to defer fixing
>> it and add device tree support at the same time.
>>
> 
> I agree with you that it's broken in the device tree, but I don't
> think it ever worked.
> 
>> Dependencies:
>> * This series applies on top of "ARM: davinici: move watchdog restart from
>>    mach to drivers" [1][2]
>> * On da850, you will also need a patch to prevent problems with the USB PHY
>>    clocks [3]
>> * Or get it all at once:
>>      git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4
> 
> That is what I pulled to test.
> 
> adam
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2018-01-02 17:10     ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 17:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/02/2018 09:10 AM, Adam Ford wrote:
> On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
>> This series converts mach-davinci to use the common clock framework.
>>
>> Basically, this series does some cleanup and rearranging to get things
>> ready for the conversion. Then there is a patch to add new driver in
>> drivers/clk and finally a patch to make the conversion from the mach
>> clock drivers to the new drivers.
>>
>> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
>> that I haven't broken anything (too badly) in da850. But, I don't have
>> other hardware to test.
> 
> I tested this on a DA850-EVM, but I was not able to successfully get it to boot.
> 
> It hangs during boot with no errors, oops's, or panics, but the
> standard 4.15.0-rc5 from linux-stable booted just fine.
> 
> Maybe one of the TI guys will have some suggestions, but as-is, it
> appears to break at least the DA850-evm.
> 

Thanks for testing. Unfortunately, the only hardware I have is the LEGO
MINDSTORMS, so I will have to rely on others to help with the debugging.
If you or anyone else with one of these boards can make the time, please
compile with:

CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y

and add "earlyprintk" to the kernel command line options. You may need to
select a different UART for this depending on your board. I think UART1 is
the default in the kernel configuration.

On da850 devices comment out the line:

	clk_set_parent(clk, pll1_sysclk2_clk);

in da850.c when doing earlyprintk, otherwise the UART1 and UART2 clock source
will change during boot and cause garbled output after a point.

>>
>> The one thing that I know I have broken is CPU frequency scaling on da850.
>> I don't think it was working with device tree anyway, so I can't really test
>> it with the hardware I have. I'm hoping that it will be OK to defer fixing
>> it and add device tree support at the same time.
>>
> 
> I agree with you that it's broken in the device tree, but I don't
> think it ever worked.
> 
>> Dependencies:
>> * This series applies on top of "ARM: davinici: move watchdog restart from
>>    mach to drivers" [1][2]
>> * On da850, you will also need a patch to prevent problems with the USB PHY
>>    clocks [3]
>> * Or get it all at once:
>>      git fetch https://github.com/dlech/ev3dev-kernel.git common-clk-v4
> 
> That is what I pulled to test.
> 
> adam
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
  2018-01-02 17:10     ` David Lechner
@ 2018-01-02 18:31       ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 18:31 UTC (permalink / raw)
  To: Adam Ford; +Cc: linux-arm-kernel, Sekhar Nori, Kevin Hilman, linux-kernel

On 01/02/2018 11:10 AM, David Lechner wrote:
> 
> and add "earlyprintk" to the kernel command line options.

The "clk_ignore_unused" command line option could be useful as well

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2018-01-02 18:31       ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/02/2018 11:10 AM, David Lechner wrote:
> 
> and add "earlyprintk" to the kernel command line options.

The "clk_ignore_unused" command line option could be useful as well

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2017-12-31 23:39   ` David Lechner
@ 2018-01-02 21:31     ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel, linux-clk,
	Michael Turquette, Stephen Boyd

Forgot to cc linux-clk, so doing that now...


On 12/31/2017 05:39 PM, David Lechner wrote:
> This introduces new drivers for arch/arm/mach-davinci. The code is based
> on the clock drivers from there and adapted to use the common clock
> framework.
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>   drivers/clk/Makefile                      |   1 +
>   drivers/clk/davinci/Makefile              |   3 +
>   drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380 ++++++++++++++++++++++++++++++
>   drivers/clk/davinci/pll.c                 | 333 ++++++++++++++++++++++++++
>   drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
>   include/linux/clk/davinci.h               |  46 ++++
>   include/linux/platform_data/davinci_clk.h |  25 ++
>   7 files changed, 1005 insertions(+)
>   create mode 100644 drivers/clk/davinci/Makefile
>   create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
>   create mode 100644 drivers/clk/davinci/pll.c
>   create mode 100644 drivers/clk/davinci/psc.c
>   create mode 100644 include/linux/clk/davinci.h
>   create mode 100644 include/linux/platform_data/davinci_clk.h
> 
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index f7f761b..c865fd0 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -60,6 +60,7 @@ obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
>   obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
>   obj-y					+= bcm/
>   obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
> +obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
>   obj-$(CONFIG_H8300)			+= h8300/
>   obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
>   obj-y					+= imgtec/
> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
> new file mode 100644
> index 0000000..5efbdcd
> --- /dev/null
> +++ b/drivers/clk/davinci/Makefile
> @@ -0,0 +1,3 @@
> +obj-$(CONFIG_PHY_DA8XX_USB) += da8xx-cfgchip-clk.o
> +obj-y += pll.o
> +obj-y += psc.o
> \ No newline at end of file
> diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> new file mode 100644
> index 0000000..780bb25
> --- /dev/null
> +++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * da8xx-cfgchip-clk - TI DaVinci DA8xx CFGCHIP clocks driver
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * This driver exposes the USB PHY clocks on DA8xx/AM18xx/OMAP-L13x SoCs.
> + * The clocks consist of two muxes and a PLL. The USB 2.0 PHY mux and PLL are
> + * combined into a single clock in Linux. The USB 1.0 PHY clock just consists
> + * of a mux. These clocks are controlled through CFGCHIP2, which is accessed
> + * as a syscon regmap since it is shared with other devices.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/mfd/da8xx-cfgchip.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/platform_data/davinci_clk.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +/**
> + * da8xx_cfgchip_clk
> + * @usb0_hw: The USB 2.0 PHY clock (mux + PLL)
> + * @usb1_hw: The USB 1.1 PHY clock (mux)
> + * @usb0_clk: The USB 2.0 subsystem PSC clock
> + * @regmap: The CFGCHIP syscon regmap
> + */
> +struct da8xx_cfgchip_clk {
> +	struct clk_hw usb0_hw;
> +	struct clk_hw usb1_hw;
> +	struct clk *usb0_clk;
> +	struct regmap *regmap;
> +};
> +
> +/* The USB 2.0 PHY can use either USB_REFCLKIN or AUXCLK */
> +enum usb0_phy_clk_parent {
> +	USB20_PHY_CLK_PARENT_USB_REFCLKIN,
> +	USB20_PHY_CLK_PARENT_PLL0_AUX,
> +};
> +
> +/* The USB 1.1 PHY can use either the PLL output from the USB 2.0 PHY or
> + * USB_REFCLKIN
> + */
> +enum usb1_phy_clk_parent {
> +	USB1_PHY_CLK_PARENT_USB_REFCLKIN,
> +	USB1_PHY_CLK_PARENT_USB0_PHY_PLL,
> +};
> +
> +/* --- USB 2.0 PHY clock --- */
> +
> +static int usb0_phy_clk_prepare(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +
> +	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
> +	 * PHY clock enable, but since clk_prepare() can't be called in an
> +	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
> +	 */
> +	return clk_prepare(clk->usb0_clk);
> +}
> +
> +static void usb0_phy_clk_unprepare(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +
> +	clk_unprepare(clk->usb0_clk);
> +}
> +
> +static int usb0_phy_clk_enable(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +	int ret;
> +
> +	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
> +	 * temporaily. It can be turned back off once the PLL is locked.
> +	 */
> +	clk_enable(clk->usb0_clk);
> +
> +	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
> +	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
> +	 */
> +	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
> +	val = CFGCHIP2_PHY_PLLON;
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +	ret = regmap_read_poll_timeout(clk->regmap, CFGCHIP(2), val,
> +				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
> +
> +	clk_disable(clk->usb0_clk);
> +
> +	return ret;
> +}
> +
> +static void usb0_phy_clk_disable(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int val;
> +
> +	val = CFGCHIP2_PHYPWRDN;
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
> +}
> +
> +static unsigned long usb0_phy_clk_recalc_rate(struct clk_hw *hw,
> +					      unsigned long parent_rate)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +
> +	/* The parent clock rate must be one of the following */
> +	mask = CFGCHIP2_REFFREQ_MASK;
> +	switch (parent_rate) {
> +	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:
> +		return 0;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	/* USB 2.0 PLL always supplies 48MHz */
> +	return 48000000;
> +}
> +
> +static long usb0_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> +				    unsigned long *parent_rate)
> +{
> +	return 48000000;
> +}
> +
> +static int usb0_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +
> +	/* Set the mux depending on the parent clock. */
> +	mask = CFGCHIP2_USB2PHYCLKMUX;
> +	switch (index) {
> +	case USB20_PHY_CLK_PARENT_USB_REFCLKIN:
> +		val = 0;
> +		break;
> +	case USB20_PHY_CLK_PARENT_PLL0_AUX:
> +		val = CFGCHIP2_USB2PHYCLKMUX;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	return 0;
> +}
> +
> +static u8 usb0_phy_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int val;
> +
> +	regmap_read(clk->regmap, CFGCHIP(2), &val);
> +
> +	if (val & CFGCHIP2_USB2PHYCLKMUX)
> +		return USB20_PHY_CLK_PARENT_PLL0_AUX;
> +
> +	return USB20_PHY_CLK_PARENT_USB_REFCLKIN;
> +}
> +
> +static const struct clk_ops usb0_phy_clk_ops = {
> +	.prepare	= usb0_phy_clk_prepare,
> +	.unprepare	= usb0_phy_clk_unprepare,
> +	.enable		= usb0_phy_clk_enable,
> +	.disable	= usb0_phy_clk_disable,
> +	.recalc_rate	= usb0_phy_clk_recalc_rate,
> +	.round_rate	= usb0_phy_clk_round_rate,
> +	.set_parent	= usb0_phy_clk_set_parent,
> +	.get_parent	= usb0_phy_clk_get_parent,
> +};
> +
> +static const char * const usb0_phy_clk_parent_names[] = {
> +	[USB20_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
> +	[USB20_PHY_CLK_PARENT_PLL0_AUX]		= "pll0_aux_clk",
> +};
> +
> +static const struct clk_init_data usb0_phy_clk_init_data = {
> +	.name		= "usb0_phy_clk",
> +	.ops		= &usb0_phy_clk_ops,
> +	.parent_names	= usb0_phy_clk_parent_names,
> +	.num_parents	= ARRAY_SIZE(usb0_phy_clk_parent_names),
> +};
> +
> +/* --- USB 1.1 PHY clock --- */
> +
> +static int usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
> +	unsigned int mask, val;
> +
> +	/* Set the USB 1.1 PHY clock mux based on the parent clock. */
> +	mask = CFGCHIP2_USB1PHYCLKMUX;
> +	switch (index) {
> +	case USB1_PHY_CLK_PARENT_USB_REFCLKIN:
> +		val = CFGCHIP2_USB1PHYCLKMUX;
> +		break;
> +	case USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
> +		val = 0;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	return 0;
> +}
> +
> +static u8 usb1_phy_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
> +	unsigned int val;
> +
> +	regmap_read(clk->regmap, CFGCHIP(2), &val);
> +
> +	if (val & CFGCHIP2_USB1PHYCLKMUX)
> +		return USB1_PHY_CLK_PARENT_USB_REFCLKIN;
> +
> +	return USB1_PHY_CLK_PARENT_USB0_PHY_PLL;
> +}
> +
> +static const struct clk_ops usb1_phy_clk_ops = {
> +	.set_parent	= usb1_phy_clk_set_parent,
> +	.get_parent	= usb1_phy_clk_get_parent,
> +};
> +
> +static const char * const usb1_phy_clk_parent_names[] = {
> +	[USB1_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
> +	[USB1_PHY_CLK_PARENT_USB0_PHY_PLL]	= "usb0_phy_clk",
> +};
> +
> +static struct clk_init_data usb1_phy_clk_init_data = {
> +	.name		= "usb1_phy_clk",
> +	.ops		= &usb1_phy_clk_ops,
> +	.parent_names	= usb1_phy_clk_parent_names,
> +	.num_parents	= ARRAY_SIZE(usb1_phy_clk_parent_names),
> +};
> +
> +/* --- platform driver --- */
> +
> +static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
> +	struct da8xx_cfgchip_clk *phy_clk;
> +	const char *parent_name;
> +	struct clk *parent;
> +	int ret;
> +
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
> +	if (!phy_clk)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy_clk);
> +
> +	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");
> +	if (IS_ERR(phy_clk->regmap)) {
> +		dev_err(dev, "Failed to get syscon\n");
> +		return PTR_ERR(phy_clk->regmap);
> +	}
> +
> +	/* USB 2.0 subsystem PSC clock - needed to lock PLL */
> +	phy_clk->usb0_clk = clk_get(dev, "usb20");
> +	if (IS_ERR(phy_clk->usb0_clk)) {
> +		dev_err(dev, "Failed to get usb20 clock\n");
> +		return PTR_ERR(phy_clk->usb0_clk);
> +	}
> +
> +	phy_clk->usb0_hw.init = &usb0_phy_clk_init_data;
> +	ret = devm_clk_hw_register(dev, &phy_clk->usb0_hw);
> +	if (ret) {
> +		dev_err(dev, "Failed to register usb0_phy_clk\n");
> +		return ret;
> +	}
> +
> +	phy_clk->usb1_hw.init = &usb1_phy_clk_init_data;
> +	ret = devm_clk_hw_register(dev, &phy_clk->usb1_hw);
> +	if (ret) {
> +		dev_err(dev, "Failed to register usb1_phy_clk\n");
> +		return ret;
> +	}
> +
> +	parent_name = pdata->usb0_use_refclkin ? "usb_refclkin" : "pll0_aux";
> +	parent = devm_clk_get(dev, parent_name);
> +	if (IS_ERR(parent)) {
> +		dev_err(dev, "Failed to get usb0 parent clock %s\n",
> +			parent_name);
> +		return PTR_ERR(parent);
> +	}
> +
> +	ret = clk_set_parent(phy_clk->usb0_hw.clk, parent);
> +	if (ret) {
> +		dev_err(dev, "Failed to set usb0 parent clock to %s\n",
> +			parent_name);
> +		return ret;
> +	}
> +
> +	clk_hw_register_clkdev(&phy_clk->usb0_hw, NULL, "da8xx-cfgchip-clk");
> +
> +	parent_name = pdata->usb1_use_refclkin ? "usb_refclkin" : "usb0_phy_clk";
> +	parent = devm_clk_get(dev, parent_name);
> +	if (IS_ERR(parent)) {
> +		dev_err(dev, "Failed to get usb1 parent clock %s\n",
> +			parent_name);
> +		return PTR_ERR(parent);
> +	}
> +
> +	ret = clk_set_parent(phy_clk->usb1_hw.clk, parent);
> +	if (ret) {
> +		dev_err(dev, "Failed to set usb1 parent clock to %s\n",
> +			parent_name);
> +		return ret;
> +	}
> +
> +	clk_hw_register_clkdev(&phy_clk->usb0_hw, "usb20_phy", "da8xx-usb-phy");
> +	clk_hw_register_clkdev(&phy_clk->usb1_hw, "usb11_phy", "da8xx-usb-phy");
> +
> +	return 0;
> +}
> +
> +static struct platform_driver da8xx_cfgchip_clk_driver = {
> +	.probe = da8xx_cfgchip_clk_probe,
> +	.driver = {
> +		.name = "da8xx-cfgchip-clk",
> +	},
> +};
> +module_platform_driver(da8xx_cfgchip_clk_driver);
> +
> +MODULE_ALIAS("platform:da8xx-cfgchip-clk");
> +MODULE_AUTHOR("David Lechner <david@lechnology.com>");
> +MODULE_DESCRIPTION("TI DA8xx CFGCHIP clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
> new file mode 100644
> index 0000000..035cd91
> --- /dev/null
> +++ b/drivers/clk/davinci/pll.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PLL clock driver for Davinci devices
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * Based on drivers/clk/keystone/pll.c
> + * Copyright (C) 2013 Texas Instruments Inc.
> + *	Murali Karicheri <m-karicheri2@ti.com>
> + *	Santosh Shilimkar <santosh.shilimkar@ti.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#define REVID		0x000
> +#define PLLCTL		0x100
> +#define OCSEL		0x104
> +#define PLLSECCTL	0x108
> +#define PLLM		0x110
> +#define PREDIV		0x114
> +#define PLLDIV1		0x118
> +#define PLLDIV2		0x11c
> +#define PLLDIV3		0x120
> +#define OSCDIV		0x124
> +#define POSTDIV		0x128
> +#define BPDIV		0x12c
> +#define PLLCMD		0x138
> +#define PLLSTAT		0x13c
> +#define ALNCTL		0x140
> +#define DCHANGE		0x144
> +#define CKEN		0x148
> +#define CKSTAT		0x14c
> +#define SYSTAT		0x150
> +#define PLLDIV4		0x160
> +#define PLLDIV5		0x164
> +#define PLLDIV6		0x168
> +#define PLLDIV7		0x16c
> +#define PLLDIV8		0x170
> +#define PLLDIV9		0x174
> +
> +#define PLLM_MASK		0x1f
> +#define PREDIV_RATIO_MASK	0x1f
> +#define PLLDIV_RATIO_WIDTH	5
> +#define PLLDIV_ENABLE_SHIFT	15
> +#define OSCDIV_RATIO_WIDTH	5
> +#define POSTDIV_RATIO_MASK	0x1f
> +#define BPDIV_RATIO_SHIFT	0
> +#define BPDIV_RATIO_WIDTH	5
> +#define CKEN_OBSCLK_SHIFT	1
> +#define CKEN_AUXEN_SHIFT	0
> +
> +/**
> + * struct davinci_pll_clk - Main PLL clock
> + * @hw: clk_hw for the pll
> + * @base: Base memory address
> + * @parent_rate: Saved parent rate used by some child clocks
> + */
> +struct davinci_pll_clk {
> +	struct clk_hw hw;
> +	void __iomem *base;
> +};
> +
> +#define to_davinci_pll_clk(_hw) container_of((_hw), struct davinci_pll_clk, hw)
> +
> +static unsigned long davinci_pll_clk_recalc(struct clk_hw *hw,
> +					    unsigned long parent_rate)
> +{
> +	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
> +	unsigned long rate = parent_rate;
> +	u32 prediv, mult, postdiv;
> +
> +	prediv = readl(pll->base + PREDIV) & PREDIV_RATIO_MASK;
> +	mult = readl(pll->base + PLLM) & PLLM_MASK;
> +	postdiv = readl(pll->base + POSTDIV) & POSTDIV_RATIO_MASK;
> +
> +	rate /= prediv + 1;
> +	rate *= mult + 1;
> +	rate /= postdiv + 1;
> +
> +	return rate;
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +#include <linux/debugfs.h>
> +
> +#define DEBUG_REG(n)	\
> +{			\
> +	.name	= #n,	\
> +	.offset	= n,	\
> +}
> +
> +static const struct debugfs_reg32 davinci_pll_regs[] = {
> +	DEBUG_REG(REVID),
> +	DEBUG_REG(PLLCTL),
> +	DEBUG_REG(OCSEL),
> +	DEBUG_REG(PLLSECCTL),
> +	DEBUG_REG(PLLM),
> +	DEBUG_REG(PREDIV),
> +	DEBUG_REG(PLLDIV1),
> +	DEBUG_REG(PLLDIV2),
> +	DEBUG_REG(PLLDIV3),
> +	DEBUG_REG(OSCDIV),
> +	DEBUG_REG(POSTDIV),
> +	DEBUG_REG(BPDIV),
> +	DEBUG_REG(PLLCMD),
> +	DEBUG_REG(PLLSTAT),
> +	DEBUG_REG(ALNCTL),
> +	DEBUG_REG(DCHANGE),
> +	DEBUG_REG(CKEN),
> +	DEBUG_REG(CKSTAT),
> +	DEBUG_REG(SYSTAT),
> +	DEBUG_REG(PLLDIV4),
> +	DEBUG_REG(PLLDIV5),
> +	DEBUG_REG(PLLDIV6),
> +	DEBUG_REG(PLLDIV7),
> +	DEBUG_REG(PLLDIV8),
> +	DEBUG_REG(PLLDIV9),
> +};
> +
> +static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
> +{
> +	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
> +	struct debugfs_regset32 *regset;
> +	struct dentry *d;
> +
> +	regset = kzalloc(sizeof(regset), GFP_KERNEL);
> +	if (!regset)
> +		return -ENOMEM;
> +
> +	regset->regs = davinci_pll_regs;
> +	regset->nregs = ARRAY_SIZE(davinci_pll_regs);
> +	regset->base = pll->base;
> +
> +	d = debugfs_create_regset32("registers", 0400, dentry, regset);
> +	if (IS_ERR(d)) {
> +		kfree(regset);
> +		return PTR_ERR(d);
> +	}
> +
> +	return 0;
> +}
> +#else
> +#define davinci_pll_debug_init NULL
> +#endif
> +
> +static const struct clk_ops davinci_pll_clk_ops = {
> +	.recalc_rate	= davinci_pll_clk_recalc,
> +	.debug_init	= davinci_pll_debug_init,
> +};
> +
> +/**
> + * davinci_pll_clk_register - Register a PLL clock
> + * @name: The clock name
> + * @parent_name: The parent clock name
> + * @base: The PLL's memory region
> + */
> +struct clk *davinci_pll_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base)
> +{
> +	struct clk_init_data init;
> +	struct davinci_pll_clk *pll;
> +	struct clk *clk;
> +
> +	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +	if (!pll)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = name;
> +	init.ops = &davinci_pll_clk_ops;
> +	init.parent_names = (parent_name ? &parent_name : NULL);
> +	init.num_parents = (parent_name ? 1 : 0);
> +
> +	pll->base = base;
> +	pll->hw.init = &init;
> +
> +	clk = clk_register(NULL, &pll->hw);
> +	if (IS_ERR(clk))
> +		kfree(pll);
> +
> +	return clk;
> +}
> +
> +struct davinci_pll_aux_clk {
> +	struct clk_hw hw;
> +	struct davinci_pll_clk *pll;
> +};
> +
> +/**
> + * davinci_pll_aux_clk_register - Register bypass clock (AUXCLK)
> + * @name: The clock name
> + * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
> + *               the PLL)
> + * @base: The PLL memory region
> + */
> +struct clk *davinci_pll_aux_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base)
> +{
> +	return clk_register_gate(NULL, name, parent_name, 0, base + CKEN,
> +				 CKEN_AUXEN_SHIFT, 0, NULL);
> +}
> +
> +/**
> + * davinci_pll_bpdiv_clk_register - Register bypass divider clock (SYSCLKBP)
> + * @name: The clock name
> + * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
> + *               the PLL)
> + * @base: The PLL memory region
> + */
> +struct clk *davinci_pll_bpdiv_clk_register(const char *name,
> +					   const char *parent_name,
> +					   void __iomem *base)
> +{
> +	return clk_register_divider(NULL, name, parent_name, 0, base + BPDIV,
> +				    BPDIV_RATIO_SHIFT, BPDIV_RATIO_WIDTH,
> +				    CLK_DIVIDER_READ_ONLY, NULL);
> +}
> +
> +/**
> + * davinci_pll_obs_clk_register - Register oscillator divider clock (OBSCLK)
> + * @name: The clock name
> + * @parent_names: The parent clock names
> + * @num_parents: The number of paren clocks
> + * @base: The PLL memory region
> + * @table: A table of values cooresponding to the parent clocks (see OCSEL
> + *         register in SRM for values)
> + */
> +struct clk *davinci_pll_obs_clk_register(const char *name,
> +					 const char * const *parent_names,
> +					 u8 num_parents,
> +					 void __iomem *base,
> +					 u32 *table)
> +{
> +	struct clk_mux *mux;
> +	struct clk_gate *gate;
> +	struct clk_divider *divider;
> +	struct clk *clk;
> +
> +	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
> +	if (!mux)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mux->reg = base + OCSEL;
> +	mux->table = table;
> +
> +	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +	if (!gate) {
> +		kfree(mux);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	gate->reg = base + CKEN;
> +	gate->bit_idx = CKEN_OBSCLK_SHIFT;
> +
> +	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
> +	if (!divider) {
> +		kfree(gate);
> +		kfree(mux);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	divider->reg = base + OSCDIV;
> +	divider->width = OSCDIV_RATIO_WIDTH;
> +
> +	clk = clk_register_composite(NULL, name, parent_names, num_parents,
> +				     &mux->hw, &clk_mux_ops,
> +				     &divider->hw, &clk_divider_ops,
> +				     &gate->hw, &clk_gate_ops, 0);
> +	if (IS_ERR(clk)) {
> +		kfree(divider);
> +		kfree(gate);
> +		kfree(mux);
> +	}
> +
> +	return clk;
> +}
> +
> +/**
> + * davinci_pll_div_clk_register - Register a PLLDIV (SYSCLK) clock
> + * @name: The clock name
> + * @parent_name: The parent clock name
> + * @base: The PLL memory region
> + * @id: The id of the divider (n in PLLDIVn)
> + */
> +struct clk *davinci_pll_div_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base,
> +					 u32 id)
> +{
> +	const char * const *parent_names = (parent_name ? &parent_name : NULL);
> +	int num_parents = (parent_name ? 1 : 0);
> +	struct clk_gate *gate;
> +	struct clk_divider *divider;
> +	struct clk *clk;
> +	u32 reg;
> +
> +	/* PLLDIVn registers are not entirely consecutive */
> +	if (id < 4)
> +		reg = PLLDIV1 + 4 * (id - 1);
> +	else
> +		reg = PLLDIV4 + 4 * (id - 4);
> +
> +	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +	if (!gate)
> +		return ERR_PTR(-ENOMEM);
> +
> +	gate->reg = base + reg;
> +	gate->bit_idx = PLLDIV_ENABLE_SHIFT;
> +
> +	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
> +	if (!divider) {
> +		kfree(gate);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	divider->reg = base + reg;
> +	divider->width = PLLDIV_RATIO_WIDTH;
> +	divider->flags = CLK_DIVIDER_READ_ONLY;
> +
> +	clk = clk_register_composite(NULL, name, parent_names, num_parents,
> +				     NULL, NULL, &divider->hw, &clk_divider_ops,
> +				     &gate->hw, &clk_gate_ops, 0);
> +	if (IS_ERR(clk)) {
> +		kfree(divider);
> +		kfree(gate);
> +	}
> +
> +	return clk;
> +}
> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
> new file mode 100644
> index 0000000..8ae85ee
> --- /dev/null
> +++ b/drivers/clk/davinci/psc.c
> @@ -0,0 +1,217 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x PSC controllers
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * Based on: drivers/clk/keystone/gate.c
> + * Copyright (C) 2013 Texas Instruments.
> + *	Murali Karicheri <m-karicheri2@ti.com>
> + *	Santosh Shilimkar <santosh.shilimkar@ti.com>
> + *
> + * And: arch/arm/mach-davinci/psc.c
> + * Copyright (C) 2006 Texas Instruments.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +/* PSC register offsets */
> +#define EPCPR			0x070
> +#define PTCMD			0x120
> +#define PTSTAT			0x128
> +#define PDSTAT			0x200
> +#define PDCTL			0x300
> +#define MDSTAT			0x800
> +#define MDCTL			0xa00
> +
> +/* PSC module states */
> +enum davinci_psc_state {
> +	PSC_STATE_SWRSTDISABLE	= 0,
> +	PSC_STATE_SYNCRST	= 1,
> +	PSC_STATE_DISABLE	= 2,
> +	PSC_STATE_ENABLE	= 3,
> +};
> +
> +#define MDSTAT_STATE_MASK	0x3f
> +#define MDSTAT_MCKOUT		BIT(12)
> +#define PDSTAT_STATE_MASK	0x1f
> +#define MDCTL_FORCE		BIT(31)
> +#define MDCTL_LRESET		BIT(8)
> +#define PDCTL_EPCGOOD		BIT(8)
> +#define PDCTL_NEXT		BIT(0)
> +
> +/**
> + * struct davinci_psc_clk - PSC clock structure
> + * @hw: clk_hw for the psc
> + * @psc_data: PSC driver specific data
> + * @lpsc: Local PSC number (module id)
> + * @pd: Power domain
> + */
> +struct davinci_psc_clk {
> +	struct clk_hw hw;
> +	void __iomem *base;
> +	u32 lpsc;
> +	u32 pd;
> +};
> +
> +#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
> +
> +static void psc_config(struct davinci_psc_clk *psc,
> +		       enum davinci_psc_state next_state)
> +{
> +	u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
> +
> +	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
> +	mdctl &= ~MDSTAT_STATE_MASK;
> +	mdctl |= next_state;
> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
> +	 * dsp here. Is this really needed?
> +	 */
> +	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
> +
> +	pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
> +	if ((pdstat & PDSTAT_STATE_MASK) == 0) {
> +		pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
> +		pdctl |= PDCTL_NEXT;
> +		writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
> +
> +		ptcmd = BIT(psc->pd);
> +		writel(ptcmd, psc->base + PTCMD);
> +
> +		do {
> +			epcpr = __raw_readl(psc->base + EPCPR);
> +		} while (!(epcpr & BIT(psc->pd)));
> +
> +		pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
> +		pdctl |= PDCTL_EPCGOOD;
> +		__raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
> +	} else {
> +		ptcmd = BIT(psc->pd);
> +		writel(ptcmd, psc->base + PTCMD);
> +	}
> +
> +	do {
> +		ptstat = readl(psc->base + PTSTAT);
> +	} while (ptstat & BIT(psc->pd));
> +
> +	do {
> +		mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
> +	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
> +}
> +
> +static int davinci_psc_clk_enable(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +
> +	psc_config(psc, PSC_STATE_ENABLE);
> +
> +	return 0;
> +}
> +
> +static void davinci_psc_clk_disable(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +
> +	psc_config(psc, PSC_STATE_DISABLE);
> +}
> +
> +static int davinci_psc_clk_is_enabled(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +	u32 mdstat;
> +
> +	mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
> +
> +	return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
> +}
> +
> +static const struct clk_ops davinci_psc_clk_ops = {
> +	.enable		= davinci_psc_clk_enable,
> +	.disable	= davinci_psc_clk_disable,
> +	.is_enabled	= davinci_psc_clk_is_enabled,
> +};
> +
> +/**
> + * davinci_psc_clk_register - register psc clock
> + * @dev: device that is registering this clock
> + * @name: name of this clock
> + * @parent_name: name of clock's parent
> + * @base: memory mapped register for the PSC
> + * @lpsc: local PSC number
> + * @pd: power domain
> + */
> +struct clk *davinci_psc_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base,
> +				     u32 lpsc, u32 pd)
> +{
> +	struct clk_init_data init;
> +	struct davinci_psc_clk *psc;
> +	struct clk *clk;
> +
> +	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> +	if (!psc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = name;
> +	init.ops = &davinci_psc_clk_ops;
> +	init.flags = 0;
> +	init.parent_names = (parent_name ? &parent_name : NULL);
> +	init.num_parents = (parent_name ? 1 : 0);
> +
> +	psc->base = base;
> +	psc->hw.init = &init;
> +	psc->lpsc = lpsc;
> +	psc->pd = pd;
> +
> +	clk = clk_register(NULL, &psc->hw);
> +	if (IS_ERR(clk))
> +		kfree(psc);
> +
> +	return clk;
> +}
> +
> +/* FIXME: This needs to be converted to a reset controller. But, the reset
> + * framework is currently device tree only.
> + */
> +
> +DEFINE_SPINLOCK(davinci_psc_reset_lock);
> +
> +static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
> +{
> +	unsigned long flags;
> +	u32 mdctl;
> +
> +	if (IS_ERR_OR_NULL(psc))
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(&davinci_psc_reset_lock, flags);
> +	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
> +	if (reset)
> +		mdctl &= ~MDCTL_LRESET;
> +	else
> +		mdctl |= MDCTL_LRESET;
> +	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
> +	spin_unlock_irqrestore(&davinci_psc_reset_lock, flags);
> +
> +	return 0;
> +}
> +
> +int davinci_clk_reset_assert(struct clk *clk)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> +	return davinci_psc_clk_reset(psc, true);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_assert);
> +
> +int davinci_clk_reset_deassert(struct clk *clk)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> +	return davinci_psc_clk_reset(psc, false);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_deassert);
> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
> new file mode 100644
> index 0000000..c5d2181
> --- /dev/null
> +++ b/include/linux/clk/davinci.h
> @@ -0,0 +1,46 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TI Davinci clocks
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +#ifndef __LINUX_CLK_DAVINCI_H__
> +#define __LINUX_CLK_DAVINCI_H__
> +
> +#include <linux/clk-provider.h>
> +#include <linux/types.h>
> +
> +struct clk *davinci_pll_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base);
> +struct clk *davinci_pll_aux_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base);
> +struct clk *davinci_pll_bpdiv_clk_register(const char *name,
> +					   const char *parent_name,
> +					   void __iomem *base);
> +struct clk *davinci_pll_obs_clk_register(const char *name,
> +					 const char * const *parent_names,
> +					 u8 num_parents,
> +					 void __iomem *base,
> +					 u32 *table);
> +struct clk *davinci_pll_div_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base,
> +					 u32 id);
> +struct clk *davinci_psc_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base,
> +				     u32 lpsc, u32 pd);
> +
> +/* convience macros for board declaration files */
> +#define EXT_CLK(n, r) clk_register_fixed_rate(NULL, (n), NULL, 0, (r))
> +#define FIX_CLK(n, p) clk_register_fixed_factor(NULL, (n), (p), 0, 1, 1)
> +#define PLL_CLK davinci_pll_clk_register
> +#define PLL_DIV_CLK davinci_pll_div_clk_register
> +#define PLL_AUX_CLK davinci_pll_aux_clk_register
> +#define PLL_BP_CLK davinci_pll_bpdiv_clk_register
> +#define PLL_OBS_CLK davinci_pll_obs_clk_register
> +#define PSC_CLK davinci_psc_clk_register
> +
> +#endif /* __LINUX_CLK_DAVINCI_H__ */
> diff --git a/include/linux/platform_data/davinci_clk.h b/include/linux/platform_data/davinci_clk.h
> new file mode 100644
> index 0000000..7576ace
> --- /dev/null
> +++ b/include/linux/platform_data/davinci_clk.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TI DaVinci Clock support
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +
> +#ifndef __PLATFORM_DATA_DAVINCI_CLK_H
> +#define __PLATFORM_DATA_DAVINCI_CLK_H
> +
> +#include <linux/types.h>
> +
> +/**
> + * da8xx_cfgchip_clk_data - DA8xx CFGCHIP clock platform data
> + * @usb0_use_refclkin: when true, use USB_REFCLKIN, otherwise use AUXCLK for
> + *                     USB 2.0 PHY clock
> + * @usb1_use_refclkin: when true, use USB_REFCLKIN, otherwise use USB 2.0 PHY
> + *                     PLL for USB 1.1 PHY clock
> + */
> +struct da8xx_cfgchip_clk_data {
> +	bool usb0_use_refclkin;
> +	bool usb1_use_refclkin;
> +};
> +
> +#endif /* __PLATFORM_DATA_DAVINCI_CLK_H */
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-02 21:31     ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-02 21:31 UTC (permalink / raw)
  To: linux-arm-kernel

Forgot to cc linux-clk, so doing that now...


On 12/31/2017 05:39 PM, David Lechner wrote:
> This introduces new drivers for arch/arm/mach-davinci. The code is based
> on the clock drivers from there and adapted to use the common clock
> framework.
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>   drivers/clk/Makefile                      |   1 +
>   drivers/clk/davinci/Makefile              |   3 +
>   drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380 ++++++++++++++++++++++++++++++
>   drivers/clk/davinci/pll.c                 | 333 ++++++++++++++++++++++++++
>   drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
>   include/linux/clk/davinci.h               |  46 ++++
>   include/linux/platform_data/davinci_clk.h |  25 ++
>   7 files changed, 1005 insertions(+)
>   create mode 100644 drivers/clk/davinci/Makefile
>   create mode 100644 drivers/clk/davinci/da8xx-cfgchip-clk.c
>   create mode 100644 drivers/clk/davinci/pll.c
>   create mode 100644 drivers/clk/davinci/psc.c
>   create mode 100644 include/linux/clk/davinci.h
>   create mode 100644 include/linux/platform_data/davinci_clk.h
> 
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index f7f761b..c865fd0 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -60,6 +60,7 @@ obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
>   obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
>   obj-y					+= bcm/
>   obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
> +obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
>   obj-$(CONFIG_H8300)			+= h8300/
>   obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
>   obj-y					+= imgtec/
> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
> new file mode 100644
> index 0000000..5efbdcd
> --- /dev/null
> +++ b/drivers/clk/davinci/Makefile
> @@ -0,0 +1,3 @@
> +obj-$(CONFIG_PHY_DA8XX_USB) += da8xx-cfgchip-clk.o
> +obj-y += pll.o
> +obj-y += psc.o
> \ No newline at end of file
> diff --git a/drivers/clk/davinci/da8xx-cfgchip-clk.c b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> new file mode 100644
> index 0000000..780bb25
> --- /dev/null
> +++ b/drivers/clk/davinci/da8xx-cfgchip-clk.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * da8xx-cfgchip-clk - TI DaVinci DA8xx CFGCHIP clocks driver
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * This driver exposes the USB PHY clocks on DA8xx/AM18xx/OMAP-L13x SoCs.
> + * The clocks consist of two muxes and a PLL. The USB 2.0 PHY mux and PLL are
> + * combined into a single clock in Linux. The USB 1.0 PHY clock just consists
> + * of a mux. These clocks are controlled through CFGCHIP2, which is accessed
> + * as a syscon regmap since it is shared with other devices.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/mfd/da8xx-cfgchip.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/platform_data/davinci_clk.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +/**
> + * da8xx_cfgchip_clk
> + * @usb0_hw: The USB 2.0 PHY clock (mux + PLL)
> + * @usb1_hw: The USB 1.1 PHY clock (mux)
> + * @usb0_clk: The USB 2.0 subsystem PSC clock
> + * @regmap: The CFGCHIP syscon regmap
> + */
> +struct da8xx_cfgchip_clk {
> +	struct clk_hw usb0_hw;
> +	struct clk_hw usb1_hw;
> +	struct clk *usb0_clk;
> +	struct regmap *regmap;
> +};
> +
> +/* The USB 2.0 PHY can use either USB_REFCLKIN or AUXCLK */
> +enum usb0_phy_clk_parent {
> +	USB20_PHY_CLK_PARENT_USB_REFCLKIN,
> +	USB20_PHY_CLK_PARENT_PLL0_AUX,
> +};
> +
> +/* The USB 1.1 PHY can use either the PLL output from the USB 2.0 PHY or
> + * USB_REFCLKIN
> + */
> +enum usb1_phy_clk_parent {
> +	USB1_PHY_CLK_PARENT_USB_REFCLKIN,
> +	USB1_PHY_CLK_PARENT_USB0_PHY_PLL,
> +};
> +
> +/* --- USB 2.0 PHY clock --- */
> +
> +static int usb0_phy_clk_prepare(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +
> +	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
> +	 * PHY clock enable, but since clk_prepare() can't be called in an
> +	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
> +	 */
> +	return clk_prepare(clk->usb0_clk);
> +}
> +
> +static void usb0_phy_clk_unprepare(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +
> +	clk_unprepare(clk->usb0_clk);
> +}
> +
> +static int usb0_phy_clk_enable(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +	int ret;
> +
> +	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
> +	 * temporaily. It can be turned back off once the PLL is locked.
> +	 */
> +	clk_enable(clk->usb0_clk);
> +
> +	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
> +	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
> +	 */
> +	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
> +	val = CFGCHIP2_PHY_PLLON;
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +	ret = regmap_read_poll_timeout(clk->regmap, CFGCHIP(2), val,
> +				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
> +
> +	clk_disable(clk->usb0_clk);
> +
> +	return ret;
> +}
> +
> +static void usb0_phy_clk_disable(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int val;
> +
> +	val = CFGCHIP2_PHYPWRDN;
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
> +}
> +
> +static unsigned long usb0_phy_clk_recalc_rate(struct clk_hw *hw,
> +					      unsigned long parent_rate)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +
> +	/* The parent clock rate must be one of the following */
> +	mask = CFGCHIP2_REFFREQ_MASK;
> +	switch (parent_rate) {
> +	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:
> +		return 0;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	/* USB 2.0 PLL always supplies 48MHz */
> +	return 48000000;
> +}
> +
> +static long usb0_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> +				    unsigned long *parent_rate)
> +{
> +	return 48000000;
> +}
> +
> +static int usb0_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int mask, val;
> +
> +	/* Set the mux depending on the parent clock. */
> +	mask = CFGCHIP2_USB2PHYCLKMUX;
> +	switch (index) {
> +	case USB20_PHY_CLK_PARENT_USB_REFCLKIN:
> +		val = 0;
> +		break;
> +	case USB20_PHY_CLK_PARENT_PLL0_AUX:
> +		val = CFGCHIP2_USB2PHYCLKMUX;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	return 0;
> +}
> +
> +static u8 usb0_phy_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb0_hw);
> +	unsigned int val;
> +
> +	regmap_read(clk->regmap, CFGCHIP(2), &val);
> +
> +	if (val & CFGCHIP2_USB2PHYCLKMUX)
> +		return USB20_PHY_CLK_PARENT_PLL0_AUX;
> +
> +	return USB20_PHY_CLK_PARENT_USB_REFCLKIN;
> +}
> +
> +static const struct clk_ops usb0_phy_clk_ops = {
> +	.prepare	= usb0_phy_clk_prepare,
> +	.unprepare	= usb0_phy_clk_unprepare,
> +	.enable		= usb0_phy_clk_enable,
> +	.disable	= usb0_phy_clk_disable,
> +	.recalc_rate	= usb0_phy_clk_recalc_rate,
> +	.round_rate	= usb0_phy_clk_round_rate,
> +	.set_parent	= usb0_phy_clk_set_parent,
> +	.get_parent	= usb0_phy_clk_get_parent,
> +};
> +
> +static const char * const usb0_phy_clk_parent_names[] = {
> +	[USB20_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
> +	[USB20_PHY_CLK_PARENT_PLL0_AUX]		= "pll0_aux_clk",
> +};
> +
> +static const struct clk_init_data usb0_phy_clk_init_data = {
> +	.name		= "usb0_phy_clk",
> +	.ops		= &usb0_phy_clk_ops,
> +	.parent_names	= usb0_phy_clk_parent_names,
> +	.num_parents	= ARRAY_SIZE(usb0_phy_clk_parent_names),
> +};
> +
> +/* --- USB 1.1 PHY clock --- */
> +
> +static int usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
> +	unsigned int mask, val;
> +
> +	/* Set the USB 1.1 PHY clock mux based on the parent clock. */
> +	mask = CFGCHIP2_USB1PHYCLKMUX;
> +	switch (index) {
> +	case USB1_PHY_CLK_PARENT_USB_REFCLKIN:
> +		val = CFGCHIP2_USB1PHYCLKMUX;
> +		break;
> +	case USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
> +		val = 0;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
> +
> +	return 0;
> +}
> +
> +static u8 usb1_phy_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct da8xx_cfgchip_clk *clk =
> +			container_of(hw, struct da8xx_cfgchip_clk, usb1_hw);
> +	unsigned int val;
> +
> +	regmap_read(clk->regmap, CFGCHIP(2), &val);
> +
> +	if (val & CFGCHIP2_USB1PHYCLKMUX)
> +		return USB1_PHY_CLK_PARENT_USB_REFCLKIN;
> +
> +	return USB1_PHY_CLK_PARENT_USB0_PHY_PLL;
> +}
> +
> +static const struct clk_ops usb1_phy_clk_ops = {
> +	.set_parent	= usb1_phy_clk_set_parent,
> +	.get_parent	= usb1_phy_clk_get_parent,
> +};
> +
> +static const char * const usb1_phy_clk_parent_names[] = {
> +	[USB1_PHY_CLK_PARENT_USB_REFCLKIN]	= "usb_refclkin",
> +	[USB1_PHY_CLK_PARENT_USB0_PHY_PLL]	= "usb0_phy_clk",
> +};
> +
> +static struct clk_init_data usb1_phy_clk_init_data = {
> +	.name		= "usb1_phy_clk",
> +	.ops		= &usb1_phy_clk_ops,
> +	.parent_names	= usb1_phy_clk_parent_names,
> +	.num_parents	= ARRAY_SIZE(usb1_phy_clk_parent_names),
> +};
> +
> +/* --- platform driver --- */
> +
> +static int da8xx_cfgchip_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct da8xx_cfgchip_clk_data *pdata = dev->platform_data;
> +	struct da8xx_cfgchip_clk *phy_clk;
> +	const char *parent_name;
> +	struct clk *parent;
> +	int ret;
> +
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	phy_clk = devm_kzalloc(dev, sizeof(*phy_clk), GFP_KERNEL);
> +	if (!phy_clk)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy_clk);
> +
> +	phy_clk->regmap = syscon_regmap_lookup_by_pdevname("syscon");
> +	if (IS_ERR(phy_clk->regmap)) {
> +		dev_err(dev, "Failed to get syscon\n");
> +		return PTR_ERR(phy_clk->regmap);
> +	}
> +
> +	/* USB 2.0 subsystem PSC clock - needed to lock PLL */
> +	phy_clk->usb0_clk = clk_get(dev, "usb20");
> +	if (IS_ERR(phy_clk->usb0_clk)) {
> +		dev_err(dev, "Failed to get usb20 clock\n");
> +		return PTR_ERR(phy_clk->usb0_clk);
> +	}
> +
> +	phy_clk->usb0_hw.init = &usb0_phy_clk_init_data;
> +	ret = devm_clk_hw_register(dev, &phy_clk->usb0_hw);
> +	if (ret) {
> +		dev_err(dev, "Failed to register usb0_phy_clk\n");
> +		return ret;
> +	}
> +
> +	phy_clk->usb1_hw.init = &usb1_phy_clk_init_data;
> +	ret = devm_clk_hw_register(dev, &phy_clk->usb1_hw);
> +	if (ret) {
> +		dev_err(dev, "Failed to register usb1_phy_clk\n");
> +		return ret;
> +	}
> +
> +	parent_name = pdata->usb0_use_refclkin ? "usb_refclkin" : "pll0_aux";
> +	parent = devm_clk_get(dev, parent_name);
> +	if (IS_ERR(parent)) {
> +		dev_err(dev, "Failed to get usb0 parent clock %s\n",
> +			parent_name);
> +		return PTR_ERR(parent);
> +	}
> +
> +	ret = clk_set_parent(phy_clk->usb0_hw.clk, parent);
> +	if (ret) {
> +		dev_err(dev, "Failed to set usb0 parent clock to %s\n",
> +			parent_name);
> +		return ret;
> +	}
> +
> +	clk_hw_register_clkdev(&phy_clk->usb0_hw, NULL, "da8xx-cfgchip-clk");
> +
> +	parent_name = pdata->usb1_use_refclkin ? "usb_refclkin" : "usb0_phy_clk";
> +	parent = devm_clk_get(dev, parent_name);
> +	if (IS_ERR(parent)) {
> +		dev_err(dev, "Failed to get usb1 parent clock %s\n",
> +			parent_name);
> +		return PTR_ERR(parent);
> +	}
> +
> +	ret = clk_set_parent(phy_clk->usb1_hw.clk, parent);
> +	if (ret) {
> +		dev_err(dev, "Failed to set usb1 parent clock to %s\n",
> +			parent_name);
> +		return ret;
> +	}
> +
> +	clk_hw_register_clkdev(&phy_clk->usb0_hw, "usb20_phy", "da8xx-usb-phy");
> +	clk_hw_register_clkdev(&phy_clk->usb1_hw, "usb11_phy", "da8xx-usb-phy");
> +
> +	return 0;
> +}
> +
> +static struct platform_driver da8xx_cfgchip_clk_driver = {
> +	.probe = da8xx_cfgchip_clk_probe,
> +	.driver = {
> +		.name = "da8xx-cfgchip-clk",
> +	},
> +};
> +module_platform_driver(da8xx_cfgchip_clk_driver);
> +
> +MODULE_ALIAS("platform:da8xx-cfgchip-clk");
> +MODULE_AUTHOR("David Lechner <david@lechnology.com>");
> +MODULE_DESCRIPTION("TI DA8xx CFGCHIP clock driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
> new file mode 100644
> index 0000000..035cd91
> --- /dev/null
> +++ b/drivers/clk/davinci/pll.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PLL clock driver for Davinci devices
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * Based on drivers/clk/keystone/pll.c
> + * Copyright (C) 2013 Texas Instruments Inc.
> + *	Murali Karicheri <m-karicheri2@ti.com>
> + *	Santosh Shilimkar <santosh.shilimkar@ti.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#define REVID		0x000
> +#define PLLCTL		0x100
> +#define OCSEL		0x104
> +#define PLLSECCTL	0x108
> +#define PLLM		0x110
> +#define PREDIV		0x114
> +#define PLLDIV1		0x118
> +#define PLLDIV2		0x11c
> +#define PLLDIV3		0x120
> +#define OSCDIV		0x124
> +#define POSTDIV		0x128
> +#define BPDIV		0x12c
> +#define PLLCMD		0x138
> +#define PLLSTAT		0x13c
> +#define ALNCTL		0x140
> +#define DCHANGE		0x144
> +#define CKEN		0x148
> +#define CKSTAT		0x14c
> +#define SYSTAT		0x150
> +#define PLLDIV4		0x160
> +#define PLLDIV5		0x164
> +#define PLLDIV6		0x168
> +#define PLLDIV7		0x16c
> +#define PLLDIV8		0x170
> +#define PLLDIV9		0x174
> +
> +#define PLLM_MASK		0x1f
> +#define PREDIV_RATIO_MASK	0x1f
> +#define PLLDIV_RATIO_WIDTH	5
> +#define PLLDIV_ENABLE_SHIFT	15
> +#define OSCDIV_RATIO_WIDTH	5
> +#define POSTDIV_RATIO_MASK	0x1f
> +#define BPDIV_RATIO_SHIFT	0
> +#define BPDIV_RATIO_WIDTH	5
> +#define CKEN_OBSCLK_SHIFT	1
> +#define CKEN_AUXEN_SHIFT	0
> +
> +/**
> + * struct davinci_pll_clk - Main PLL clock
> + * @hw: clk_hw for the pll
> + * @base: Base memory address
> + * @parent_rate: Saved parent rate used by some child clocks
> + */
> +struct davinci_pll_clk {
> +	struct clk_hw hw;
> +	void __iomem *base;
> +};
> +
> +#define to_davinci_pll_clk(_hw) container_of((_hw), struct davinci_pll_clk, hw)
> +
> +static unsigned long davinci_pll_clk_recalc(struct clk_hw *hw,
> +					    unsigned long parent_rate)
> +{
> +	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
> +	unsigned long rate = parent_rate;
> +	u32 prediv, mult, postdiv;
> +
> +	prediv = readl(pll->base + PREDIV) & PREDIV_RATIO_MASK;
> +	mult = readl(pll->base + PLLM) & PLLM_MASK;
> +	postdiv = readl(pll->base + POSTDIV) & POSTDIV_RATIO_MASK;
> +
> +	rate /= prediv + 1;
> +	rate *= mult + 1;
> +	rate /= postdiv + 1;
> +
> +	return rate;
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +#include <linux/debugfs.h>
> +
> +#define DEBUG_REG(n)	\
> +{			\
> +	.name	= #n,	\
> +	.offset	= n,	\
> +}
> +
> +static const struct debugfs_reg32 davinci_pll_regs[] = {
> +	DEBUG_REG(REVID),
> +	DEBUG_REG(PLLCTL),
> +	DEBUG_REG(OCSEL),
> +	DEBUG_REG(PLLSECCTL),
> +	DEBUG_REG(PLLM),
> +	DEBUG_REG(PREDIV),
> +	DEBUG_REG(PLLDIV1),
> +	DEBUG_REG(PLLDIV2),
> +	DEBUG_REG(PLLDIV3),
> +	DEBUG_REG(OSCDIV),
> +	DEBUG_REG(POSTDIV),
> +	DEBUG_REG(BPDIV),
> +	DEBUG_REG(PLLCMD),
> +	DEBUG_REG(PLLSTAT),
> +	DEBUG_REG(ALNCTL),
> +	DEBUG_REG(DCHANGE),
> +	DEBUG_REG(CKEN),
> +	DEBUG_REG(CKSTAT),
> +	DEBUG_REG(SYSTAT),
> +	DEBUG_REG(PLLDIV4),
> +	DEBUG_REG(PLLDIV5),
> +	DEBUG_REG(PLLDIV6),
> +	DEBUG_REG(PLLDIV7),
> +	DEBUG_REG(PLLDIV8),
> +	DEBUG_REG(PLLDIV9),
> +};
> +
> +static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
> +{
> +	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
> +	struct debugfs_regset32 *regset;
> +	struct dentry *d;
> +
> +	regset = kzalloc(sizeof(regset), GFP_KERNEL);
> +	if (!regset)
> +		return -ENOMEM;
> +
> +	regset->regs = davinci_pll_regs;
> +	regset->nregs = ARRAY_SIZE(davinci_pll_regs);
> +	regset->base = pll->base;
> +
> +	d = debugfs_create_regset32("registers", 0400, dentry, regset);
> +	if (IS_ERR(d)) {
> +		kfree(regset);
> +		return PTR_ERR(d);
> +	}
> +
> +	return 0;
> +}
> +#else
> +#define davinci_pll_debug_init NULL
> +#endif
> +
> +static const struct clk_ops davinci_pll_clk_ops = {
> +	.recalc_rate	= davinci_pll_clk_recalc,
> +	.debug_init	= davinci_pll_debug_init,
> +};
> +
> +/**
> + * davinci_pll_clk_register - Register a PLL clock
> + * @name: The clock name
> + * @parent_name: The parent clock name
> + * @base: The PLL's memory region
> + */
> +struct clk *davinci_pll_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base)
> +{
> +	struct clk_init_data init;
> +	struct davinci_pll_clk *pll;
> +	struct clk *clk;
> +
> +	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +	if (!pll)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = name;
> +	init.ops = &davinci_pll_clk_ops;
> +	init.parent_names = (parent_name ? &parent_name : NULL);
> +	init.num_parents = (parent_name ? 1 : 0);
> +
> +	pll->base = base;
> +	pll->hw.init = &init;
> +
> +	clk = clk_register(NULL, &pll->hw);
> +	if (IS_ERR(clk))
> +		kfree(pll);
> +
> +	return clk;
> +}
> +
> +struct davinci_pll_aux_clk {
> +	struct clk_hw hw;
> +	struct davinci_pll_clk *pll;
> +};
> +
> +/**
> + * davinci_pll_aux_clk_register - Register bypass clock (AUXCLK)
> + * @name: The clock name
> + * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
> + *               the PLL)
> + * @base: The PLL memory region
> + */
> +struct clk *davinci_pll_aux_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base)
> +{
> +	return clk_register_gate(NULL, name, parent_name, 0, base + CKEN,
> +				 CKEN_AUXEN_SHIFT, 0, NULL);
> +}
> +
> +/**
> + * davinci_pll_bpdiv_clk_register - Register bypass divider clock (SYSCLKBP)
> + * @name: The clock name
> + * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
> + *               the PLL)
> + * @base: The PLL memory region
> + */
> +struct clk *davinci_pll_bpdiv_clk_register(const char *name,
> +					   const char *parent_name,
> +					   void __iomem *base)
> +{
> +	return clk_register_divider(NULL, name, parent_name, 0, base + BPDIV,
> +				    BPDIV_RATIO_SHIFT, BPDIV_RATIO_WIDTH,
> +				    CLK_DIVIDER_READ_ONLY, NULL);
> +}
> +
> +/**
> + * davinci_pll_obs_clk_register - Register oscillator divider clock (OBSCLK)
> + * @name: The clock name
> + * @parent_names: The parent clock names
> + * @num_parents: The number of paren clocks
> + * @base: The PLL memory region
> + * @table: A table of values cooresponding to the parent clocks (see OCSEL
> + *         register in SRM for values)
> + */
> +struct clk *davinci_pll_obs_clk_register(const char *name,
> +					 const char * const *parent_names,
> +					 u8 num_parents,
> +					 void __iomem *base,
> +					 u32 *table)
> +{
> +	struct clk_mux *mux;
> +	struct clk_gate *gate;
> +	struct clk_divider *divider;
> +	struct clk *clk;
> +
> +	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
> +	if (!mux)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mux->reg = base + OCSEL;
> +	mux->table = table;
> +
> +	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +	if (!gate) {
> +		kfree(mux);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	gate->reg = base + CKEN;
> +	gate->bit_idx = CKEN_OBSCLK_SHIFT;
> +
> +	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
> +	if (!divider) {
> +		kfree(gate);
> +		kfree(mux);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	divider->reg = base + OSCDIV;
> +	divider->width = OSCDIV_RATIO_WIDTH;
> +
> +	clk = clk_register_composite(NULL, name, parent_names, num_parents,
> +				     &mux->hw, &clk_mux_ops,
> +				     &divider->hw, &clk_divider_ops,
> +				     &gate->hw, &clk_gate_ops, 0);
> +	if (IS_ERR(clk)) {
> +		kfree(divider);
> +		kfree(gate);
> +		kfree(mux);
> +	}
> +
> +	return clk;
> +}
> +
> +/**
> + * davinci_pll_div_clk_register - Register a PLLDIV (SYSCLK) clock
> + * @name: The clock name
> + * @parent_name: The parent clock name
> + * @base: The PLL memory region
> + * @id: The id of the divider (n in PLLDIVn)
> + */
> +struct clk *davinci_pll_div_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base,
> +					 u32 id)
> +{
> +	const char * const *parent_names = (parent_name ? &parent_name : NULL);
> +	int num_parents = (parent_name ? 1 : 0);
> +	struct clk_gate *gate;
> +	struct clk_divider *divider;
> +	struct clk *clk;
> +	u32 reg;
> +
> +	/* PLLDIVn registers are not entirely consecutive */
> +	if (id < 4)
> +		reg = PLLDIV1 + 4 * (id - 1);
> +	else
> +		reg = PLLDIV4 + 4 * (id - 4);
> +
> +	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +	if (!gate)
> +		return ERR_PTR(-ENOMEM);
> +
> +	gate->reg = base + reg;
> +	gate->bit_idx = PLLDIV_ENABLE_SHIFT;
> +
> +	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
> +	if (!divider) {
> +		kfree(gate);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	divider->reg = base + reg;
> +	divider->width = PLLDIV_RATIO_WIDTH;
> +	divider->flags = CLK_DIVIDER_READ_ONLY;
> +
> +	clk = clk_register_composite(NULL, name, parent_names, num_parents,
> +				     NULL, NULL, &divider->hw, &clk_divider_ops,
> +				     &gate->hw, &clk_gate_ops, 0);
> +	if (IS_ERR(clk)) {
> +		kfree(divider);
> +		kfree(gate);
> +	}
> +
> +	return clk;
> +}
> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
> new file mode 100644
> index 0000000..8ae85ee
> --- /dev/null
> +++ b/drivers/clk/davinci/psc.c
> @@ -0,0 +1,217 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x PSC controllers
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + *
> + * Based on: drivers/clk/keystone/gate.c
> + * Copyright (C) 2013 Texas Instruments.
> + *	Murali Karicheri <m-karicheri2@ti.com>
> + *	Santosh Shilimkar <santosh.shilimkar@ti.com>
> + *
> + * And: arch/arm/mach-davinci/psc.c
> + * Copyright (C) 2006 Texas Instruments.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +/* PSC register offsets */
> +#define EPCPR			0x070
> +#define PTCMD			0x120
> +#define PTSTAT			0x128
> +#define PDSTAT			0x200
> +#define PDCTL			0x300
> +#define MDSTAT			0x800
> +#define MDCTL			0xa00
> +
> +/* PSC module states */
> +enum davinci_psc_state {
> +	PSC_STATE_SWRSTDISABLE	= 0,
> +	PSC_STATE_SYNCRST	= 1,
> +	PSC_STATE_DISABLE	= 2,
> +	PSC_STATE_ENABLE	= 3,
> +};
> +
> +#define MDSTAT_STATE_MASK	0x3f
> +#define MDSTAT_MCKOUT		BIT(12)
> +#define PDSTAT_STATE_MASK	0x1f
> +#define MDCTL_FORCE		BIT(31)
> +#define MDCTL_LRESET		BIT(8)
> +#define PDCTL_EPCGOOD		BIT(8)
> +#define PDCTL_NEXT		BIT(0)
> +
> +/**
> + * struct davinci_psc_clk - PSC clock structure
> + * @hw: clk_hw for the psc
> + * @psc_data: PSC driver specific data
> + * @lpsc: Local PSC number (module id)
> + * @pd: Power domain
> + */
> +struct davinci_psc_clk {
> +	struct clk_hw hw;
> +	void __iomem *base;
> +	u32 lpsc;
> +	u32 pd;
> +};
> +
> +#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
> +
> +static void psc_config(struct davinci_psc_clk *psc,
> +		       enum davinci_psc_state next_state)
> +{
> +	u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
> +
> +	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
> +	mdctl &= ~MDSTAT_STATE_MASK;
> +	mdctl |= next_state;
> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
> +	 * dsp here. Is this really needed?
> +	 */
> +	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
> +
> +	pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
> +	if ((pdstat & PDSTAT_STATE_MASK) == 0) {
> +		pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
> +		pdctl |= PDCTL_NEXT;
> +		writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
> +
> +		ptcmd = BIT(psc->pd);
> +		writel(ptcmd, psc->base + PTCMD);
> +
> +		do {
> +			epcpr = __raw_readl(psc->base + EPCPR);
> +		} while (!(epcpr & BIT(psc->pd)));
> +
> +		pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
> +		pdctl |= PDCTL_EPCGOOD;
> +		__raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
> +	} else {
> +		ptcmd = BIT(psc->pd);
> +		writel(ptcmd, psc->base + PTCMD);
> +	}
> +
> +	do {
> +		ptstat = readl(psc->base + PTSTAT);
> +	} while (ptstat & BIT(psc->pd));
> +
> +	do {
> +		mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
> +	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
> +}
> +
> +static int davinci_psc_clk_enable(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +
> +	psc_config(psc, PSC_STATE_ENABLE);
> +
> +	return 0;
> +}
> +
> +static void davinci_psc_clk_disable(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +
> +	psc_config(psc, PSC_STATE_DISABLE);
> +}
> +
> +static int davinci_psc_clk_is_enabled(struct clk_hw *hw)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
> +	u32 mdstat;
> +
> +	mdstat = readl(psc->base + MDSTAT + 4 * psc->lpsc);
> +
> +	return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
> +}
> +
> +static const struct clk_ops davinci_psc_clk_ops = {
> +	.enable		= davinci_psc_clk_enable,
> +	.disable	= davinci_psc_clk_disable,
> +	.is_enabled	= davinci_psc_clk_is_enabled,
> +};
> +
> +/**
> + * davinci_psc_clk_register - register psc clock
> + * @dev: device that is registering this clock
> + * @name: name of this clock
> + * @parent_name: name of clock's parent
> + * @base: memory mapped register for the PSC
> + * @lpsc: local PSC number
> + * @pd: power domain
> + */
> +struct clk *davinci_psc_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base,
> +				     u32 lpsc, u32 pd)
> +{
> +	struct clk_init_data init;
> +	struct davinci_psc_clk *psc;
> +	struct clk *clk;
> +
> +	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> +	if (!psc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = name;
> +	init.ops = &davinci_psc_clk_ops;
> +	init.flags = 0;
> +	init.parent_names = (parent_name ? &parent_name : NULL);
> +	init.num_parents = (parent_name ? 1 : 0);
> +
> +	psc->base = base;
> +	psc->hw.init = &init;
> +	psc->lpsc = lpsc;
> +	psc->pd = pd;
> +
> +	clk = clk_register(NULL, &psc->hw);
> +	if (IS_ERR(clk))
> +		kfree(psc);
> +
> +	return clk;
> +}
> +
> +/* FIXME: This needs to be converted to a reset controller. But, the reset
> + * framework is currently device tree only.
> + */
> +
> +DEFINE_SPINLOCK(davinci_psc_reset_lock);
> +
> +static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
> +{
> +	unsigned long flags;
> +	u32 mdctl;
> +
> +	if (IS_ERR_OR_NULL(psc))
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(&davinci_psc_reset_lock, flags);
> +	mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
> +	if (reset)
> +		mdctl &= ~MDCTL_LRESET;
> +	else
> +		mdctl |= MDCTL_LRESET;
> +	writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
> +	spin_unlock_irqrestore(&davinci_psc_reset_lock, flags);
> +
> +	return 0;
> +}
> +
> +int davinci_clk_reset_assert(struct clk *clk)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> +	return davinci_psc_clk_reset(psc, true);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_assert);
> +
> +int davinci_clk_reset_deassert(struct clk *clk)
> +{
> +	struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> +	return davinci_psc_clk_reset(psc, false);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_deassert);
> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
> new file mode 100644
> index 0000000..c5d2181
> --- /dev/null
> +++ b/include/linux/clk/davinci.h
> @@ -0,0 +1,46 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TI Davinci clocks
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +#ifndef __LINUX_CLK_DAVINCI_H__
> +#define __LINUX_CLK_DAVINCI_H__
> +
> +#include <linux/clk-provider.h>
> +#include <linux/types.h>
> +
> +struct clk *davinci_pll_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base);
> +struct clk *davinci_pll_aux_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base);
> +struct clk *davinci_pll_bpdiv_clk_register(const char *name,
> +					   const char *parent_name,
> +					   void __iomem *base);
> +struct clk *davinci_pll_obs_clk_register(const char *name,
> +					 const char * const *parent_names,
> +					 u8 num_parents,
> +					 void __iomem *base,
> +					 u32 *table);
> +struct clk *davinci_pll_div_clk_register(const char *name,
> +					 const char *parent_name,
> +					 void __iomem *base,
> +					 u32 id);
> +struct clk *davinci_psc_clk_register(const char *name,
> +				     const char *parent_name,
> +				     void __iomem *base,
> +				     u32 lpsc, u32 pd);
> +
> +/* convience macros for board declaration files */
> +#define EXT_CLK(n, r) clk_register_fixed_rate(NULL, (n), NULL, 0, (r))
> +#define FIX_CLK(n, p) clk_register_fixed_factor(NULL, (n), (p), 0, 1, 1)
> +#define PLL_CLK davinci_pll_clk_register
> +#define PLL_DIV_CLK davinci_pll_div_clk_register
> +#define PLL_AUX_CLK davinci_pll_aux_clk_register
> +#define PLL_BP_CLK davinci_pll_bpdiv_clk_register
> +#define PLL_OBS_CLK davinci_pll_obs_clk_register
> +#define PSC_CLK davinci_psc_clk_register
> +
> +#endif /* __LINUX_CLK_DAVINCI_H__ */
> diff --git a/include/linux/platform_data/davinci_clk.h b/include/linux/platform_data/davinci_clk.h
> new file mode 100644
> index 0000000..7576ace
> --- /dev/null
> +++ b/include/linux/platform_data/davinci_clk.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TI DaVinci Clock support
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +
> +#ifndef __PLATFORM_DATA_DAVINCI_CLK_H
> +#define __PLATFORM_DATA_DAVINCI_CLK_H
> +
> +#include <linux/types.h>
> +
> +/**
> + * da8xx_cfgchip_clk_data - DA8xx CFGCHIP clock platform data
> + * @usb0_use_refclkin: when true, use USB_REFCLKIN, otherwise use AUXCLK for
> + *                     USB 2.0 PHY clock
> + * @usb1_use_refclkin: when true, use USB_REFCLKIN, otherwise use USB 2.0 PHY
> + *                     PLL for USB 1.1 PHY clock
> + */
> +struct da8xx_cfgchip_clk_data {
> +	bool usb0_use_refclkin;
> +	bool usb1_use_refclkin;
> +};
> +
> +#endif /* __PLATFORM_DATA_DAVINCI_CLK_H */
> 

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
  2018-01-02 15:10   ` Adam Ford
@ 2018-01-03 16:57     ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-03 16:57 UTC (permalink / raw)
  To: Adam Ford, David Lechner; +Cc: linux-arm-kernel, Kevin Hilman, linux-kernel

On Tuesday 02 January 2018 08:40 PM, Adam Ford wrote:
> On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
>> This series converts macreqh-davinci to use the common clock framework.
>>
>> Basically, this series does some cleanup and rearranging to get things
>> ready for the conversion. Then there is a patch to add new driver in
>> drivers/clk and finally a patch to make the conversion from the mach
>> clock drivers to the new drivers.
>>
>> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
>> that I haven't broken anything (too badly) in da850. But, I don't have
>> other hardware to test.
> 
> I tested this on a DA850-EVM, but I was not able to successfully get it to boot.
> 
> It hangs during boot with no errors, oops's, or panics, but the
> standard 4.15.0-rc5 from linux-stable booted just fine.
> 
> Maybe one of the TI guys will have some suggestions, but as-is, it
> appears to break at least the DA850-evm.

I haven't gotten to looking into this series yet. Should happen by
Friday this week.
>> The one thing that I know I have broken is CPU frequency scaling on da850.
>> I don't think it was working with device tree anyway, so I can't really test
>> it with the hardware I have. I'm hoping that it will be OK to defer fixing
>> it and add device tree support at the same time.
>>
> 
> I agree with you that it's broken in the device tree, but I don't
> think it ever worked.

It was working with legacy board file method. Its not supported with DT,
yes. Most probably, the generic cpufreq-dt support needs to be used for
the DT case.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 0/7] ARM: davinci: convert to common clock framework​
@ 2018-01-03 16:57     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-03 16:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 02 January 2018 08:40 PM, Adam Ford wrote:
> On Sun, Dec 31, 2017 at 5:39 PM, David Lechner <david@lechnology.com> wrote:
>> This series converts macreqh-davinci to use the common clock framework.
>>
>> Basically, this series does some cleanup and rearranging to get things
>> ready for the conversion. Then there is a patch to add new driver in
>> drivers/clk and finally a patch to make the conversion from the mach
>> clock drivers to the new drivers.
>>
>> I have tested this on LEGO MINDSTORMS EV3 (TI AM1808), so I am confident
>> that I haven't broken anything (too badly) in da850. But, I don't have
>> other hardware to test.
> 
> I tested this on a DA850-EVM, but I was not able to successfully get it to boot.
> 
> It hangs during boot with no errors, oops's, or panics, but the
> standard 4.15.0-rc5 from linux-stable booted just fine.
> 
> Maybe one of the TI guys will have some suggestions, but as-is, it
> appears to break at least the DA850-evm.

I haven't gotten to looking into this series yet. Should happen by
Friday this week.
>> The one thing that I know I have broken is CPU frequency scaling on da850.
>> I don't think it was working with device tree anyway, so I can't really test
>> it with the hardware I have. I'm hoping that it will be OK to defer fixing
>> it and add device tree support at the same time.
>>
> 
> I agree with you that it's broken in the device tree, but I don't
> think it ever worked.

It was working with legacy board file method. Its not supported with DT,
yes. Most probably, the generic cpufreq-dt support needs to be used for
the DT case.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
  2017-12-31 23:39   ` David Lechner
@ 2018-01-04 11:10     ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 11:10 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

Hi David,

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> In preparation of moving to the common clock framework, usage of static
> struct clk_lookup is removed. The common clock framework uses an opaque
> struct clk, so we won't be able to use static tables as was previously
> done.
> 
> davinci_clk_init() is changed to init a single clock instead of a table
> and an individual clk_register_clkdev() is added for each clock.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

Is there a need for this considering in 6/7 you end up modifying quite a
bit of this patch again?

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
@ 2018-01-04 11:10     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 11:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi David,

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> In preparation of moving to the common clock framework, usage of static
> struct clk_lookup is removed. The common clock framework uses an opaque
> struct clk, so we won't be able to use static tables as was previously
> done.
> 
> davinci_clk_init() is changed to init a single clock instead of a table
> and an individual clk_register_clkdev() is added for each clock.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

Is there a need for this considering in 6/7 you end up modifying quite a
bit of this patch again?

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
  2017-12-31 23:39   ` David Lechner
@ 2018-01-04 11:12     ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 11:12 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> There are a number of clocks that were duplicated because they are used by
> more than one device. It is no longer necessary to do this since we are
> explicitly calling clk_register_clkdev() for each clock. In da830.c, some
> clocks were using the same LPSC, which would cause problems with reference
> counting, so these are combinded into one clock each. In da850.c the
> duplicate clocks had already been fixed by creating dummy child clocks, so
> these clocks are removed.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

If we do end up keeping 2/7, this should be done before that - to avoid
retouching code that was just introduced.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
@ 2018-01-04 11:12     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> There are a number of clocks that were duplicated because they are used by
> more than one device. It is no longer necessary to do this since we are
> explicitly calling clk_register_clkdev() for each clock. In da830.c, some
> clocks were using the same LPSC, which would cause problems with reference
> counting, so these are combinded into one clock each. In da850.c the
> duplicate clocks had already been fixed by creating dummy child clocks, so
> these clocks are removed.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

If we do end up keeping 2/7, this should be done before that - to avoid
retouching code that was just introduced.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2018-01-02 21:31     ` David Lechner
@ 2018-01-04 12:28       ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:28 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel
  Cc: Kevin Hilman, Adam Ford, linux-kernel, linux-clk,
	Michael Turquette, Stephen Boyd

On Wednesday 03 January 2018 03:01 AM, David Lechner wrote:
> Forgot to cc linux-clk, so doing that now...
> 
> 
> On 12/31/2017 05:39 PM, David Lechner wrote:
>> This introduces new drivers for arch/arm/mach-davinci. The code is based
>> on the clock drivers from there and adapted to use the common clock
>> framework.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>>   drivers/clk/Makefile                      |   1 +
>>   drivers/clk/davinci/Makefile              |   3 +
>>   drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380
>> ++++++++++++++++++++++++++++++
>>   drivers/clk/davinci/pll.c                 | 333
>> ++++++++++++++++++++++++++
>>   drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
>>   include/linux/clk/davinci.h               |  46 ++++
>>   include/linux/platform_data/davinci_clk.h |  25 ++
>>   7 files changed, 1005 insertions(+)

This is a pretty huge patch and I think each of cfgchip, pll and PSC
clocks deserve a patch of their own.

On the PLL patch, please describe how the PLL implementation on DaVinci
is different from Keystone, so no reuse is really possible. Similarly
for the PSC patch (no non-DT support in keystone etc).

>> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
>> new file mode 100644
>> index 0000000..8ae85ee
>> --- /dev/null
>> +++ b/drivers/clk/davinci/psc.c
>> @@ -0,0 +1,217 @@

>> +static void psc_config(struct davinci_psc_clk *psc,
>> +               enum davinci_psc_state next_state)
>> +{
>> +    u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
>> +
>> +    mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
>> +    mdctl &= ~MDSTAT_STATE_MASK;
>> +    mdctl |= next_state;
>> +    /* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for
>> sata and
>> +     * dsp here. Is this really needed?
>> +     */
>> +    writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
>> +
>> +    pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
>> +    if ((pdstat & PDSTAT_STATE_MASK) == 0) {
>> +        pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
>> +        pdctl |= PDCTL_NEXT;
>> +        writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
>> +
>> +        ptcmd = BIT(psc->pd);
>> +        writel(ptcmd, psc->base + PTCMD);
>> +
>> +        do {
>> +            epcpr = __raw_readl(psc->base + EPCPR);
>> +        } while (!(epcpr & BIT(psc->pd)));
>> +
>> +        pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
>> +        pdctl |= PDCTL_EPCGOOD;
>> +        __raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);

Can we shift to regmap here too? Then the polling loops like above can
be converted to regmap_read_poll_timeout() too like you have done elsewhere.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-04 12:28       ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 03 January 2018 03:01 AM, David Lechner wrote:
> Forgot to cc linux-clk, so doing that now...
> 
> 
> On 12/31/2017 05:39 PM, David Lechner wrote:
>> This introduces new drivers for arch/arm/mach-davinci. The code is based
>> on the clock drivers from there and adapted to use the common clock
>> framework.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>> ? drivers/clk/Makefile????????????????????? |?? 1 +
>> ? drivers/clk/davinci/Makefile????????????? |?? 3 +
>> ? drivers/clk/davinci/da8xx-cfgchip-clk.c?? | 380
>> ++++++++++++++++++++++++++++++
>> ? drivers/clk/davinci/pll.c???????????????? | 333
>> ++++++++++++++++++++++++++
>> ? drivers/clk/davinci/psc.c???????????????? | 217 +++++++++++++++++
>> ? include/linux/clk/davinci.h?????????????? |? 46 ++++
>> ? include/linux/platform_data/davinci_clk.h |? 25 ++
>> ? 7 files changed, 1005 insertions(+)

This is a pretty huge patch and I think each of cfgchip, pll and PSC
clocks deserve a patch of their own.

On the PLL patch, please describe how the PLL implementation on DaVinci
is different from Keystone, so no reuse is really possible. Similarly
for the PSC patch (no non-DT support in keystone etc).

>> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
>> new file mode 100644
>> index 0000000..8ae85ee
>> --- /dev/null
>> +++ b/drivers/clk/davinci/psc.c
>> @@ -0,0 +1,217 @@

>> +static void psc_config(struct davinci_psc_clk *psc,
>> +?????????????? enum davinci_psc_state next_state)
>> +{
>> +??? u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
>> +
>> +??? mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
>> +??? mdctl &= ~MDSTAT_STATE_MASK;
>> +??? mdctl |= next_state;
>> +??? /* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for
>> sata and
>> +???? * dsp here. Is this really needed?
>> +???? */
>> +??? writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
>> +
>> +??? pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
>> +??? if ((pdstat & PDSTAT_STATE_MASK) == 0) {
>> +??????? pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
>> +??????? pdctl |= PDCTL_NEXT;
>> +??????? writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
>> +
>> +??????? ptcmd = BIT(psc->pd);
>> +??????? writel(ptcmd, psc->base + PTCMD);
>> +
>> +??????? do {
>> +??????????? epcpr = __raw_readl(psc->base + EPCPR);
>> +??????? } while (!(epcpr & BIT(psc->pd)));
>> +
>> +??????? pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
>> +??????? pdctl |= PDCTL_EPCGOOD;
>> +??????? __raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);

Can we shift to regmap here too? Then the polling loops like above can
be converted to regmap_read_poll_timeout() too like you have done elsewhere.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2017-12-31 23:39 ` [PATCH v4 6/7] ARM: davinci: convert to common clock framework David Lechner
@ 2018-01-04 12:39     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:39 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> 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.

This functionality needs to be restored as part of this series since we
cannot commit anything with regressions.

> 
> Also, the order of #includes are cleaned up in files while we are touching
> this code.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

This is a pretty huge patch again and I hope it can be broken down.
Ideally one per SoC converted and then the unused code removal.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-04 12:39     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> 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.

This functionality needs to be restored as part of this series since we
cannot commit anything with regressions.

> 
> Also, the order of #includes are cleaned up in files while we are touching
> this code.
> 
> Signed-off-by: David Lechner <david@lechnology.com>

This is a pretty huge patch again and I hope it can be broken down.
Ideally one per SoC converted and then the unused code removal.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2017-12-31 23:39   ` David Lechner
@ 2018-01-04 12:43     ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:43 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

Hi David,

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
> +	 * dsp here. Is this really needed?
> +	 */

The commit that introduced this flag suggests so.

commit aad70de20fc69970a3080e7e8f02b54a4a3fe3e6
Author:     Sekhar Nori <nsekhar@ti.com>
AuthorDate: Wed Jul 6 06:01:22 2011 +0000
Commit:     Sekhar Nori <nsekhar@ti.com>
CommitDate: Fri Jul 8 11:10:09 2011 +0530

    davinci: enable forced transitions on PSC

    Some DaVinci modules like the SATA on DA850
    need forced module state transitions.

    Define a "force" flag which can be passed to
    the PSC config function to enable it to make
    forced transitions.

    Forced transitions shouldn't normally be attempted,
    unless the TRM explicitly specifies its usage.

    ChangeLog:
    v2:
    Modified to take care of the fact that
    davinci_psc_config() now takes the flags
    directly.

    Signed-off-by: Sekhar Nori <nsekhar@ti.com>

I can check without that flag again, but I do recall it being needed.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-04 12:43     ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-04 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi David,

On Monday 01 January 2018 05:09 AM, David Lechner wrote:
> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
> +	 * dsp here. Is this really needed?
> +	 */

The commit that introduced this flag suggests so.

commit aad70de20fc69970a3080e7e8f02b54a4a3fe3e6
Author:     Sekhar Nori <nsekhar@ti.com>
AuthorDate: Wed Jul 6 06:01:22 2011 +0000
Commit:     Sekhar Nori <nsekhar@ti.com>
CommitDate: Fri Jul 8 11:10:09 2011 +0530

    davinci: enable forced transitions on PSC

    Some DaVinci modules like the SATA on DA850
    need forced module state transitions.

    Define a "force" flag which can be passed to
    the PSC config function to enable it to make
    forced transitions.

    Forced transitions shouldn't normally be attempted,
    unless the TRM explicitly specifies its usage.

    ChangeLog:
    v2:
    Modified to take care of the fact that
    davinci_psc_config() now takes the flags
    directly.

    Signed-off-by: Sekhar Nori <nsekhar@ti.com>

I can check without that flag again, but I do recall it being needed.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
  2018-01-04 11:10     ` Sekhar Nori
@ 2018-01-04 17:43       ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:43 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel



On 1/4/18 5:10 AM, Sekhar Nori wrote:
> Hi David,
> 
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> In preparation of moving to the common clock framework, usage of static
>> struct clk_lookup is removed. The common clock framework uses an opaque
>> struct clk, so we won't be able to use static tables as was previously
>> done.
>>
>> davinci_clk_init() is changed to init a single clock instead of a table
>> and an individual clk_register_clkdev() is added for each clock.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> Is there a need for this considering in 6/7 you end up modifying quite a
> bit of this patch again?

No, you are right. And I've been working ahead with device tree support 
so I think I want to do this a bit differently anyway.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup
@ 2018-01-04 17:43       ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:43 UTC (permalink / raw)
  To: linux-arm-kernel



On 1/4/18 5:10 AM, Sekhar Nori wrote:
> Hi David,
> 
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> In preparation of moving to the common clock framework, usage of static
>> struct clk_lookup is removed. The common clock framework uses an opaque
>> struct clk, so we won't be able to use static tables as was previously
>> done.
>>
>> davinci_clk_init() is changed to init a single clock instead of a table
>> and an individual clk_register_clkdev() is added for each clock.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> Is there a need for this considering in 6/7 you end up modifying quite a
> bit of this patch again?

No, you are right. And I've been working ahead with device tree support 
so I think I want to do this a bit differently anyway.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
  2018-01-04 11:12     ` Sekhar Nori
@ 2018-01-04 17:44       ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:44 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel



On 1/4/18 5:12 AM, Sekhar Nori wrote:
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> There are a number of clocks that were duplicated because they are used by
>> more than one device. It is no longer necessary to do this since we are
>> explicitly calling clk_register_clkdev() for each clock. In da830.c, some
>> clocks were using the same LPSC, which would cause problems with reference
>> counting, so these are combinded into one clock each. In da850.c the
>> duplicate clocks had already been fixed by creating dummy child clocks, so
>> these clocks are removed.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> If we do end up keeping 2/7, this should be done before that - to avoid
> retouching code that was just introduced.
> 

FWIW, this can't be done before because it will cause broken linked 
lists in the davinci clocks. But, as I mentioned already, I am going to 
try a different approach, so this patch will go away completely.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 3/7] ARM: davinci: fix duplicate clocks
@ 2018-01-04 17:44       ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:44 UTC (permalink / raw)
  To: linux-arm-kernel



On 1/4/18 5:12 AM, Sekhar Nori wrote:
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> There are a number of clocks that were duplicated because they are used by
>> more than one device. It is no longer necessary to do this since we are
>> explicitly calling clk_register_clkdev() for each clock. In da830.c, some
>> clocks were using the same LPSC, which would cause problems with reference
>> counting, so these are combinded into one clock each. In da850.c the
>> duplicate clocks had already been fixed by creating dummy child clocks, so
>> these clocks are removed.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> If we do end up keeping 2/7, this should be done before that - to avoid
> retouching code that was just introduced.
> 

FWIW, this can't be done before because it will cause broken linked 
lists in the davinci clocks. But, as I mentioned already, I am going to 
try a different approach, so this patch will go away completely.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2018-01-04 12:28       ` Sekhar Nori
@ 2018-01-04 17:46         ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:46 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel
  Cc: Kevin Hilman, Adam Ford, linux-kernel, linux-clk,
	Michael Turquette, Stephen Boyd



On 1/4/18 6:28 AM, Sekhar Nori wrote:
> On Wednesday 03 January 2018 03:01 AM, David Lechner wrote:
>> Forgot to cc linux-clk, so doing that now...
>>
>>
>> On 12/31/2017 05:39 PM, David Lechner wrote:
>>> This introduces new drivers for arch/arm/mach-davinci. The code is based
>>> on the clock drivers from there and adapted to use the common clock
>>> framework.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> ---
>>>    drivers/clk/Makefile                      |   1 +
>>>    drivers/clk/davinci/Makefile              |   3 +
>>>    drivers/clk/davinci/da8xx-cfgchip-clk.c   | 380
>>> ++++++++++++++++++++++++++++++
>>>    drivers/clk/davinci/pll.c                 | 333
>>> ++++++++++++++++++++++++++
>>>    drivers/clk/davinci/psc.c                 | 217 +++++++++++++++++
>>>    include/linux/clk/davinci.h               |  46 ++++
>>>    include/linux/platform_data/davinci_clk.h |  25 ++
>>>    7 files changed, 1005 insertions(+)
> 
> This is a pretty huge patch and I think each of cfgchip, pll and PSC
> clocks deserve a patch of their own.

Will do.

> 
> On the PLL patch, please describe how the PLL implementation on DaVinci
> is different from Keystone, so no reuse is really possible. Similarly
> for the PSC patch (no non-DT support in keystone etc).

OK.

> 
>>> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
>>> new file mode 100644
>>> index 0000000..8ae85ee
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/psc.c
>>> @@ -0,0 +1,217 @@
> 
>>> +static void psc_config(struct davinci_psc_clk *psc,
>>> +               enum davinci_psc_state next_state)
>>> +{
>>> +    u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
>>> +
>>> +    mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
>>> +    mdctl &= ~MDSTAT_STATE_MASK;
>>> +    mdctl |= next_state;
>>> +    /* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for
>>> sata and
>>> +     * dsp here. Is this really needed?
>>> +     */
>>> +    writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
>>> +
>>> +    pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
>>> +    if ((pdstat & PDSTAT_STATE_MASK) == 0) {
>>> +        pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
>>> +        pdctl |= PDCTL_NEXT;
>>> +        writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
>>> +
>>> +        ptcmd = BIT(psc->pd);
>>> +        writel(ptcmd, psc->base + PTCMD);
>>> +
>>> +        do {
>>> +            epcpr = __raw_readl(psc->base + EPCPR);
>>> +        } while (!(epcpr & BIT(psc->pd)));
>>> +
>>> +        pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
>>> +        pdctl |= PDCTL_EPCGOOD;
>>> +        __raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
> 
> Can we shift to regmap here too? Then the polling loops like above can
> be converted to regmap_read_poll_timeout() too like you have done elsewhere.
> 

I'll give it a try.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-04 17:46         ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:46 UTC (permalink / raw)
  To: linux-arm-kernel



On 1/4/18 6:28 AM, Sekhar Nori wrote:
> On Wednesday 03 January 2018 03:01 AM, David Lechner wrote:
>> Forgot to cc linux-clk, so doing that now...
>>
>>
>> On 12/31/2017 05:39 PM, David Lechner wrote:
>>> This introduces new drivers for arch/arm/mach-davinci. The code is based
>>> on the clock drivers from there and adapted to use the common clock
>>> framework.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> ---
>>>  ? drivers/clk/Makefile????????????????????? |?? 1 +
>>>  ? drivers/clk/davinci/Makefile????????????? |?? 3 +
>>>  ? drivers/clk/davinci/da8xx-cfgchip-clk.c?? | 380
>>> ++++++++++++++++++++++++++++++
>>>  ? drivers/clk/davinci/pll.c???????????????? | 333
>>> ++++++++++++++++++++++++++
>>>  ? drivers/clk/davinci/psc.c???????????????? | 217 +++++++++++++++++
>>>  ? include/linux/clk/davinci.h?????????????? |? 46 ++++
>>>  ? include/linux/platform_data/davinci_clk.h |? 25 ++
>>>  ? 7 files changed, 1005 insertions(+)
> 
> This is a pretty huge patch and I think each of cfgchip, pll and PSC
> clocks deserve a patch of their own.

Will do.

> 
> On the PLL patch, please describe how the PLL implementation on DaVinci
> is different from Keystone, so no reuse is really possible. Similarly
> for the PSC patch (no non-DT support in keystone etc).

OK.

> 
>>> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
>>> new file mode 100644
>>> index 0000000..8ae85ee
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/psc.c
>>> @@ -0,0 +1,217 @@
> 
>>> +static void psc_config(struct davinci_psc_clk *psc,
>>> +?????????????? enum davinci_psc_state next_state)
>>> +{
>>> +??? u32 epcpr, ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
>>> +
>>> +??? mdctl = readl(psc->base + MDCTL + 4 * psc->lpsc);
>>> +??? mdctl &= ~MDSTAT_STATE_MASK;
>>> +??? mdctl |= next_state;
>>> +??? /* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for
>>> sata and
>>> +???? * dsp here. Is this really needed?
>>> +???? */
>>> +??? writel(mdctl, psc->base + MDCTL + 4 * psc->lpsc);
>>> +
>>> +??? pdstat = readl(psc->base + PDSTAT + 4 * psc->pd);
>>> +??? if ((pdstat & PDSTAT_STATE_MASK) == 0) {
>>> +??????? pdctl = readl(psc->base + PDSTAT + 4 * psc->pd);
>>> +??????? pdctl |= PDCTL_NEXT;
>>> +??????? writel(pdctl, psc->base + PDSTAT + 4 * psc->pd);
>>> +
>>> +??????? ptcmd = BIT(psc->pd);
>>> +??????? writel(ptcmd, psc->base + PTCMD);
>>> +
>>> +??????? do {
>>> +??????????? epcpr = __raw_readl(psc->base + EPCPR);
>>> +??????? } while (!(epcpr & BIT(psc->pd)));
>>> +
>>> +??????? pdctl = __raw_readl(psc->base + PDCTL + 4 * psc->pd);
>>> +??????? pdctl |= PDCTL_EPCGOOD;
>>> +??????? __raw_writel(pdctl, psc->base + PDCTL + 4 * psc->pd);
> 
> Can we shift to regmap here too? Then the polling loops like above can
> be converted to regmap_read_poll_timeout() too like you have done elsewhere.
> 

I'll give it a try.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 5/7] clk: Introduce davinci clocks
  2018-01-04 12:43     ` Sekhar Nori
@ 2018-01-04 17:47       ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:47 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel



On 1/4/18 6:43 AM, Sekhar Nori wrote:
> Hi David,
> 
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
>> +	 * dsp here. Is this really needed?
>> +	 */
> 
> The commit that introduced this flag suggests so.
> 
> commit aad70de20fc69970a3080e7e8f02b54a4a3fe3e6
> Author:     Sekhar Nori <nsekhar@ti.com>
> AuthorDate: Wed Jul 6 06:01:22 2011 +0000
> Commit:     Sekhar Nori <nsekhar@ti.com>
> CommitDate: Fri Jul 8 11:10:09 2011 +0530
> 
>      davinci: enable forced transitions on PSC
> 
>      Some DaVinci modules like the SATA on DA850
>      need forced module state transitions.
> 
>      Define a "force" flag which can be passed to
>      the PSC config function to enable it to make
>      forced transitions.
> 
>      Forced transitions shouldn't normally be attempted,
>      unless the TRM explicitly specifies its usage.
> 
>      ChangeLog:
>      v2:
>      Modified to take care of the fact that
>      davinci_psc_config() now takes the flags
>      directly.
> 
>      Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> 
> I can check without that flag again, but I do recall it being needed.
> 

OK, I will add it back. I need to add some other flags as well anyway.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 5/7] clk: Introduce davinci clocks
@ 2018-01-04 17:47       ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:47 UTC (permalink / raw)
  To: linux-arm-kernel



On 1/4/18 6:43 AM, Sekhar Nori wrote:
> Hi David,
> 
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> +	/* TODO: old davinci clocks for da850 set MDCTL_FORCE bit for sata and
>> +	 * dsp here. Is this really needed?
>> +	 */
> 
> The commit that introduced this flag suggests so.
> 
> commit aad70de20fc69970a3080e7e8f02b54a4a3fe3e6
> Author:     Sekhar Nori <nsekhar@ti.com>
> AuthorDate: Wed Jul 6 06:01:22 2011 +0000
> Commit:     Sekhar Nori <nsekhar@ti.com>
> CommitDate: Fri Jul 8 11:10:09 2011 +0530
> 
>      davinci: enable forced transitions on PSC
> 
>      Some DaVinci modules like the SATA on DA850
>      need forced module state transitions.
> 
>      Define a "force" flag which can be passed to
>      the PSC config function to enable it to make
>      forced transitions.
> 
>      Forced transitions shouldn't normally be attempted,
>      unless the TRM explicitly specifies its usage.
> 
>      ChangeLog:
>      v2:
>      Modified to take care of the fact that
>      davinci_psc_config() now takes the flags
>      directly.
> 
>      Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> 
> I can check without that flag again, but I do recall it being needed.
> 

OK, I will add it back. I need to add some other flags as well anyway.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-04 12:39     ` Sekhar Nori
@ 2018-01-04 17:50       ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:50 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel



On 1/4/18 6:39 AM, Sekhar Nori wrote:
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> 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.
> 
> This functionality needs to be restored as part of this series since we
> cannot commit anything with regressions.
> 

Do you have a suggestion on how to accomplish this? I don't have a board 
for testing, so I don't have a way of knowing if my changes will work or 
not.

>>
>> Also, the order of #includes are cleaned up in files while we are touching
>> this code.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> This is a pretty huge patch again and I hope it can be broken down.
> Ideally one per SoC converted and then the unused code removal.
> 

Will do.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-04 17:50       ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 17:50 UTC (permalink / raw)
  To: linux-arm-kernel



On 1/4/18 6:39 AM, Sekhar Nori wrote:
> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>> 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.
> 
> This functionality needs to be restored as part of this series since we
> cannot commit anything with regressions.
> 

Do you have a suggestion on how to accomplish this? I don't have a board 
for testing, so I don't have a way of knowing if my changes will work or 
not.

>>
>> Also, the order of #includes are cleaned up in files while we are touching
>> this code.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
> 
> This is a pretty huge patch again and I hope it can be broken down.
> Ideally one per SoC converted and then the unused code removal.
> 

Will do.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-04 17:50       ` David Lechner
@ 2018-01-04 19:26         ` Adam Ford
  -1 siblings, 0 replies; 59+ messages in thread
From: Adam Ford @ 2018-01-04 19:26 UTC (permalink / raw)
  To: David Lechner; +Cc: Sekhar Nori, linux-arm-kernel, Kevin Hilman, linux-kernel

On Thu, Jan 4, 2018 at 11:50 AM, David Lechner <david@lechnology.com> wrote:
>
>
> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>
>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>>
>>> 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.
>>
>>
>> This functionality needs to be restored as part of this series since we
>> cannot commit anything with regressions.
>>
>
> Do you have a suggestion on how to accomplish this? I don't have a board for
> testing, so I don't have a way of knowing if my changes will work or not.

I work for Logic PD who makes the original da850-evm.  I can help if
you want to send me patches.  It would be better if you had a git repo
setup where I could just clone the repo and tests.

Having a larger collection of smaller the patches would also give me
the ability to bisect down to help determine what actually breaks the
da850-evm vs a few large patches.

Do you still need me to run the board with some of the extra debugging
enabled, or should I wait for the next round of patches?

adam

>
>>>
>>> Also, the order of #includes are cleaned up in files while we are
>>> touching
>>> this code.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>
>>
>> This is a pretty huge patch again and I hope it can be broken down.
>> Ideally one per SoC converted and then the unused code removal.
>>
>
> Will do.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-04 19:26         ` Adam Ford
  0 siblings, 0 replies; 59+ messages in thread
From: Adam Ford @ 2018-01-04 19:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 4, 2018 at 11:50 AM, David Lechner <david@lechnology.com> wrote:
>
>
> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>
>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>>
>>> 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.
>>
>>
>> This functionality needs to be restored as part of this series since we
>> cannot commit anything with regressions.
>>
>
> Do you have a suggestion on how to accomplish this? I don't have a board for
> testing, so I don't have a way of knowing if my changes will work or not.

I work for Logic PD who makes the original da850-evm.  I can help if
you want to send me patches.  It would be better if you had a git repo
setup where I could just clone the repo and tests.

Having a larger collection of smaller the patches would also give me
the ability to bisect down to help determine what actually breaks the
da850-evm vs a few large patches.

Do you still need me to run the board with some of the extra debugging
enabled, or should I wait for the next round of patches?

adam

>
>>>
>>> Also, the order of #includes are cleaned up in files while we are
>>> touching
>>> this code.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>
>>
>> This is a pretty huge patch again and I hope it can be broken down.
>> Ideally one per SoC converted and then the unused code removal.
>>
>
> Will do.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-04 19:26         ` Adam Ford
@ 2018-01-04 21:22           ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 21:22 UTC (permalink / raw)
  To: Adam Ford; +Cc: Sekhar Nori, linux-arm-kernel, Kevin Hilman, linux-kernel

On 01/04/2018 01:26 PM, Adam Ford wrote:
> On Thu, Jan 4, 2018 at 11:50 AM, David Lechner <david@lechnology.com> wrote:
>>
>>
>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>>
>>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>>>
>>>> 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.
>>>
>>>
>>> This functionality needs to be restored as part of this series since we
>>> cannot commit anything with regressions.
>>>
>>
>> Do you have a suggestion on how to accomplish this? I don't have a board for
>> testing, so I don't have a way of knowing if my changes will work or not.
> 
> I work for Logic PD who makes the original da850-evm.  I can help if
> you want to send me patches.  It would be better if you had a git repo
> setup where I could just clone the repo and tests.
> 
> Having a larger collection of smaller the patches would also give me
> the ability to bisect down to help determine what actually breaks the
> da850-evm vs a few large patches.
> 
> Do you still need me to run the board with some of the extra debugging
> enabled, or should I wait for the next round of patches?
> 

You might as well wait until I resubmit. There are going to be some significant
changes.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-04 21:22           ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-04 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/04/2018 01:26 PM, Adam Ford wrote:
> On Thu, Jan 4, 2018 at 11:50 AM, David Lechner <david@lechnology.com> wrote:
>>
>>
>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>>
>>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>>>
>>>> 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.
>>>
>>>
>>> This functionality needs to be restored as part of this series since we
>>> cannot commit anything with regressions.
>>>
>>
>> Do you have a suggestion on how to accomplish this? I don't have a board for
>> testing, so I don't have a way of knowing if my changes will work or not.
> 
> I work for Logic PD who makes the original da850-evm.  I can help if
> you want to send me patches.  It would be better if you had a git repo
> setup where I could just clone the repo and tests.
> 
> Having a larger collection of smaller the patches would also give me
> the ability to bisect down to help determine what actually breaks the
> da850-evm vs a few large patches.
> 
> Do you still need me to run the board with some of the extra debugging
> enabled, or should I wait for the next round of patches?
> 

You might as well wait until I resubmit. There are going to be some significant
changes.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-04 17:50       ` David Lechner
@ 2018-01-05  2:59         ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-05  2:59 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On 01/04/2018 11:50 AM, David Lechner wrote:
> 
> 
> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>> 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.
>>
>> This functionality needs to be restored as part of this series since we
>> cannot commit anything with regressions.
>>
> 
> Do you have a suggestion on how to accomplish this? I don't have a board for testing, so I don't have a way of knowing if my changes will work or not.
> 
>>>
>>> Also, the order of #includes are cleaned up in files while we are touching
>>> this code.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>
>> This is a pretty huge patch again and I hope it can be broken down.
>> Ideally one per SoC converted and then the unused code removal.
>>
> 
> Will do.

Well, I can do this, but I don't think it will compile or run. We can't
have the common clock framework and the legacy davinci clocks enabled at
the same time.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-05  2:59         ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-05  2:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/04/2018 11:50 AM, David Lechner wrote:
> 
> 
> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>> On Monday 01 January 2018 05:09 AM, David Lechner wrote:
>>> 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.
>>
>> This functionality needs to be restored as part of this series since we
>> cannot commit anything with regressions.
>>
> 
> Do you have a suggestion on how to accomplish this? I don't have a board for testing, so I don't have a way of knowing if my changes will work or not.
> 
>>>
>>> Also, the order of #includes are cleaned up in files while we are touching
>>> this code.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>
>> This is a pretty huge patch again and I hope it can be broken down.
>> Ideally one per SoC converted and then the unused code removal.
>>
> 
> Will do.

Well, I can do this, but I don't think it will compile or run. We can't
have the common clock framework and the legacy davinci clocks enabled at
the same time.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-05  2:59         ` David Lechner
@ 2018-01-05 10:42           ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-05 10:42 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On Friday 05 January 2018 08:29 AM, David Lechner wrote:
> On 01/04/2018 11:50 AM, David Lechner wrote:
>> On 1/4/18 6:39 AM, Sekhar Nori wrote:

>>> This is a pretty huge patch again and I hope it can be broken down.
>>> Ideally one per SoC converted and then the unused code removal.
>>>
>>
>> Will do.
> 
> Well, I can do this, but I don't think it will compile or run. We can't
> have the common clock framework and the legacy davinci clocks enabled at
> the same time.

I see. Can you at least hive off the code removal into a separate patch
for next submission. I will then take a closer look at this.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-05 10:42           ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-05 10:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 05 January 2018 08:29 AM, David Lechner wrote:
> On 01/04/2018 11:50 AM, David Lechner wrote:
>> On 1/4/18 6:39 AM, Sekhar Nori wrote:

>>> This is a pretty huge patch again and I hope it can be broken down.
>>> Ideally one per SoC converted and then the unused code removal.
>>>
>>
>> Will do.
> 
> Well, I can do this, but I don't think it will compile or run. We can't
> have the common clock framework and the legacy davinci clocks enabled at
> the same time.

I see. Can you at least hive off the code removal into a separate patch
for next submission. I will then take a closer look at this.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-05 10:42           ` Sekhar Nori
@ 2018-01-06  1:42             ` David Lechner
  -1 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-06  1:42 UTC (permalink / raw)
  To: Sekhar Nori, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On 01/05/2018 04:42 AM, Sekhar Nori wrote:
> On Friday 05 January 2018 08:29 AM, David Lechner wrote:
>> On 01/04/2018 11:50 AM, David Lechner wrote:
>>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
> 
>>>> This is a pretty huge patch again and I hope it can be broken down.
>>>> Ideally one per SoC converted and then the unused code removal.
>>>>
>>>
>>> Will do.
>>
>> Well, I can do this, but I don't think it will compile or run. We can't
>> have the common clock framework and the legacy davinci clocks enabled at
>> the same time.
> 
> I see. Can you at least hive off the code removal into a separate patch
> for next submission. I will then take a closer look at this.
> 

I've realized that I can accomplish this if I use some #if 0/#endif blocks
temporarily if that sounds OK.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-06  1:42             ` David Lechner
  0 siblings, 0 replies; 59+ messages in thread
From: David Lechner @ 2018-01-06  1:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/05/2018 04:42 AM, Sekhar Nori wrote:
> On Friday 05 January 2018 08:29 AM, David Lechner wrote:
>> On 01/04/2018 11:50 AM, David Lechner wrote:
>>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
> 
>>>> This is a pretty huge patch again and I hope it can be broken down.
>>>> Ideally one per SoC converted and then the unused code removal.
>>>>
>>>
>>> Will do.
>>
>> Well, I can do this, but I don't think it will compile or run. We can't
>> have the common clock framework and the legacy davinci clocks enabled at
>> the same time.
> 
> I see. Can you at least hive off the code removal into a separate patch
> for next submission. I will then take a closer look at this.
> 

I've realized that I can accomplish this if I use some #if 0/#endif blocks
temporarily if that sounds OK.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH v4 6/7] ARM: davinci: convert to common clock framework
  2018-01-06  1:42             ` David Lechner
@ 2018-01-08  5:36               ` Sekhar Nori
  -1 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-08  5:36 UTC (permalink / raw)
  To: David Lechner, linux-arm-kernel; +Cc: Kevin Hilman, Adam Ford, linux-kernel

On Saturday 06 January 2018 07:12 AM, David Lechner wrote:
> On 01/05/2018 04:42 AM, Sekhar Nori wrote:
>> On Friday 05 January 2018 08:29 AM, David Lechner wrote:
>>> On 01/04/2018 11:50 AM, David Lechner wrote:
>>>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>
>>>>> This is a pretty huge patch again and I hope it can be broken down.
>>>>> Ideally one per SoC converted and then the unused code removal.
>>>>>
>>>>
>>>> Will do.
>>>
>>> Well, I can do this, but I don't think it will compile or run. We can't
>>> have the common clock framework and the legacy davinci clocks enabled at
>>> the same time.
>>
>> I see. Can you at least hive off the code removal into a separate patch
>> for next submission. I will then take a closer look at this.
>>
> 
> I've realized that I can accomplish this if I use some #if 0/#endif blocks
> temporarily if that sounds OK.

I haven't looked at your latest submission, but this wont be acceptable.
Even as a temporary measure.

If the patch cannot be broken down any, thats fine. I just wanted to
explore the possibility to ease review.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v4 6/7] ARM: davinci: convert to common clock framework
@ 2018-01-08  5:36               ` Sekhar Nori
  0 siblings, 0 replies; 59+ messages in thread
From: Sekhar Nori @ 2018-01-08  5:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 06 January 2018 07:12 AM, David Lechner wrote:
> On 01/05/2018 04:42 AM, Sekhar Nori wrote:
>> On Friday 05 January 2018 08:29 AM, David Lechner wrote:
>>> On 01/04/2018 11:50 AM, David Lechner wrote:
>>>> On 1/4/18 6:39 AM, Sekhar Nori wrote:
>>
>>>>> This is a pretty huge patch again and I hope it can be broken down.
>>>>> Ideally one per SoC converted and then the unused code removal.
>>>>>
>>>>
>>>> Will do.
>>>
>>> Well, I can do this, but I don't think it will compile or run. We can't
>>> have the common clock framework and the legacy davinci clocks enabled at
>>> the same time.
>>
>> I see. Can you at least hive off the code removal into a separate patch
>> for next submission. I will then take a closer look at this.
>>
> 
> I've realized that I can accomplish this if I use some #if 0/#endif blocks
> temporarily if that sounds OK.

I haven't looked at your latest submission, but this wont be acceptable.
Even as a temporary measure.

If the patch cannot be broken down any, thats fine. I just wanted to
explore the possibility to ease review.

Thanks,
Sekhar

^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2018-01-08  5:37 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-31 23:39 [PATCH v4 0/7] ARM: davinci: convert to common clock framework​ David Lechner
2017-12-31 23:39 ` David Lechner
2017-12-31 23:39 ` [PATCH v4 1/7] ARM: davinci: move davinci_clk_init() to init_time David Lechner
2017-12-31 23:39   ` David Lechner
2017-12-31 23:39 ` [PATCH v4 2/7] ARM: davinci: don't use static clk_lookup David Lechner
2017-12-31 23:39   ` David Lechner
2018-01-04 11:10   ` Sekhar Nori
2018-01-04 11:10     ` Sekhar Nori
2018-01-04 17:43     ` David Lechner
2018-01-04 17:43       ` David Lechner
2017-12-31 23:39 ` [PATCH v4 3/7] ARM: davinci: fix duplicate clocks David Lechner
2017-12-31 23:39   ` David Lechner
2018-01-04 11:12   ` Sekhar Nori
2018-01-04 11:12     ` Sekhar Nori
2018-01-04 17:44     ` David Lechner
2018-01-04 17:44       ` David Lechner
2017-12-31 23:39 ` [PATCH v4 4/7] ARM: davinci: remove davinci_set_refclk_rate() David Lechner
2017-12-31 23:39   ` David Lechner
2017-12-31 23:39 ` [PATCH v4 5/7] clk: Introduce davinci clocks David Lechner
2017-12-31 23:39   ` David Lechner
2018-01-01  0:23   ` David Lechner
2018-01-01  0:23     ` David Lechner
2018-01-02 21:31   ` David Lechner
2018-01-02 21:31     ` David Lechner
2018-01-04 12:28     ` Sekhar Nori
2018-01-04 12:28       ` Sekhar Nori
2018-01-04 17:46       ` David Lechner
2018-01-04 17:46         ` David Lechner
2018-01-04 12:43   ` Sekhar Nori
2018-01-04 12:43     ` Sekhar Nori
2018-01-04 17:47     ` David Lechner
2018-01-04 17:47       ` David Lechner
2017-12-31 23:39 ` [PATCH v4 6/7] ARM: davinci: convert to common clock framework David Lechner
2018-01-04 12:39   ` Sekhar Nori
2018-01-04 12:39     ` Sekhar Nori
2018-01-04 17:50     ` David Lechner
2018-01-04 17:50       ` David Lechner
2018-01-04 19:26       ` Adam Ford
2018-01-04 19:26         ` Adam Ford
2018-01-04 21:22         ` David Lechner
2018-01-04 21:22           ` David Lechner
2018-01-05  2:59       ` David Lechner
2018-01-05  2:59         ` David Lechner
2018-01-05 10:42         ` Sekhar Nori
2018-01-05 10:42           ` Sekhar Nori
2018-01-06  1:42           ` David Lechner
2018-01-06  1:42             ` David Lechner
2018-01-08  5:36             ` Sekhar Nori
2018-01-08  5:36               ` Sekhar Nori
2017-12-31 23:39 ` [PATCH v4 7/7] ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS David Lechner
2017-12-31 23:39   ` David Lechner
2018-01-02 15:10 ` [PATCH v4 0/7] ARM: davinci: convert to common clock framework​ Adam Ford
2018-01-02 15:10   ` Adam Ford
2018-01-02 17:10   ` David Lechner
2018-01-02 17:10     ` David Lechner
2018-01-02 18:31     ` David Lechner
2018-01-02 18:31       ` David Lechner
2018-01-03 16:57   ` Sekhar Nori
2018-01-03 16:57     ` Sekhar Nori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.