Selaa lähdekoodia

Merge tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux

Pull clock framework updates from Mike Turquette:
 "The clock framework changes contain the usual driver additions,
  enhancements and fixes mostly for ARM32, ARM64, MIPS and Power-based
  devices.

  Additionally the framework core underwent a bit of surgery with two
  major changes:

   - The boundary between the clock core and clock providers (e.g clock
     drivers) is now more well defined with dedicated provider helper
     functions.  struct clk no longer maps 1:1 with the hardware clock
     but is a true per-user cookie which helps us tracker users of
     hardware clocks and debug bad behavior.

   - The addition of rate constraints for clocks.  Rate ranges are now
     supported which are analogous to the voltage ranges in the
     regulator framework.

  Unfortunately these changes to the core created some breakeage.  We
  think we fixed it all up but for this reason there are lots of last
  minute commits trying to undo the damage"

* tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux: (113 commits)
  clk: Only recalculate the rate if needed
  Revert "clk: mxs: Fix invalid 32-bit access to frac registers"
  clk: qoriq: Add support for the platform PLL
  powerpc/corenet: Enable CLK_QORIQ
  clk: Replace explicit clk assignment with __clk_hw_set_clk
  clk: Add __clk_hw_set_clk helper function
  clk: Don't dereference parent clock if is NULL
  MIPS: Alchemy: Remove bogus args from alchemy_clk_fgcs_detr
  clkdev: Always allocate a struct clk and call __clk_get() w/ CCF
  clk: shmobile: div6: Avoid division by zero in .round_rate()
  clk: mxs: Fix invalid 32-bit access to frac registers
  clk: omap: compile legacy omap3 clocks conditionally
  clkdev: Export clk_register_clkdev
  clk: Add rate constraints to clocks
  clk: remove clk-private.h
  pci: xgene: do not use clk-private.h
  arm: omap2+ remove dead clock code
  clk: Make clk API return per-user struct clk instances
  clk: tegra: Define PLLD_DSI and remove dsia(b)_mux
  clk: tegra: Add support for the Tegra132 CAR IP block
  ...
Linus Torvalds 10 vuotta sitten
vanhempi
commit
18a8d49973
100 muutettua tiedostoa jossa 10924 lisäystä ja 5008 poistoa
  1. 2 0
      Documentation/clk.txt
  2. 15 0
      Documentation/devicetree/bindings/clock/exynos7-clock.txt
  3. 6 4
      Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt
  4. 21 0
      Documentation/devicetree/bindings/clock/qcom,lcc.txt
  5. 3 2
      Documentation/devicetree/bindings/clock/qoriq-clock.txt
  6. 1 0
      Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
  7. 33 0
      Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt
  8. 8 4
      Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
  9. 36 7
      Documentation/devicetree/bindings/clock/sunxi.txt
  10. 42 0
      Documentation/devicetree/bindings/clock/ti,cdce706.txt
  11. 33 0
      Documentation/devicetree/bindings/clock/ti/fapll.txt
  12. 4 4
      Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
  13. 5 0
      MAINTAINERS
  14. 52 20
      arch/arm/boot/dts/sun4i-a10.dtsi
  15. 39 15
      arch/arm/boot/dts/sun5i-a10s.dtsi
  16. 31 13
      arch/arm/boot/dts/sun5i-a13.dtsi
  17. 55 31
      arch/arm/boot/dts/sun6i-a31.dtsi
  18. 52 20
      arch/arm/boot/dts/sun7i-a20.dtsi
  19. 64 32
      arch/arm/boot/dts/sun8i-a23.dtsi
  20. 1 1
      arch/arm/mach-omap2/Makefile
  21. 0 3688
      arch/arm/mach-omap2/cclock3xxx_data.c
  22. 0 16
      arch/arm/mach-omap2/clock.c
  23. 8 6
      arch/arm/mach-omap2/clock.h
  24. 0 11
      arch/arm/mach-omap2/clock_common_data.c
  25. 8 5
      arch/arm/mach-omap2/dpll3xxx.c
  26. 2 0
      arch/arm/mach-omap2/dpll44xx.c
  27. 19 7
      arch/arm/mach-omap2/io.c
  28. 1 0
      arch/arm/mach-omap2/prm.h
  29. 11 0
      arch/arm/mach-omap2/prm_common.c
  30. 0 2
      arch/arm/mach-tegra/tegra.c
  31. 6 0
      arch/mips/alchemy/common/clock.c
  32. 1 0
      arch/powerpc/configs/corenet32_smp_defconfig
  33. 1 0
      arch/powerpc/configs/corenet64_smp_defconfig
  34. 5 0
      arch/powerpc/kernel/time.c
  35. 5 6
      arch/powerpc/platforms/512x/clock-commonclk.c
  36. 13 5
      drivers/clk/Kconfig
  37. 3 1
      drivers/clk/Makefile
  38. 2 0
      drivers/clk/at91/clk-programmable.c
  39. 2 0
      drivers/clk/bcm/clk-kona.c
  40. 348 0
      drivers/clk/clk-asm9260.c
  41. 700 0
      drivers/clk/clk-cdce706.c
  42. 17 12
      drivers/clk/clk-composite.c
  43. 144 84
      drivers/clk/clk-divider.c
  44. 17 1
      drivers/clk/clk-gate.c
  45. 16 0
      drivers/clk/clk-mux.c
  46. 117 61
      drivers/clk/clk-qoriq.c
  47. 705 304
      drivers/clk/clk.c
  48. 23 1
      drivers/clk/clk.h
  49. 76 34
      drivers/clk/clkdev.c
  50. 2 0
      drivers/clk/hisilicon/clk-hi3620.c
  51. 2 0
      drivers/clk/mmp/clk-mix.c
  52. 1 0
      drivers/clk/pxa/Makefile
  53. 1 1
      drivers/clk/pxa/clk-pxa.c
  54. 364 0
      drivers/clk/pxa/clk-pxa3xx.c
  55. 18 0
      drivers/clk/qcom/Kconfig
  56. 4 0
      drivers/clk/qcom/Makefile
  57. 1 0
      drivers/clk/qcom/clk-pll.c
  58. 8 2
      drivers/clk/qcom/clk-rcg.c
  59. 6 0
      drivers/clk/qcom/clk-rcg2.c
  60. 70 0
      drivers/clk/qcom/clk-regmap-divider.c
  61. 29 0
      drivers/clk/qcom/clk-regmap-divider.h
  62. 59 0
      drivers/clk/qcom/clk-regmap-mux.c
  63. 29 0
      drivers/clk/qcom/clk-regmap-mux.h
  64. 12 0
      drivers/clk/qcom/gcc-ipq806x.c
  65. 473 0
      drivers/clk/qcom/lcc-ipq806x.c
  66. 585 0
      drivers/clk/qcom/lcc-msm8960.c
  67. 35 13
      drivers/clk/rockchip/clk-rk3288.c
  68. 22 10
      drivers/clk/samsung/clk-exynos-audss.c
  69. 47 170
      drivers/clk/samsung/clk-exynos3250.c
  70. 5 5
      drivers/clk/samsung/clk-exynos4.c
  71. 48 168
      drivers/clk/samsung/clk-exynos4415.c
  72. 406 2
      drivers/clk/samsung/clk-exynos7.c
  73. 10 3
      drivers/clk/samsung/clk.c
  74. 2 1
      drivers/clk/samsung/clk.h
  75. 2 0
      drivers/clk/shmobile/Makefile
  76. 14 4
      drivers/clk/shmobile/clk-div6.c
  77. 241 0
      drivers/clk/shmobile/clk-r8a73a4.c
  78. 88 0
      drivers/clk/shmobile/clk-rcar-gen2.c
  79. 25 14
      drivers/clk/st/clk-flexgen.c
  80. 7 7
      drivers/clk/st/clkgen-mux.c
  81. 1 0
      drivers/clk/sunxi/Makefile
  82. 6 6
      drivers/clk/sunxi/clk-factors.c
  83. 4 3
      drivers/clk/sunxi/clk-factors.h
  84. 166 58
      drivers/clk/sunxi/clk-mod0.c
  85. 2 0
      drivers/clk/sunxi/clk-sun6i-ar100.c
  86. 11 2
      drivers/clk/sunxi/clk-sun8i-mbus.c
  87. 85 34
      drivers/clk/sunxi/clk-sun9i-core.c
  88. 219 0
      drivers/clk/sunxi/clk-sun9i-mmc.c
  89. 222 40
      drivers/clk/sunxi/clk-sunxi.c
  90. 1 0
      drivers/clk/tegra/Makefile
  91. 0 2
      drivers/clk/tegra/clk-id.h
  92. 7 7
      drivers/clk/tegra/clk-periph.c
  93. 11 7
      drivers/clk/tegra/clk-pll.c
  94. 8 10
      drivers/clk/tegra/clk-tegra-periph.c
  95. 8 2
      drivers/clk/tegra/clk-tegra114.c
  96. 139 29
      drivers/clk/tegra/clk-tegra124.c
  97. 5 2
      drivers/clk/tegra/clk.c
  98. 6 2
      drivers/clk/ti/Makefile
  99. 4653 0
      drivers/clk/ti/clk-3xxx-legacy.c
  100. 1 7
      drivers/clk/ti/clk-3xxx.c

+ 2 - 0
Documentation/clk.txt

@@ -73,6 +73,8 @@ the operations defined in clk.h:
 						unsigned long *parent_rate);
 		long		(*determine_rate)(struct clk_hw *hw,
 						unsigned long rate,
+						unsigned long min_rate,
+						unsigned long max_rate,
 						unsigned long *best_parent_rate,
 						struct clk_hw **best_parent_clk);
 		int		(*set_parent)(struct clk_hw *hw, u8 index);

+ 15 - 0
Documentation/devicetree/bindings/clock/exynos7-clock.txt

@@ -34,6 +34,8 @@ Required Properties for Clock Controller:
 	- "samsung,exynos7-clock-peris"
 	- "samsung,exynos7-clock-fsys0"
 	- "samsung,exynos7-clock-fsys1"
+	- "samsung,exynos7-clock-mscl"
+	- "samsung,exynos7-clock-aud"
 
  - reg: physical base address of the controller and the length of
 	memory mapped region.
@@ -53,6 +55,7 @@ Input clocks for top0 clock controller:
 	- dout_sclk_bus1_pll
 	- dout_sclk_cc_pll
 	- dout_sclk_mfc_pll
+	- dout_sclk_aud_pll
 
 Input clocks for top1 clock controller:
 	- fin_pll
@@ -76,6 +79,14 @@ Input clocks for peric1 clock controller:
 	- sclk_uart1
 	- sclk_uart2
 	- sclk_uart3
+	- sclk_spi0
+	- sclk_spi1
+	- sclk_spi2
+	- sclk_spi3
+	- sclk_spi4
+	- sclk_i2s1
+	- sclk_pcm1
+	- sclk_spdif
 
 Input clocks for peris clock controller:
 	- fin_pll
@@ -91,3 +102,7 @@ Input clocks for fsys1 clock controller:
 	- dout_aclk_fsys1_200
 	- dout_sclk_mmc0
 	- dout_sclk_mmc1
+
+Input clocks for aud clock controller:
+	- fin_pll
+	- fout_aud_pll

+ 6 - 4
Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt

@@ -1,4 +1,4 @@
-NVIDIA Tegra124 Clock And Reset Controller
+NVIDIA Tegra124 and Tegra132 Clock And Reset Controller
 
 This binding uses the common clock binding:
 Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -7,14 +7,16 @@ The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
 for muxing and gating Tegra's clocks, and setting their rates.
 
 Required properties :
-- compatible : Should be "nvidia,tegra124-car"
+- compatible : Should be "nvidia,tegra124-car" or "nvidia,tegra132-car"
 - reg : Should contain CAR registers location and length
 - clocks : Should contain phandle and clock specifiers for two clocks:
   the 32 KHz "32k_in", and the board-specific oscillator "osc".
 - #clock-cells : Should be 1.
   In clock consumers, this cell represents the clock ID exposed by the
-  CAR. The assignments may be found in header file
-  <dt-bindings/clock/tegra124-car.h>.
+  CAR. The assignments may be found in the header files
+  <dt-bindings/clock/tegra124-car-common.h> (which covers IDs common
+  to Tegra124 and Tegra132) and <dt-bindings/clock/tegra124-car.h>
+  (for Tegra124-specific clocks).
 - #reset-cells : Should be 1.
   In clock consumers, this cell represents the bit number in the CAR's
   array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.

+ 21 - 0
Documentation/devicetree/bindings/clock/qcom,lcc.txt

@@ -0,0 +1,21 @@
+Qualcomm LPASS Clock & Reset Controller Binding
+------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+			"qcom,lcc-msm8960"
+			"qcom,lcc-apq8064"
+			"qcom,lcc-ipq8064"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+- #reset-cells : shall contain 1
+
+Example:
+	clock-controller@28000000 {
+		compatible = "qcom,lcc-ipq8064";
+		reg = <0x28000000 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};

+ 3 - 2
Documentation/devicetree/bindings/clock/qoriq-clock.txt

@@ -1,6 +1,6 @@
-* Clock Block on Freescale CoreNet Platforms
+* Clock Block on Freescale QorIQ Platforms
 
-Freescale CoreNet chips take primary clocking input from the external
+Freescale qoriq chips take primary clocking input from the external
 SYSCLK signal. The SYSCLK input (frequency) is multiplied using
 multiple phase locked loops (PLL) to create a variety of frequencies
 which can then be passed to a variety of internal logic, including
@@ -29,6 +29,7 @@ Required properties:
 	* "fsl,t4240-clockgen"
 	* "fsl,b4420-clockgen"
 	* "fsl,b4860-clockgen"
+	* "fsl,ls1021a-clockgen"
 	Chassis clock strings include:
 	* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
 	* "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks

+ 1 - 0
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt

@@ -11,6 +11,7 @@ Required Properties:
 
   - compatible: Must be one of the following
     - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
+    - "renesas,r8a73a4-mstp-clocks" for R8A73A4 (R-Mobile APE6) MSTP gate clocks
     - "renesas,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) MSTP gate clocks
     - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
     - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks

+ 33 - 0
Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt

@@ -0,0 +1,33 @@
+* Renesas R8A73A4 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the R8A73A4 SoC. It includes five PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+  - compatible: Must be "renesas,r8a73a4-cpg-clocks"
+
+  - reg: Base address and length of the memory resource used by the CPG
+
+  - clocks: Reference to the parent clocks ("extal1" and "extal2")
+
+  - #clock-cells: Must be 1
+
+  - clock-output-names: The names of the clocks. Supported clocks are "main",
+    "pll0", "pll1", "pll2", "pll2s", "pll2h", "z", "z2", "i", "m3", "b",
+    "m1", "m2", "zx", "zs", and "hp".
+
+
+Example
+-------
+
+        cpg_clocks: cpg_clocks@e6150000 {
+                compatible = "renesas,r8a73a4-cpg-clocks";
+                reg = <0 0xe6150000 0 0x10000>;
+                clocks = <&extal1_clk>, <&extal2_clk>;
+                #clock-cells = <1>;
+                clock-output-names = "main", "pll0", "pll1", "pll2",
+                                     "pll2s", "pll2h", "z", "z2",
+                                     "i", "m3", "b", "m1", "m2",
+                                     "zx", "zs", "hp";
+        };

+ 8 - 4
Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt

@@ -8,15 +8,18 @@ Required Properties:
   - compatible: Must be one of
     - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
     - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
+    - "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG
     - "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG
     - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
 
   - reg: Base address and length of the memory resource used by the CPG
 
-  - clocks: Reference to the parent clock
+  - clocks: References to the parent clocks: first to the EXTAL clock, second
+    to the USB_EXTAL clock
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "main",
-    "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
+    "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
+    "adsp"
 
 
 Example
@@ -26,8 +29,9 @@ Example
 		compatible = "renesas,r8a7790-cpg-clocks",
 			     "renesas,rcar-gen2-cpg-clocks";
 		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>;
+		clocks = <&extal_clk &usb_extal_clk>;
 		#clock-cells = <1>;
 		clock-output-names = "main", "pll0, "pll1", "pll3",
-				     "lb", "qspi", "sdh", "sd0", "sd1", "z";
+				     "lb", "qspi", "sdh", "sd0", "sd1", "z",
+				     "rcan", "adsp";
 	};

+ 36 - 7
Documentation/devicetree/bindings/clock/sunxi.txt

@@ -26,7 +26,7 @@ Required properties:
 	"allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
 	"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
 	"allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
-	"allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
+	"allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
 	"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
 	"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
 	"allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80
@@ -55,9 +55,11 @@ Required properties:
 	"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
 	"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
 	"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
-	"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
-	"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
+	"allwinner,sun4i-a10-mmc-clk" - for the MMC clock
+	"allwinner,sun9i-a80-mmc-clk" - for mmc module clocks on A80
+	"allwinner,sun9i-a80-mmc-config-clk" - for mmc gates + resets on A80
 	"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
+	"allwinner,sun9i-a80-mod0-clk" - for module 0 (storage) clocks on A80
 	"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
 	"allwinner,sun7i-a20-out-clk" - for the external output clocks
 	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
@@ -73,7 +75,9 @@ Required properties for all clocks:
 - #clock-cells : from common clock binding; shall be set to 0 except for
 	the following compatibles where it shall be set to 1:
 	"allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk",
-	"allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk"
+	"allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk",
+	"allwinner,*-usb-clk", "allwinner,*-mmc-clk",
+	"allwinner,*-mmc-config-clk"
 - clock-output-names : shall be the corresponding names of the outputs.
 	If the clock module only has one output, the name shall be the
 	module name.
@@ -81,6 +85,10 @@ Required properties for all clocks:
 And "allwinner,*-usb-clk" clocks also require:
 - reset-cells : shall be set to 1
 
+The "allwinner,sun9i-a80-mmc-config-clk" clock also requires:
+- #reset-cells : shall be set to 1
+- resets : shall be the reset control phandle for the mmc block.
+
 For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
 dummy clocks at 25 MHz and 125 MHz, respectively. See example.
 
@@ -95,6 +103,14 @@ For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output
 is the normal PLL6 output, or "pll6". The second output is rate doubled
 PLL6, or "pll6x2".
 
+The "allwinner,*-mmc-clk" clocks have three different outputs: the
+main clock, with the ID 0, and the output and sample clocks, with the
+IDs 1 and 2, respectively.
+
+The "allwinner,sun9i-a80-mmc-config-clk" clock has one clock/reset output
+per mmc controller. The number of outputs is determined by the size of
+the address block, which is related to the overall mmc block.
+
 For example:
 
 osc24M: clk@01c20050 {
@@ -138,11 +154,11 @@ cpu: cpu@01c20054 {
 };
 
 mmc0_clk: clk@01c20088 {
-	#clock-cells = <0>;
-	compatible = "allwinner,sun4i-mod0-clk";
+	#clock-cells = <1>;
+	compatible = "allwinner,sun4i-a10-mmc-clk";
 	reg = <0x01c20088 0x4>;
 	clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-	clock-output-names = "mmc0";
+	clock-output-names = "mmc0", "mmc0_output", "mmc0_sample";
 };
 
 mii_phy_tx_clk: clk@2 {
@@ -170,3 +186,16 @@ gmac_clk: clk@01c20164 {
 	clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
 	clock-output-names = "gmac";
 };
+
+mmc_config_clk: clk@01c13000 {
+	compatible = "allwinner,sun9i-a80-mmc-config-clk";
+	reg = <0x01c13000 0x10>;
+	clocks = <&ahb0_gates 8>;
+	clock-names = "ahb";
+	resets = <&ahb0_resets 8>;
+	reset-names = "ahb";
+	#clock-cells = <1>;
+	#reset-cells = <1>;
+	clock-output-names = "mmc0_config", "mmc1_config",
+			     "mmc2_config", "mmc3_config";
+};

+ 42 - 0
Documentation/devicetree/bindings/clock/ti,cdce706.txt

@@ -0,0 +1,42 @@
+Bindings for Texas Instruments CDCE706 programmable 3-PLL clock
+synthesizer/multiplier/divider.
+
+Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
+
+I2C device node required properties:
+- compatible: shall be "ti,cdce706".
+- reg: i2c device address, shall be in range [0x68...0x6b].
+- #clock-cells: from common clock binding; shall be set to 1.
+- clocks: from common clock binding; list of parent clock
+  handles, shall be reference clock(s) connected to CLK_IN0
+  and CLK_IN1 pins.
+- clock-names: shall be clk_in0 and/or clk_in1. Use clk_in0
+  in case of crystal oscillator or differential signal input
+  configuration. Use clk_in0 and clk_in1 in case of independent
+  single-ended LVCMOS inputs configuration.
+
+Example:
+
+	clocks {
+		clk54: clk54 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <54000000>;
+		};
+	};
+	...
+	i2c0: i2c-master@0d090000 {
+		...
+		cdce706: clock-synth@69 {
+			compatible = "ti,cdce706";
+			#clock-cells = <1>;
+			reg = <0x69>;
+			clocks = <&clk54>;
+			clock-names = "clk_in0";
+		};
+	};
+	...
+	simple-audio-card,codec {
+		...
+		clocks = <&cdce706 4>;
+	};

+ 33 - 0
Documentation/devicetree/bindings/clock/ti/fapll.txt

@@ -0,0 +1,33 @@
+Binding for Texas Instruments FAPLL clock.
+
+Binding status: Unstable - ABI compatibility may be broken in the future
+
+This binding uses the common clock binding[1]. It assumes a
+register-mapped FAPLL with usually two selectable input clocks
+(reference clock and bypass clock), and one or more child
+syntesizers.
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "ti,dm816-fapll-clock"
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : link phandles of parent clocks (clk-ref and clk-bypass)
+- reg : address and length of the register set for controlling the FAPLL.
+
+Examples:
+	main_fapll: main_fapll {
+		#clock-cells = <1>;
+		compatible = "ti,dm816-fapll-clock";
+		reg = <0x400 0x40>;
+		clocks = <&sys_clkin_ck &sys_clkin_ck>;
+		clock-indices = <1>, <2>, <3>, <4>, <5>,
+				<6>, <7>;
+		clock-output-names = "main_pll_clk1",
+				     "main_pll_clk2",
+				     "main_pll_clk3",
+				     "main_pll_clk4",
+				     "main_pll_clk5",
+				     "main_pll_clk6",
+				     "main_pll_clk7";
+	};

+ 4 - 4
Documentation/devicetree/bindings/mmc/sunxi-mmc.txt

@@ -10,8 +10,8 @@ Absolute maximum transfer rate is 200MB/s
 Required properties:
  - compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc"
  - reg : mmc controller base registers
- - clocks : a list with 2 phandle + clock specifier pairs
- - clock-names : must contain "ahb" and "mmc"
+ - clocks : a list with 4 phandle + clock specifier pairs
+ - clock-names : must contain "ahb", "mmc", "output" and "sample"
  - interrupts : mmc controller interrupt
 
 Optional properties:
@@ -25,8 +25,8 @@ Examples:
 	mmc0: mmc@01c0f000 {
 		compatible = "allwinner,sun5i-a13-mmc";
 		reg = <0x01c0f000 0x1000>;
-		clocks = <&ahb_gates 8>, <&mmc0_clk>;
-		clock-names = "ahb", "mod";
+		clocks = <&ahb_gates 8>, <&mmc0_clk>, <&mmc0_output_clk>, <&mmc0_sample_clk>;
+		clock-names = "ahb", "mod", "output", "sample";
 		interrupts = <0 32 4>;
 		status = "disabled";
 	};

+ 5 - 0
MAINTAINERS

@@ -9719,6 +9719,11 @@ L:	linux-omap@vger.kernel.org
 S:	Maintained
 F:	drivers/thermal/ti-soc-thermal/
 
+TI CDCE706 CLOCK DRIVER
+M:	Max Filippov <jcmvbkbc@gmail.com>
+S:	Maintained
+F:	drivers/clk/clk-cdce706.c
+
 TI CLOCK DRIVER
 M:	Tero Kristo <t-kristo@ti.com>
 L:	linux-omap@vger.kernel.org

+ 52 - 20
arch/arm/boot/dts/sun4i-a10.dtsi

@@ -294,35 +294,43 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 
 		mmc3_clk: clk@01c20094 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 
 		ts_clk: clk@01c20098 {
@@ -468,8 +476,14 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <32>;
 			status = "disabled";
 		};
@@ -477,8 +491,14 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>, <&mmc1_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <33>;
 			status = "disabled";
 		};
@@ -486,8 +506,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <34>;
 			status = "disabled";
 		};
@@ -495,8 +521,14 @@
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c12000 0x1000>;
-			clocks = <&ahb_gates 11>, <&mmc3_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 11>,
+				 <&mmc3_clk 0>,
+				 <&mmc3_clk 1>,
+				 <&mmc3_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <35>;
 			status = "disabled";
 		};

+ 39 - 15
arch/arm/boot/dts/sun5i-a10s.dtsi

@@ -218,27 +218,33 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 
 		ts_clk: clk@01c20098 {
@@ -368,8 +374,14 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <32>;
 			status = "disabled";
 		};
@@ -377,8 +389,14 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>, <&mmc1_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <33>;
 			status = "disabled";
 		};
@@ -386,8 +404,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <34>;
 			status = "disabled";
 		};

+ 31 - 13
arch/arm/boot/dts/sun5i-a13.dtsi

@@ -257,27 +257,33 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 
 		ts_clk: clk@01c20098 {
@@ -391,8 +397,14 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <32>;
 			status = "disabled";
 		};
@@ -400,8 +412,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <34>;
 			status = "disabled";
 		};

+ 55 - 31
arch/arm/boot/dts/sun6i-a31.dtsi

@@ -190,19 +190,11 @@
 			clock-output-names = "axi";
 		};
 
-		ahb1_mux: ahb1_mux@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
-			clock-output-names = "ahb1_mux";
-		};
-
 		ahb1: ahb1@01c20054 {
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-ahb-clk";
+			compatible = "allwinner,sun6i-a31-ahb1-clk";
 			reg = <0x01c20054 0x4>;
-			clocks = <&ahb1_mux>;
+			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
 			clock-output-names = "ahb1";
 		};
 
@@ -265,35 +257,43 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 
 		mmc3_clk: clk@01c20094 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 
 		spi0_clk: clk@01c200a0 {
@@ -383,15 +383,21 @@
 			#dma-cells = <1>;
 
 			/* DMA controller requires AHB1 clocked from PLL6 */
-			assigned-clocks = <&ahb1_mux>;
+			assigned-clocks = <&ahb1>;
 			assigned-clock-parents = <&pll6 0>;
 		};
 
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb1_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 8>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
@@ -401,8 +407,14 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb1_gates 9>, <&mmc1_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 9>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
@@ -412,8 +424,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb1_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 10>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
@@ -423,8 +441,14 @@
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c12000 0x1000>;
-			clocks = <&ahb1_gates 11>, <&mmc3_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 11>,
+				 <&mmc3_clk 0>,
+				 <&mmc3_clk 1>,
+				 <&mmc3_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 11>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;

+ 52 - 20
arch/arm/boot/dts/sun7i-a20.dtsi

@@ -337,35 +337,43 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 
 		mmc3_clk: clk@01c20094 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 
 		ts_clk: clk@01c20098 {
@@ -583,8 +591,14 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};
@@ -592,8 +606,14 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>, <&mmc1_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};
@@ -601,8 +621,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};
@@ -610,8 +636,14 @@
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c12000 0x1000>;
-			clocks = <&ahb_gates 11>, <&mmc3_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb_gates 11>,
+				 <&mmc3_clk 0>,
+				 <&mmc3_clk 1>,
+				 <&mmc3_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};

+ 64 - 32
arch/arm/boot/dts/sun8i-a23.dtsi

@@ -119,11 +119,19 @@
 		};
 
 		/* dummy clock until actually implemented */
-		pll6: pll6_clk {
+		pll5: pll5_clk {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
-			clock-frequency = <600000000>;
-			clock-output-names = "pll6";
+			clock-frequency = <0>;
+			clock-output-names = "pll5";
+		};
+
+		pll6: clk@01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun6i-a31-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6", "pll6x2";
 		};
 
 		cpu: cpu_clk@01c20050 {
@@ -149,19 +157,11 @@
 			clock-output-names = "axi";
 		};
 
-		ahb1_mux: ahb1_mux_clk@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>;
-			clock-output-names = "ahb1_mux";
-		};
-
 		ahb1: ahb1_clk@01c20054 {
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-ahb-clk";
+			compatible = "allwinner,sun6i-a31-ahb1-clk";
 			reg = <0x01c20054 0x4>;
-			clocks = <&ahb1_mux>;
+			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
 			clock-output-names = "ahb1";
 		};
 
@@ -202,7 +202,7 @@
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-a10-apb1-clk";
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
+			clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
 			clock-output-names = "apb2";
 		};
 
@@ -218,27 +218,41 @@
 		};
 
 		mmc0_clk: clk@01c20088 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20088 0x4>;
-			clocks = <&osc24M>, <&pll6>;
-			clock-output-names = "mmc0";
+			clocks = <&osc24M>, <&pll6 0>;
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 
 		mmc1_clk: clk@01c2008c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c2008c 0x4>;
-			clocks = <&osc24M>, <&pll6>;
-			clock-output-names = "mmc1";
+			clocks = <&osc24M>, <&pll6 0>;
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 
 		mmc2_clk: clk@01c20090 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
 			reg = <0x01c20090 0x4>;
-			clocks = <&osc24M>, <&pll6>;
-			clock-output-names = "mmc2";
+			clocks = <&osc24M>, <&pll6 0>;
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
+		};
+
+		mbus_clk: clk@01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun8i-a23-mbus-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5>;
+			clock-output-names = "mbus";
 		};
 	};
 
@@ -260,8 +274,14 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb1_gates 8>, <&mmc0_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 8>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
@@ -271,8 +291,14 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb1_gates 9>, <&mmc1_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 9>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
@@ -282,8 +308,14 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb1_gates 10>, <&mmc2_clk>;
-			clock-names = "ahb", "mmc";
+			clocks = <&ahb1_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
 			resets = <&ahb1_rst 10>;
 			reset-names = "ahb";
 			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;

+ 1 - 1
arch/arm/mach-omap2/Makefile

@@ -190,7 +190,7 @@ obj-$(CONFIG_SOC_OMAP2430)		+= clock2430.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clkt34xx_dpll3m2.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock3517.o clock36xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= dpll3xxx.o cclock3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3)		+= dpll3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clkt_iclk.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common)
 obj-$(CONFIG_ARCH_OMAP4)		+= dpll3xxx.o dpll44xx.o

+ 0 - 3688
arch/arm/mach-omap2/cclock3xxx_data.c

@@ -1,3688 +0,0 @@
-/*
- * OMAP3 clock data
- *
- * Copyright (C) 2007-2012 Texas Instruments, Inc.
- * Copyright (C) 2007-2011 Nokia Corporation
- *
- * Written by Paul Walmsley
- * Updated to COMMON clk data format by Rajendra Nayak <rnayak@ti.com>
- * With many device clock fixes by Kevin Hilman and Jouni Högander
- * DPLL bypass clock support added by Roman Tereshonkov
- *
- */
-
-/*
- * Virtual clocks are introduced as convenient tools.
- * They are sources for other clocks and not supposed
- * to be requested from drivers directly.
- */
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/clk-private.h>
-#include <linux/list.h>
-#include <linux/io.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "clock.h"
-#include "clock3xxx.h"
-#include "clock34xx.h"
-#include "clock36xx.h"
-#include "clock3517.h"
-#include "cm3xxx.h"
-#include "cm-regbits-34xx.h"
-#include "prm3xxx.h"
-#include "prm-regbits-34xx.h"
-#include "control.h"
-
-/*
- * clocks
- */
-
-#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
-
-/* Maximum DPLL multiplier, divider values for OMAP3 */
-#define OMAP3_MAX_DPLL_MULT		2047
-#define OMAP3630_MAX_JTYPE_DPLL_MULT	4095
-#define OMAP3_MAX_DPLL_DIV		128
-
-DEFINE_CLK_FIXED_RATE(dummy_apb_pclk, CLK_IS_ROOT, 0x0, 0x0);
-
-DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0);
-
-DEFINE_CLK_FIXED_RATE(omap_32k_fck, CLK_IS_ROOT, 32768, 0x0);
-
-DEFINE_CLK_FIXED_RATE(pclk_ck, CLK_IS_ROOT, 27000000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(rmii_ck, CLK_IS_ROOT, 50000000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(secure_32k_fck, CLK_IS_ROOT, 32768, 0x0);
-
-DEFINE_CLK_FIXED_RATE(sys_altclk, CLK_IS_ROOT, 0x0, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_12m_ck, CLK_IS_ROOT, 12000000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_13m_ck, CLK_IS_ROOT, 13000000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_16_8m_ck, CLK_IS_ROOT, 16800000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
-
-DEFINE_CLK_FIXED_RATE(virt_38_4m_ck, CLK_IS_ROOT, 38400000, 0x0);
-
-static const char *osc_sys_ck_parent_names[] = {
-	"virt_12m_ck", "virt_13m_ck", "virt_19200000_ck", "virt_26000000_ck",
-	"virt_38_4m_ck", "virt_16_8m_ck",
-};
-
-DEFINE_CLK_MUX(osc_sys_ck, osc_sys_ck_parent_names, NULL, 0x0,
-	       OMAP3430_PRM_CLKSEL, OMAP3430_SYS_CLKIN_SEL_SHIFT,
-	       OMAP3430_SYS_CLKIN_SEL_WIDTH, 0x0, NULL);
-
-DEFINE_CLK_DIVIDER(sys_ck, "osc_sys_ck", &osc_sys_ck, 0x0,
-		   OMAP3430_PRM_CLKSRC_CTRL, OMAP_SYSCLKDIV_SHIFT,
-		   OMAP_SYSCLKDIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct dpll_data dpll3_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
-	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll3_ck;
-
-static const char *dpll3_ck_parent_names[] = {
-	"sys_ck",
-	"sys_ck",
-};
-
-static const struct clk_ops dpll3_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.get_parent	= &omap2_init_dpll_parent,
-	.recalc_rate	= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-};
-
-static struct clk_hw_omap dpll3_ck_hw = {
-	.hw = {
-		.clk = &dpll3_ck,
-	},
-	.ops		= &clkhwops_omap3_dpll,
-	.dpll_data	= &dpll3_dd,
-	.clkdm_name	= "dpll3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll3_ck, dpll3_ck_parent_names, dpll3_ck_ops);
-
-DEFINE_CLK_DIVIDER(dpll3_m2_ck, "dpll3_ck", &dpll3_ck, 0x0,
-		   OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-		   OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT,
-		   OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk core_ck;
-
-static const char *core_ck_parent_names[] = {
-	"dpll3_m2_ck",
-};
-
-static const struct clk_ops core_ck_ops = {};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_ck, NULL);
-DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops);
-
-DEFINE_CLK_DIVIDER(l3_ick, "core_ck", &core_ck, 0x0,
-		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_L3_SHIFT, OMAP3430_CLKSEL_L3_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-DEFINE_CLK_DIVIDER(l4_ick, "l3_ick", &l3_ick, 0x0,
-		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_L4_SHIFT, OMAP3430_CLKSEL_L4_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk security_l4_ick2;
-
-static const char *security_l4_ick2_parent_names[] = {
-	"l4_ick",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(security_l4_ick2, NULL);
-DEFINE_STRUCT_CLK(security_l4_ick2, security_l4_ick2_parent_names, core_ck_ops);
-
-static struct clk aes1_ick;
-
-static const char *aes1_ick_parent_names[] = {
-	"security_l4_ick2",
-};
-
-static const struct clk_ops aes1_ick_ops = {
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-};
-
-static struct clk_hw_omap aes1_ick_hw = {
-	.hw = {
-		.clk = &aes1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(aes1_ick, aes1_ick_parent_names, aes1_ick_ops);
-
-static struct clk core_l4_ick;
-
-static const struct clk_ops core_l4_ick_ops = {
-	.init		= &omap2_init_clk_clkdm,
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_l4_ick, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(core_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
-
-static struct clk aes2_ick;
-
-static const char *aes2_ick_parent_names[] = {
-	"core_l4_ick",
-};
-
-static const struct clk_ops aes2_ick_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-};
-
-static struct clk_hw_omap aes2_ick_hw = {
-	.hw = {
-		.clk = &aes2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(aes2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk dpll1_fck;
-
-static struct dpll_data dpll1_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll1_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll1_ck;
-
-static const struct clk_ops dpll1_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
-	.get_parent	= &omap2_init_dpll_parent,
-	.recalc_rate	= &omap3_dpll_recalc,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.set_parent	= &omap3_noncore_dpll_set_parent,
-	.set_rate_and_parent	= &omap3_noncore_dpll_set_rate_and_parent,
-	.determine_rate	= &omap3_noncore_dpll_determine_rate,
-	.round_rate	= &omap2_dpll_round_rate,
-};
-
-static struct clk_hw_omap dpll1_ck_hw = {
-	.hw = {
-		.clk = &dpll1_ck,
-	},
-	.ops		= &clkhwops_omap3_dpll,
-	.dpll_data	= &dpll1_dd,
-	.clkdm_name	= "dpll1_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll1_ck, dpll3_ck_parent_names, dpll1_ck_ops);
-
-DEFINE_CLK_FIXED_FACTOR(dpll1_x2_ck, "dpll1_ck", &dpll1_ck, 0x0, 2, 1);
-
-DEFINE_CLK_DIVIDER(dpll1_x2m2_ck, "dpll1_x2_ck", &dpll1_x2_ck, 0x0,
-		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
-		   OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT,
-		   OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk mpu_ck;
-
-static const char *mpu_ck_parent_names[] = {
-	"dpll1_x2m2_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(mpu_ck, "mpu_clkdm");
-DEFINE_STRUCT_CLK(mpu_ck, mpu_ck_parent_names, core_l4_ick_ops);
-
-DEFINE_CLK_DIVIDER(arm_fck, "mpu_ck", &mpu_ck, 0x0,
-		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-		   OMAP3430_ST_MPU_CLK_SHIFT, OMAP3430_ST_MPU_CLK_WIDTH,
-		   0x0, NULL);
-
-static struct clk cam_ick;
-
-static struct clk_hw_omap cam_ick_hw = {
-	.hw = {
-		.clk = &cam_ick,
-	},
-	.ops		= &clkhwops_iclk,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-};
-
-DEFINE_STRUCT_CLK(cam_ick, security_l4_ick2_parent_names, aes2_ick_ops);
-
-/* DPLL4 */
-/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
-/* Type: DPLL */
-static struct dpll_data dpll4_dd;
-
-static struct dpll_data dpll4_dd_34xx __initdata = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct dpll_data dpll4_dd_3630 __initdata = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3630_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.dco_mask	= OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
-	.sddiv_mask	= OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
-	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.flags		= DPLL_J_TYPE
-};
-
-static struct clk dpll4_ck;
-
-static const struct clk_ops dpll4_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
-	.get_parent	= &omap2_init_dpll_parent,
-	.recalc_rate	= &omap3_dpll_recalc,
-	.set_rate	= &omap3_dpll4_set_rate,
-	.set_parent	= &omap3_noncore_dpll_set_parent,
-	.set_rate_and_parent	= &omap3_dpll4_set_rate_and_parent,
-	.determine_rate	= &omap3_noncore_dpll_determine_rate,
-	.round_rate	= &omap2_dpll_round_rate,
-};
-
-static struct clk_hw_omap dpll4_ck_hw = {
-	.hw = {
-		.clk = &dpll4_ck,
-	},
-	.dpll_data	= &dpll4_dd,
-	.ops		= &clkhwops_omap3_dpll,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll4_ck, dpll3_ck_parent_names, dpll4_ck_ops);
-
-static const struct clk_div_table dpll4_mx_ck_div_table[] = {
-	{ .div = 1, .val = 1 },
-	{ .div = 2, .val = 2 },
-	{ .div = 3, .val = 3 },
-	{ .div = 4, .val = 4 },
-	{ .div = 5, .val = 5 },
-	{ .div = 6, .val = 6 },
-	{ .div = 7, .val = 7 },
-	{ .div = 8, .val = 8 },
-	{ .div = 9, .val = 9 },
-	{ .div = 10, .val = 10 },
-	{ .div = 11, .val = 11 },
-	{ .div = 12, .val = 12 },
-	{ .div = 13, .val = 13 },
-	{ .div = 14, .val = 14 },
-	{ .div = 15, .val = 15 },
-	{ .div = 16, .val = 16 },
-	{ .div = 17, .val = 17 },
-	{ .div = 18, .val = 18 },
-	{ .div = 19, .val = 19 },
-	{ .div = 20, .val = 20 },
-	{ .div = 21, .val = 21 },
-	{ .div = 22, .val = 22 },
-	{ .div = 23, .val = 23 },
-	{ .div = 24, .val = 24 },
-	{ .div = 25, .val = 25 },
-	{ .div = 26, .val = 26 },
-	{ .div = 27, .val = 27 },
-	{ .div = 28, .val = 28 },
-	{ .div = 29, .val = 29 },
-	{ .div = 30, .val = 30 },
-	{ .div = 31, .val = 31 },
-	{ .div = 32, .val = 32 },
-	{ .div = 0 },
-};
-
-DEFINE_CLK_DIVIDER(dpll4_m5_ck, "dpll4_ck", &dpll4_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_CAM_SHIFT, OMAP3630_CLKSEL_CAM_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dpll4_m5x2_ck;
-
-static const char *dpll4_m5x2_ck_parent_names[] = {
-	"dpll4_m5_ck",
-};
-
-static const struct clk_ops dpll4_m5x2_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-	.set_rate	= &omap3_clkoutx2_set_rate,
-	.recalc_rate	= &omap3_clkoutx2_recalc,
-	.round_rate	= &omap3_clkoutx2_round_rate,
-};
-
-static const struct clk_ops dpll4_m5x2_ck_3630_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
-	.disable	= &omap2_dflt_clk_disable,
-	.recalc_rate	= &omap3_clkoutx2_recalc,
-};
-
-static struct clk_hw_omap dpll4_m5x2_ck_hw = {
-	.hw = {
-		.clk = &dpll4_m5x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK_FLAGS(dpll4_m5x2_ck, dpll4_m5x2_ck_parent_names,
-			dpll4_m5x2_ck_ops, CLK_SET_RATE_PARENT);
-
-static struct clk dpll4_m5x2_ck_3630 = {
-	.name		= "dpll4_m5x2_ck",
-	.hw		= &dpll4_m5x2_ck_hw.hw,
-	.parent_names	= dpll4_m5x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll4_m5x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-	.flags		= CLK_SET_RATE_PARENT,
-};
-
-static struct clk cam_mclk;
-
-static const char *cam_mclk_parent_names[] = {
-	"dpll4_m5x2_ck",
-};
-
-static struct clk_hw_omap cam_mclk_hw = {
-	.hw = {
-		.clk = &cam_mclk,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-};
-
-static struct clk cam_mclk = {
-	.name		= "cam_mclk",
-	.hw		= &cam_mclk_hw.hw,
-	.parent_names	= cam_mclk_parent_names,
-	.num_parents	= ARRAY_SIZE(cam_mclk_parent_names),
-	.ops		= &aes2_ick_ops,
-	.flags		= CLK_SET_RATE_PARENT,
-};
-
-static const struct clksel_rate clkout2_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-DEFINE_CLK_DIVIDER(dpll4_m2_ck, "dpll4_ck", &dpll4_ck, 0x0,
-		   OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
-		   OMAP3430_DIV_96M_SHIFT, OMAP3630_DIV_96M_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dpll4_m2x2_ck;
-
-static const char *dpll4_m2x2_ck_parent_names[] = {
-	"dpll4_m2_ck",
-};
-
-static struct clk_hw_omap dpll4_m2x2_ck_hw = {
-	.hw = {
-		.clk = &dpll4_m2x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll4_m2x2_ck, dpll4_m2x2_ck_parent_names, dpll4_m5x2_ck_ops);
-
-static struct clk dpll4_m2x2_ck_3630 = {
-	.name		= "dpll4_m2x2_ck",
-	.hw		= &dpll4_m2x2_ck_hw.hw,
-	.parent_names	= dpll4_m2x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll4_m2x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-};
-
-static struct clk omap_96m_alwon_fck;
-
-static const char *omap_96m_alwon_fck_parent_names[] = {
-	"dpll4_m2x2_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(omap_96m_alwon_fck, NULL);
-DEFINE_STRUCT_CLK(omap_96m_alwon_fck, omap_96m_alwon_fck_parent_names,
-		  core_ck_ops);
-
-static struct clk cm_96m_fck;
-
-static const char *cm_96m_fck_parent_names[] = {
-	"omap_96m_alwon_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(cm_96m_fck, NULL);
-DEFINE_STRUCT_CLK(cm_96m_fck, cm_96m_fck_parent_names, core_ck_ops);
-
-static const struct clksel_rate clkout2_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-DEFINE_CLK_DIVIDER_TABLE(dpll4_m3_ck, "dpll4_ck", &dpll4_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_TV_SHIFT, OMAP3630_CLKSEL_TV_WIDTH,
-		   0, dpll4_mx_ck_div_table, NULL);
-
-static struct clk dpll4_m3x2_ck;
-
-static const char *dpll4_m3x2_ck_parent_names[] = {
-	"dpll4_m3_ck",
-};
-
-static struct clk_hw_omap dpll4_m3x2_ck_hw = {
-	.hw = {
-		.clk = &dpll4_m3x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll4_m3x2_ck, dpll4_m3x2_ck_parent_names, dpll4_m5x2_ck_ops);
-
-static struct clk dpll4_m3x2_ck_3630 = {
-	.name		= "dpll4_m3x2_ck",
-	.hw		= &dpll4_m3x2_ck_hw.hw,
-	.parent_names	= dpll4_m3x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll4_m3x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-};
-
-static const char *omap_54m_fck_parent_names[] = {
-	"dpll4_m3x2_ck", "sys_altclk",
-};
-
-DEFINE_CLK_MUX(omap_54m_fck, omap_54m_fck_parent_names, NULL, 0x0,
-	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP3430_SOURCE_54M_SHIFT,
-	       OMAP3430_SOURCE_54M_WIDTH, 0x0, NULL);
-
-static const struct clksel clkout2_src_clksel[] = {
-	{ .parent = &core_ck, .rates = clkout2_src_core_rates },
-	{ .parent = &sys_ck, .rates = clkout2_src_sys_rates },
-	{ .parent = &cm_96m_fck, .rates = clkout2_src_96m_rates },
-	{ .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates },
-	{ .parent = NULL },
-};
-
-static const char *clkout2_src_ck_parent_names[] = {
-	"core_ck", "sys_ck", "cm_96m_fck", "omap_54m_fck",
-};
-
-static const struct clk_ops clkout2_src_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.get_parent	= &omap2_clksel_find_parent_index,
-	.set_parent	= &omap2_clksel_set_parent,
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(clkout2_src_ck, "core_clkdm",
-			 clkout2_src_clksel, OMAP3430_CM_CLKOUT_CTRL,
-			 OMAP3430_CLKOUT2SOURCE_MASK,
-			 OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_EN_SHIFT,
-			 NULL, clkout2_src_ck_parent_names, clkout2_src_ck_ops);
-
-static const struct clksel_rate omap_48m_cm96m_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_48m_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
-	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
-	{ .parent = NULL },
-};
-
-static const char *omap_48m_fck_parent_names[] = {
-	"cm_96m_fck", "sys_altclk",
-};
-
-static struct clk omap_48m_fck;
-
-static const struct clk_ops omap_48m_fck_ops = {
-	.recalc_rate	= &omap2_clksel_recalc,
-	.get_parent	= &omap2_clksel_find_parent_index,
-	.set_parent	= &omap2_clksel_set_parent,
-};
-
-static struct clk_hw_omap omap_48m_fck_hw = {
-	.hw = {
-		.clk = &omap_48m_fck,
-	},
-	.clksel		= omap_48m_clksel,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
-};
-
-DEFINE_STRUCT_CLK(omap_48m_fck, omap_48m_fck_parent_names, omap_48m_fck_ops);
-
-DEFINE_CLK_FIXED_FACTOR(omap_12m_fck, "omap_48m_fck", &omap_48m_fck, 0x0, 1, 4);
-
-static struct clk core_12m_fck;
-
-static const char *core_12m_fck_parent_names[] = {
-	"omap_12m_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_12m_fck, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(core_12m_fck, core_12m_fck_parent_names, core_l4_ick_ops);
-
-static struct clk core_48m_fck;
-
-static const char *core_48m_fck_parent_names[] = {
-	"omap_48m_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_48m_fck, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(core_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops);
-
-static const char *omap_96m_fck_parent_names[] = {
-	"cm_96m_fck", "sys_ck",
-};
-
-DEFINE_CLK_MUX(omap_96m_fck, omap_96m_fck_parent_names, NULL, 0x0,
-	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	       OMAP3430_SOURCE_96M_SHIFT, OMAP3430_SOURCE_96M_WIDTH, 0x0, NULL);
-
-static struct clk core_96m_fck;
-
-static const char *core_96m_fck_parent_names[] = {
-	"omap_96m_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_96m_fck, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(core_96m_fck, core_96m_fck_parent_names, core_l4_ick_ops);
-
-static struct clk core_l3_ick;
-
-static const char *core_l3_ick_parent_names[] = {
-	"l3_ick",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(core_l3_ick, "core_l3_clkdm");
-DEFINE_STRUCT_CLK(core_l3_ick, core_l3_ick_parent_names, core_l4_ick_ops);
-
-DEFINE_CLK_FIXED_FACTOR(dpll3_m2x2_ck, "dpll3_m2_ck", &dpll3_m2_ck, 0x0, 2, 1);
-
-static struct clk corex2_fck;
-
-static const char *corex2_fck_parent_names[] = {
-	"dpll3_m2x2_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(corex2_fck, NULL);
-DEFINE_STRUCT_CLK(corex2_fck, corex2_fck_parent_names, core_ck_ops);
-
-static const char *cpefuse_fck_parent_names[] = {
-	"sys_ck",
-};
-
-static struct clk cpefuse_fck;
-
-static struct clk_hw_omap cpefuse_fck_hw = {
-	.hw = {
-		.clk = &cpefuse_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(cpefuse_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk csi2_96m_fck;
-
-static const char *csi2_96m_fck_parent_names[] = {
-	"core_96m_fck",
-};
-
-static struct clk_hw_omap csi2_96m_fck_hw = {
-	.hw = {
-		.clk = &csi2_96m_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-};
-
-DEFINE_STRUCT_CLK(csi2_96m_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk d2d_26m_fck;
-
-static struct clk_hw_omap d2d_26m_fck_hw = {
-	.hw = {
-		.clk = &d2d_26m_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-};
-
-DEFINE_STRUCT_CLK(d2d_26m_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk des1_ick;
-
-static struct clk_hw_omap des1_ick_hw = {
-	.hw = {
-		.clk = &des1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(des1_ick, aes1_ick_parent_names, aes1_ick_ops);
-
-static struct clk des2_ick;
-
-static struct clk_hw_omap des2_ick_hw = {
-	.hw = {
-		.clk = &des2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(des2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_DIVIDER(dpll1_fck, "core_ck", &core_ck, 0x0,
-		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-		   OMAP3430_MPU_CLK_SRC_SHIFT, OMAP3430_MPU_CLK_SRC_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dpll2_fck;
-
-static struct dpll_data dpll2_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll2_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
-	.modes		= ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
-			   (1 << DPLL_LOW_POWER_BYPASS)),
-	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll2_ck;
-
-static struct clk_hw_omap dpll2_ck_hw = {
-	.hw = {
-		.clk = &dpll2_ck,
-	},
-	.ops		= &clkhwops_omap3_dpll,
-	.dpll_data	= &dpll2_dd,
-	.clkdm_name	= "dpll2_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll2_ck, dpll3_ck_parent_names, dpll1_ck_ops);
-
-DEFINE_CLK_DIVIDER(dpll2_fck, "core_ck", &core_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-		   OMAP3430_IVA2_CLK_SRC_SHIFT, OMAP3430_IVA2_CLK_SRC_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-DEFINE_CLK_DIVIDER(dpll2_m2_ck, "dpll2_ck", &dpll2_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL2_PLL),
-		   OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT,
-		   OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-DEFINE_CLK_DIVIDER(dpll3_m3_ck, "dpll3_ck", &dpll3_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_DIV_DPLL3_SHIFT, OMAP3430_DIV_DPLL3_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dpll3_m3x2_ck;
-
-static const char *dpll3_m3x2_ck_parent_names[] = {
-	"dpll3_m3_ck",
-};
-
-static struct clk_hw_omap dpll3_m3x2_ck_hw = {
-	.hw = {
-		.clk = &dpll3_m3x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll3_m3x2_ck, dpll3_m3x2_ck_parent_names, dpll4_m5x2_ck_ops);
-
-static struct clk dpll3_m3x2_ck_3630 = {
-	.name		= "dpll3_m3x2_ck",
-	.hw		= &dpll3_m3x2_ck_hw.hw,
-	.parent_names	= dpll3_m3x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll3_m3x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-};
-
-DEFINE_CLK_FIXED_FACTOR(dpll3_x2_ck, "dpll3_ck", &dpll3_ck, 0x0, 2, 1);
-
-DEFINE_CLK_DIVIDER_TABLE(dpll4_m4_ck, "dpll4_ck", &dpll4_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_DSS1_SHIFT, OMAP3630_CLKSEL_DSS1_WIDTH,
-		   0, dpll4_mx_ck_div_table, NULL);
-
-static struct clk dpll4_m4x2_ck;
-
-static const char *dpll4_m4x2_ck_parent_names[] = {
-	"dpll4_m4_ck",
-};
-
-static struct clk_hw_omap dpll4_m4x2_ck_hw = {
-	.hw = {
-		.clk = &dpll4_m4x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_DSS1_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK_FLAGS(dpll4_m4x2_ck, dpll4_m4x2_ck_parent_names,
-		dpll4_m5x2_ck_ops, CLK_SET_RATE_PARENT);
-
-static struct clk dpll4_m4x2_ck_3630 = {
-	.name		= "dpll4_m4x2_ck",
-	.hw		= &dpll4_m4x2_ck_hw.hw,
-	.parent_names	= dpll4_m4x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll4_m4x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-	.flags		= CLK_SET_RATE_PARENT,
-};
-
-DEFINE_CLK_DIVIDER(dpll4_m6_ck, "dpll4_ck", &dpll4_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_DIV_DPLL4_SHIFT, OMAP3630_DIV_DPLL4_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dpll4_m6x2_ck;
-
-static const char *dpll4_m6x2_ck_parent_names[] = {
-	"dpll4_m6_ck",
-};
-
-static struct clk_hw_omap dpll4_m6x2_ck_hw = {
-	.hw = {
-		.clk = &dpll4_m6x2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll4_m6x2_ck, dpll4_m6x2_ck_parent_names, dpll4_m5x2_ck_ops);
-
-static struct clk dpll4_m6x2_ck_3630 = {
-	.name		= "dpll4_m6x2_ck",
-	.hw		= &dpll4_m6x2_ck_hw.hw,
-	.parent_names	= dpll4_m6x2_ck_parent_names,
-	.num_parents	= ARRAY_SIZE(dpll4_m6x2_ck_parent_names),
-	.ops		= &dpll4_m5x2_ck_3630_ops,
-};
-
-DEFINE_CLK_FIXED_FACTOR(dpll4_x2_ck, "dpll4_ck", &dpll4_ck, 0x0, 2, 1);
-
-static struct dpll_data dpll5_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
-	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
-	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
-	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll5_ck;
-
-static struct clk_hw_omap dpll5_ck_hw = {
-	.hw = {
-		.clk = &dpll5_ck,
-	},
-	.ops		= &clkhwops_omap3_dpll,
-	.dpll_data	= &dpll5_dd,
-	.clkdm_name	= "dpll5_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dpll5_ck, dpll3_ck_parent_names, dpll1_ck_ops);
-
-DEFINE_CLK_DIVIDER(dpll5_m2_ck, "dpll5_ck", &dpll5_ck, 0x0,
-		   OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
-		   OMAP3430ES2_DIV_120M_SHIFT, OMAP3430ES2_DIV_120M_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk dss1_alwon_fck_3430es1;
-
-static const char *dss1_alwon_fck_3430es1_parent_names[] = {
-	"dpll4_m4x2_ck",
-};
-
-static struct clk_hw_omap dss1_alwon_fck_3430es1_hw = {
-	.hw = {
-		.clk = &dss1_alwon_fck_3430es1,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es1,
-		dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops,
-		CLK_SET_RATE_PARENT);
-
-static struct clk dss1_alwon_fck_3430es2;
-
-static struct clk_hw_omap dss1_alwon_fck_3430es2_hw = {
-	.hw = {
-		.clk = &dss1_alwon_fck_3430es2,
-	},
-	.ops		= &clkhwops_omap3430es2_dss_usbhost_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es2,
-		dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops,
-		CLK_SET_RATE_PARENT);
-
-static struct clk dss2_alwon_fck;
-
-static struct clk_hw_omap dss2_alwon_fck_hw = {
-	.hw = {
-		.clk = &dss2_alwon_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dss2_alwon_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk dss_96m_fck;
-
-static struct clk_hw_omap dss_96m_fck_hw = {
-	.hw = {
-		.clk = &dss_96m_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dss_96m_fck, core_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk dss_ick_3430es1;
-
-static struct clk_hw_omap dss_ick_3430es1_hw = {
-	.hw = {
-		.clk = &dss_ick_3430es1,
-	},
-	.ops		= &clkhwops_iclk,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dss_ick_3430es1, security_l4_ick2_parent_names, aes2_ick_ops);
-
-static struct clk dss_ick_3430es2;
-
-static struct clk_hw_omap dss_ick_3430es2_hw = {
-	.hw = {
-		.clk = &dss_ick_3430es2,
-	},
-	.ops		= &clkhwops_omap3430es2_iclk_dss_usbhost_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dss_ick_3430es2, security_l4_ick2_parent_names, aes2_ick_ops);
-
-static struct clk dss_tv_fck;
-
-static const char *dss_tv_fck_parent_names[] = {
-	"omap_54m_fck",
-};
-
-static struct clk_hw_omap dss_tv_fck_hw = {
-	.hw = {
-		.clk = &dss_tv_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-};
-
-DEFINE_STRUCT_CLK(dss_tv_fck, dss_tv_fck_parent_names, aes2_ick_ops);
-
-static struct clk emac_fck;
-
-static const char *emac_fck_parent_names[] = {
-	"rmii_ck",
-};
-
-static struct clk_hw_omap emac_fck_hw = {
-	.hw = {
-		.clk = &emac_fck,
-	},
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_CPGMAC_FCLK_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(emac_fck, emac_fck_parent_names, aes1_ick_ops);
-
-static struct clk ipss_ick;
-
-static const char *ipss_ick_parent_names[] = {
-	"core_l3_ick",
-};
-
-static struct clk_hw_omap ipss_ick_hw = {
-	.hw = {
-		.clk = &ipss_ick,
-	},
-	.ops		= &clkhwops_am35xx_ipss_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= AM35XX_EN_IPSS_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(ipss_ick, ipss_ick_parent_names, aes2_ick_ops);
-
-static struct clk emac_ick;
-
-static const char *emac_ick_parent_names[] = {
-	"ipss_ick",
-};
-
-static struct clk_hw_omap emac_ick_hw = {
-	.hw = {
-		.clk = &emac_ick,
-	},
-	.ops		= &clkhwops_am35xx_ipss_module_wait,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(emac_ick, emac_ick_parent_names, aes2_ick_ops);
-
-static struct clk emu_core_alwon_ck;
-
-static const char *emu_core_alwon_ck_parent_names[] = {
-	"dpll3_m3x2_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(emu_core_alwon_ck, "dpll3_clkdm");
-DEFINE_STRUCT_CLK(emu_core_alwon_ck, emu_core_alwon_ck_parent_names,
-		  core_l4_ick_ops);
-
-static struct clk emu_mpu_alwon_ck;
-
-static const char *emu_mpu_alwon_ck_parent_names[] = {
-	"mpu_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(emu_mpu_alwon_ck, NULL);
-DEFINE_STRUCT_CLK(emu_mpu_alwon_ck, emu_mpu_alwon_ck_parent_names, core_ck_ops);
-
-static struct clk emu_per_alwon_ck;
-
-static const char *emu_per_alwon_ck_parent_names[] = {
-	"dpll4_m6x2_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(emu_per_alwon_ck, "dpll4_clkdm");
-DEFINE_STRUCT_CLK(emu_per_alwon_ck, emu_per_alwon_ck_parent_names,
-		  core_l4_ick_ops);
-
-static const char *emu_src_ck_parent_names[] = {
-	"sys_ck", "emu_core_alwon_ck", "emu_per_alwon_ck", "emu_mpu_alwon_ck",
-};
-
-static const struct clksel_rate emu_src_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_per_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_mpu_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel emu_src_clksel[] = {
-	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
-	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
-	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
-	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
-	{ .parent = NULL },
-};
-
-static const struct clk_ops emu_src_ck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.get_parent	= &omap2_clksel_find_parent_index,
-	.set_parent	= &omap2_clksel_set_parent,
-	.enable		= &omap2_clkops_enable_clkdm,
-	.disable	= &omap2_clkops_disable_clkdm,
-};
-
-static struct clk emu_src_ck;
-
-static struct clk_hw_omap emu_src_ck_hw = {
-	.hw = {
-		.clk = &emu_src_ck,
-	},
-	.clksel		= emu_src_clksel,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
-	.clkdm_name	= "emu_clkdm",
-};
-
-DEFINE_STRUCT_CLK(emu_src_ck, emu_src_ck_parent_names, emu_src_ck_ops);
-
-DEFINE_CLK_DIVIDER(atclk_fck, "emu_src_ck", &emu_src_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_CLKSEL_ATCLK_SHIFT, OMAP3430_CLKSEL_ATCLK_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk fac_ick;
-
-static struct clk_hw_omap fac_ick_hw = {
-	.hw = {
-		.clk = &fac_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(fac_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk fshostusb_fck;
-
-static const char *fshostusb_fck_parent_names[] = {
-	"core_48m_fck",
-};
-
-static struct clk_hw_omap fshostusb_fck_hw = {
-	.hw = {
-		.clk = &fshostusb_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(fshostusb_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk gfx_l3_ck;
-
-static struct clk_hw_omap gfx_l3_ck_hw = {
-	.hw = {
-		.clk = &gfx_l3_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gfx_l3_ck, core_l3_ick_parent_names, aes1_ick_ops);
-
-DEFINE_CLK_DIVIDER(gfx_l3_fck, "l3_ick", &l3_ick, 0x0,
-		   OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-		   OMAP_CLKSEL_GFX_SHIFT, OMAP_CLKSEL_GFX_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk gfx_cg1_ck;
-
-static const char *gfx_cg1_ck_parent_names[] = {
-	"gfx_l3_fck",
-};
-
-static struct clk_hw_omap gfx_cg1_ck_hw = {
-	.hw = {
-		.clk = &gfx_cg1_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gfx_cg1_ck, gfx_cg1_ck_parent_names, aes2_ick_ops);
-
-static struct clk gfx_cg2_ck;
-
-static struct clk_hw_omap gfx_cg2_ck_hw = {
-	.hw = {
-		.clk = &gfx_cg2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gfx_cg2_ck, gfx_cg1_ck_parent_names, aes2_ick_ops);
-
-static struct clk gfx_l3_ick;
-
-static const char *gfx_l3_ick_parent_names[] = {
-	"gfx_l3_ck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(gfx_l3_ick, "gfx_3430es1_clkdm");
-DEFINE_STRUCT_CLK(gfx_l3_ick, gfx_l3_ick_parent_names, core_l4_ick_ops);
-
-static struct clk wkup_32k_fck;
-
-static const char *wkup_32k_fck_parent_names[] = {
-	"omap_32k_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(wkup_32k_fck, "wkup_clkdm");
-DEFINE_STRUCT_CLK(wkup_32k_fck, wkup_32k_fck_parent_names, core_l4_ick_ops);
-
-static struct clk gpio1_dbck;
-
-static const char *gpio1_dbck_parent_names[] = {
-	"wkup_32k_fck",
-};
-
-static struct clk_hw_omap gpio1_dbck_hw = {
-	.hw = {
-		.clk = &gpio1_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio1_dbck, gpio1_dbck_parent_names, aes2_ick_ops);
-
-static struct clk wkup_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(wkup_l4_ick, "wkup_clkdm");
-DEFINE_STRUCT_CLK(wkup_l4_ick, cpefuse_fck_parent_names, core_l4_ick_ops);
-
-static struct clk gpio1_ick;
-
-static const char *gpio1_ick_parent_names[] = {
-	"wkup_l4_ick",
-};
-
-static struct clk_hw_omap gpio1_ick_hw = {
-	.hw = {
-		.clk = &gpio1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio1_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-static struct clk per_32k_alwon_fck;
-
-DEFINE_STRUCT_CLK_HW_OMAP(per_32k_alwon_fck, "per_clkdm");
-DEFINE_STRUCT_CLK(per_32k_alwon_fck, wkup_32k_fck_parent_names,
-		  core_l4_ick_ops);
-
-static struct clk gpio2_dbck;
-
-static const char *gpio2_dbck_parent_names[] = {
-	"per_32k_alwon_fck",
-};
-
-static struct clk_hw_omap gpio2_dbck_hw = {
-	.hw = {
-		.clk = &gpio2_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio2_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk per_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(per_l4_ick, "per_clkdm");
-DEFINE_STRUCT_CLK(per_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
-
-static struct clk gpio2_ick;
-
-static const char *gpio2_ick_parent_names[] = {
-	"per_l4_ick",
-};
-
-static struct clk_hw_omap gpio2_ick_hw = {
-	.hw = {
-		.clk = &gpio2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio2_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpio3_dbck;
-
-static struct clk_hw_omap gpio3_dbck_hw = {
-	.hw = {
-		.clk = &gpio3_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio3_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk gpio3_ick;
-
-static struct clk_hw_omap gpio3_ick_hw = {
-	.hw = {
-		.clk = &gpio3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio3_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpio4_dbck;
-
-static struct clk_hw_omap gpio4_dbck_hw = {
-	.hw = {
-		.clk = &gpio4_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio4_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk gpio4_ick;
-
-static struct clk_hw_omap gpio4_ick_hw = {
-	.hw = {
-		.clk = &gpio4_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio4_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpio5_dbck;
-
-static struct clk_hw_omap gpio5_dbck_hw = {
-	.hw = {
-		.clk = &gpio5_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio5_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk gpio5_ick;
-
-static struct clk_hw_omap gpio5_ick_hw = {
-	.hw = {
-		.clk = &gpio5_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio5_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpio6_dbck;
-
-static struct clk_hw_omap gpio6_dbck_hw = {
-	.hw = {
-		.clk = &gpio6_dbck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio6_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk gpio6_ick;
-
-static struct clk_hw_omap gpio6_ick_hw = {
-	.hw = {
-		.clk = &gpio6_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpio6_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpmc_fck;
-
-static struct clk_hw_omap gpmc_fck_hw = {
-	.hw = {
-		.clk = &gpmc_fck,
-	},
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpmc_fck, ipss_ick_parent_names, core_l4_ick_ops);
-
-static const struct clksel omap343x_gpt_clksel[] = {
-	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck, .rates = gpt_sys_rates },
-	{ .parent = NULL },
-};
-
-static const char *gpt10_fck_parent_names[] = {
-	"omap_32k_fck", "sys_ck",
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT10_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_GPT10_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt10_ick;
-
-static struct clk_hw_omap gpt10_ick_hw = {
-	.hw = {
-		.clk = &gpt10_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt10_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT11_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_GPT11_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt11_ick;
-
-static struct clk_hw_omap gpt11_ick_hw = {
-	.hw = {
-		.clk = &gpt11_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt11_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk gpt12_fck;
-
-static const char *gpt12_fck_parent_names[] = {
-	"secure_32k_fck",
-};
-
-DEFINE_STRUCT_CLK_HW_OMAP(gpt12_fck, "wkup_clkdm");
-DEFINE_STRUCT_CLK(gpt12_fck, gpt12_fck_parent_names, core_l4_ick_ops);
-
-static struct clk gpt12_ick;
-
-static struct clk_hw_omap gpt12_ick_hw = {
-	.hw = {
-		.clk = &gpt12_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt12_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "wkup_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT1_MASK,
-			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT1_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt1_ick;
-
-static struct clk_hw_omap gpt1_ick_hw = {
-	.hw = {
-		.clk = &gpt1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt1_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT2_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT2_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt2_ick;
-
-static struct clk_hw_omap gpt2_ick_hw = {
-	.hw = {
-		.clk = &gpt2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt2_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT3_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT3_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt3_ick;
-
-static struct clk_hw_omap gpt3_ick_hw = {
-	.hw = {
-		.clk = &gpt3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt3_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT4_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT4_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt4_ick;
-
-static struct clk_hw_omap gpt4_ick_hw = {
-	.hw = {
-		.clk = &gpt4_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt4_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT5_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT5_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt5_ick;
-
-static struct clk_hw_omap gpt5_ick_hw = {
-	.hw = {
-		.clk = &gpt5_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt5_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT6_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT6_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt6_ick;
-
-static struct clk_hw_omap gpt6_ick_hw = {
-	.hw = {
-		.clk = &gpt6_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt6_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT7_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT7_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt7_ick;
-
-static struct clk_hw_omap gpt7_ick_hw = {
-	.hw = {
-		.clk = &gpt7_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt7_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT8_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT8_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt8_ick;
-
-static struct clk_hw_omap gpt8_ick_hw = {
-	.hw = {
-		.clk = &gpt8_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt8_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "per_clkdm", omap343x_gpt_clksel,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_GPT9_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_GPT9_SHIFT, &clkhwops_wait,
-			 gpt10_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk gpt9_ick;
-
-static struct clk_hw_omap gpt9_ick_hw = {
-	.hw = {
-		.clk = &gpt9_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(gpt9_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk hdq_fck;
-
-static const char *hdq_fck_parent_names[] = {
-	"core_12m_fck",
-};
-
-static struct clk_hw_omap hdq_fck_hw = {
-	.hw = {
-		.clk = &hdq_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hdq_fck, hdq_fck_parent_names, aes2_ick_ops);
-
-static struct clk hdq_ick;
-
-static struct clk_hw_omap hdq_ick_hw = {
-	.hw = {
-		.clk = &hdq_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hdq_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk hecc_ck;
-
-static struct clk_hw_omap hecc_ck_hw = {
-	.hw = {
-		.clk = &hecc_ck,
-	},
-	.ops		= &clkhwops_am35xx_ipss_module_wait,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_HECC_VBUSP_CLK_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hecc_ck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk hsotgusb_fck_am35xx;
-
-static struct clk_hw_omap hsotgusb_fck_am35xx_hw = {
-	.hw = {
-		.clk = &hsotgusb_fck_am35xx,
-	},
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_USBOTG_FCLK_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hsotgusb_fck_am35xx, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk hsotgusb_ick_3430es1;
-
-static struct clk_hw_omap hsotgusb_ick_3430es1_hw = {
-	.hw = {
-		.clk = &hsotgusb_ick_3430es1,
-	},
-	.ops		= &clkhwops_iclk,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hsotgusb_ick_3430es1, ipss_ick_parent_names, aes2_ick_ops);
-
-static struct clk hsotgusb_ick_3430es2;
-
-static struct clk_hw_omap hsotgusb_ick_3430es2_hw = {
-	.hw = {
-		.clk = &hsotgusb_ick_3430es2,
-	},
-	.ops		= &clkhwops_omap3430es2_iclk_hsotgusb_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hsotgusb_ick_3430es2, ipss_ick_parent_names, aes2_ick_ops);
-
-static struct clk hsotgusb_ick_am35xx;
-
-static struct clk_hw_omap hsotgusb_ick_am35xx_hw = {
-	.hw = {
-		.clk = &hsotgusb_ick_am35xx,
-	},
-	.ops		= &clkhwops_am35xx_ipss_module_wait,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_USBOTG_VBUSP_CLK_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(hsotgusb_ick_am35xx, emac_ick_parent_names, aes2_ick_ops);
-
-static struct clk i2c1_fck;
-
-static struct clk_hw_omap i2c1_fck_hw = {
-	.hw = {
-		.clk = &i2c1_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c1_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk i2c1_ick;
-
-static struct clk_hw_omap i2c1_ick_hw = {
-	.hw = {
-		.clk = &i2c1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c1_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk i2c2_fck;
-
-static struct clk_hw_omap i2c2_fck_hw = {
-	.hw = {
-		.clk = &i2c2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c2_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk i2c2_ick;
-
-static struct clk_hw_omap i2c2_ick_hw = {
-	.hw = {
-		.clk = &i2c2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk i2c3_fck;
-
-static struct clk_hw_omap i2c3_fck_hw = {
-	.hw = {
-		.clk = &i2c3_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c3_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk i2c3_ick;
-
-static struct clk_hw_omap i2c3_ick_hw = {
-	.hw = {
-		.clk = &i2c3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(i2c3_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk icr_ick;
-
-static struct clk_hw_omap icr_ick_hw = {
-	.hw = {
-		.clk = &icr_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(icr_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk iva2_ck;
-
-static const char *iva2_ck_parent_names[] = {
-	"dpll2_m2_ck",
-};
-
-static struct clk_hw_omap iva2_ck_hw = {
-	.hw = {
-		.clk = &iva2_ck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
-	.clkdm_name	= "iva2_clkdm",
-};
-
-DEFINE_STRUCT_CLK(iva2_ck, iva2_ck_parent_names, aes2_ick_ops);
-
-static struct clk mad2d_ick;
-
-static struct clk_hw_omap mad2d_ick_hw = {
-	.hw = {
-		.clk = &mad2d_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mad2d_ick, core_l3_ick_parent_names, aes2_ick_ops);
-
-static struct clk mailboxes_ick;
-
-static struct clk_hw_omap mailboxes_ick_hw = {
-	.hw = {
-		.clk = &mailboxes_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mailboxes_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_15_clksel[] = {
-	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL },
-};
-
-static const char *mcbsp1_fck_parent_names[] = {
-	"core_96m_fck", "mcbsp_clks",
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_15_clksel,
-			 OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-			 OMAP2_MCBSP1_CLKS_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_MCBSP1_SHIFT, &clkhwops_wait,
-			 mcbsp1_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk mcbsp1_ick;
-
-static struct clk_hw_omap mcbsp1_ick_hw = {
-	.hw = {
-		.clk = &mcbsp1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcbsp1_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk per_96m_fck;
-
-DEFINE_STRUCT_CLK_HW_OMAP(per_96m_fck, "per_clkdm");
-DEFINE_STRUCT_CLK(per_96m_fck, cm_96m_fck_parent_names, core_l4_ick_ops);
-
-static const struct clksel mcbsp_234_clksel[] = {
-	{ .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL },
-};
-
-static const char *mcbsp2_fck_parent_names[] = {
-	"per_96m_fck", "mcbsp_clks",
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "per_clkdm", mcbsp_234_clksel,
-			 OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-			 OMAP2_MCBSP2_CLKS_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_MCBSP2_SHIFT, &clkhwops_wait,
-			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk mcbsp2_ick;
-
-static struct clk_hw_omap mcbsp2_ick_hw = {
-	.hw = {
-		.clk = &mcbsp2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcbsp2_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "per_clkdm", mcbsp_234_clksel,
-			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-			 OMAP2_MCBSP3_CLKS_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_MCBSP3_SHIFT, &clkhwops_wait,
-			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk mcbsp3_ick;
-
-static struct clk_hw_omap mcbsp3_ick_hw = {
-	.hw = {
-		.clk = &mcbsp3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcbsp3_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "per_clkdm", mcbsp_234_clksel,
-			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-			 OMAP2_MCBSP4_CLKS_MASK,
-			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-			 OMAP3430_EN_MCBSP4_SHIFT, &clkhwops_wait,
-			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk mcbsp4_ick;
-
-static struct clk_hw_omap mcbsp4_ick_hw = {
-	.hw = {
-		.clk = &mcbsp4_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcbsp4_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(mcbsp5_fck, "core_l4_clkdm", mcbsp_15_clksel,
-			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-			 OMAP2_MCBSP5_CLKS_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_MCBSP5_SHIFT, &clkhwops_wait,
-			 mcbsp1_fck_parent_names, clkout2_src_ck_ops);
-
-static struct clk mcbsp5_ick;
-
-static struct clk_hw_omap mcbsp5_ick_hw = {
-	.hw = {
-		.clk = &mcbsp5_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcbsp5_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mcspi1_fck;
-
-static struct clk_hw_omap mcspi1_fck_hw = {
-	.hw = {
-		.clk = &mcspi1_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi1_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk mcspi1_ick;
-
-static struct clk_hw_omap mcspi1_ick_hw = {
-	.hw = {
-		.clk = &mcspi1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi1_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mcspi2_fck;
-
-static struct clk_hw_omap mcspi2_fck_hw = {
-	.hw = {
-		.clk = &mcspi2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi2_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk mcspi2_ick;
-
-static struct clk_hw_omap mcspi2_ick_hw = {
-	.hw = {
-		.clk = &mcspi2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mcspi3_fck;
-
-static struct clk_hw_omap mcspi3_fck_hw = {
-	.hw = {
-		.clk = &mcspi3_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi3_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk mcspi3_ick;
-
-static struct clk_hw_omap mcspi3_ick_hw = {
-	.hw = {
-		.clk = &mcspi3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi3_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mcspi4_fck;
-
-static struct clk_hw_omap mcspi4_fck_hw = {
-	.hw = {
-		.clk = &mcspi4_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi4_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk mcspi4_ick;
-
-static struct clk_hw_omap mcspi4_ick_hw = {
-	.hw = {
-		.clk = &mcspi4_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mcspi4_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mmchs1_fck;
-
-static struct clk_hw_omap mmchs1_fck_hw = {
-	.hw = {
-		.clk = &mmchs1_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs1_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk mmchs1_ick;
-
-static struct clk_hw_omap mmchs1_ick_hw = {
-	.hw = {
-		.clk = &mmchs1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs1_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mmchs2_fck;
-
-static struct clk_hw_omap mmchs2_fck_hw = {
-	.hw = {
-		.clk = &mmchs2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs2_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk mmchs2_ick;
-
-static struct clk_hw_omap mmchs2_ick_hw = {
-	.hw = {
-		.clk = &mmchs2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk mmchs3_fck;
-
-static struct clk_hw_omap mmchs3_fck_hw = {
-	.hw = {
-		.clk = &mmchs3_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs3_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk mmchs3_ick;
-
-static struct clk_hw_omap mmchs3_ick_hw = {
-	.hw = {
-		.clk = &mmchs3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mmchs3_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk modem_fck;
-
-static struct clk_hw_omap modem_fck_hw = {
-	.hw = {
-		.clk = &modem_fck,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-};
-
-DEFINE_STRUCT_CLK(modem_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk mspro_fck;
-
-static struct clk_hw_omap mspro_fck_hw = {
-	.hw = {
-		.clk = &mspro_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mspro_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
-
-static struct clk mspro_ick;
-
-static struct clk_hw_omap mspro_ick_hw = {
-	.hw = {
-		.clk = &mspro_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(mspro_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk omap_192m_alwon_fck;
-
-DEFINE_STRUCT_CLK_HW_OMAP(omap_192m_alwon_fck, NULL);
-DEFINE_STRUCT_CLK(omap_192m_alwon_fck, omap_96m_alwon_fck_parent_names,
-		  core_ck_ops);
-
-static struct clk omap_32ksync_ick;
-
-static struct clk_hw_omap omap_32ksync_ick_hw = {
-	.hw = {
-		.clk = &omap_32ksync_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(omap_32ksync_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_36XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_36XX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_96m_alwon_fck_clksel[] = {
-	{ .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_96m_alwon_fck_3630;
-
-static const char *omap_96m_alwon_fck_3630_parent_names[] = {
-	"omap_192m_alwon_fck",
-};
-
-static const struct clk_ops omap_96m_alwon_fck_3630_ops = {
-	.set_rate	= &omap2_clksel_set_rate,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-};
-
-static struct clk_hw_omap omap_96m_alwon_fck_3630_hw = {
-	.hw = {
-		.clk = &omap_96m_alwon_fck_3630,
-	},
-	.clksel		= omap_96m_alwon_fck_clksel,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3630_CLKSEL_96M_MASK,
-};
-
-static struct clk omap_96m_alwon_fck_3630 = {
-	.name	= "omap_96m_alwon_fck",
-	.hw	= &omap_96m_alwon_fck_3630_hw.hw,
-	.parent_names	= omap_96m_alwon_fck_3630_parent_names,
-	.num_parents	= ARRAY_SIZE(omap_96m_alwon_fck_3630_parent_names),
-	.ops	= &omap_96m_alwon_fck_3630_ops,
-};
-
-static struct clk omapctrl_ick;
-
-static struct clk_hw_omap omapctrl_ick_hw = {
-	.hw = {
-		.clk = &omapctrl_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(omapctrl_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-DEFINE_CLK_DIVIDER(pclk_fck, "emu_src_ck", &emu_src_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_CLKSEL_PCLK_SHIFT, OMAP3430_CLKSEL_PCLK_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-DEFINE_CLK_DIVIDER(pclkx2_fck, "emu_src_ck", &emu_src_ck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_CLKSEL_PCLKX2_SHIFT, OMAP3430_CLKSEL_PCLKX2_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk per_48m_fck;
-
-DEFINE_STRUCT_CLK_HW_OMAP(per_48m_fck, "per_clkdm");
-DEFINE_STRUCT_CLK(per_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops);
-
-static struct clk security_l3_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(security_l3_ick, NULL);
-DEFINE_STRUCT_CLK(security_l3_ick, core_l3_ick_parent_names, core_ck_ops);
-
-static struct clk pka_ick;
-
-static const char *pka_ick_parent_names[] = {
-	"security_l3_ick",
-};
-
-static struct clk_hw_omap pka_ick_hw = {
-	.hw = {
-		.clk = &pka_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(pka_ick, pka_ick_parent_names, aes1_ick_ops);
-
-DEFINE_CLK_DIVIDER(rm_ick, "l4_ick", &l4_ick, 0x0,
-		   OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-		   OMAP3430_CLKSEL_RM_SHIFT, OMAP3430_CLKSEL_RM_WIDTH,
-		   CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk rng_ick;
-
-static struct clk_hw_omap rng_ick_hw = {
-	.hw = {
-		.clk = &rng_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(rng_ick, aes1_ick_parent_names, aes1_ick_ops);
-
-static struct clk sad2d_ick;
-
-static struct clk_hw_omap sad2d_ick_hw = {
-	.hw = {
-		.clk = &sad2d_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sad2d_ick, core_l3_ick_parent_names, aes2_ick_ops);
-
-static struct clk sdrc_ick;
-
-static struct clk_hw_omap sdrc_ick_hw = {
-	.hw = {
-		.clk = &sdrc_ick,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sdrc_ick, ipss_ick_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate sgx_core_rates[] = {
-	{ .div = 2, .val = 5, .flags = RATE_IN_36XX },
-	{ .div = 3, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate sgx_96m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate sgx_192m_rates[] = {
-	{ .div = 1, .val = 4, .flags = RATE_IN_36XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate sgx_corex2_rates[] = {
-	{ .div = 3, .val = 6, .flags = RATE_IN_36XX },
-	{ .div = 5, .val = 7, .flags = RATE_IN_36XX },
-	{ .div = 0 }
-};
-
-static const struct clksel sgx_clksel[] = {
-	{ .parent = &core_ck, .rates = sgx_core_rates },
-	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
-	{ .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
-	{ .parent = &corex2_fck, .rates = sgx_corex2_rates },
-	{ .parent = NULL },
-};
-
-static const char *sgx_fck_parent_names[] = {
-	"core_ck", "cm_96m_fck", "omap_192m_alwon_fck", "corex2_fck",
-};
-
-static struct clk sgx_fck;
-
-static const struct clk_ops sgx_fck_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-	.get_parent	= &omap2_clksel_find_parent_index,
-	.set_parent	= &omap2_clksel_set_parent,
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(sgx_fck, "sgx_clkdm", sgx_clksel,
-			 OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
-			 OMAP3430ES2_CLKSEL_SGX_MASK,
-			 OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
-			 OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
-			 &clkhwops_wait, sgx_fck_parent_names, sgx_fck_ops);
-
-static struct clk sgx_ick;
-
-static struct clk_hw_omap sgx_ick_hw = {
-	.hw = {
-		.clk = &sgx_ick,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
-	.clkdm_name	= "sgx_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sgx_ick, core_l3_ick_parent_names, aes2_ick_ops);
-
-static struct clk sha11_ick;
-
-static struct clk_hw_omap sha11_ick_hw = {
-	.hw = {
-		.clk = &sha11_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(sha11_ick, aes1_ick_parent_names, aes1_ick_ops);
-
-static struct clk sha12_ick;
-
-static struct clk_hw_omap sha12_ick_hw = {
-	.hw = {
-		.clk = &sha12_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sha12_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk sr1_fck;
-
-static struct clk_hw_omap sr1_fck_hw = {
-	.hw = {
-		.clk = &sr1_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sr1_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk sr2_fck;
-
-static struct clk_hw_omap sr2_fck_hw = {
-	.hw = {
-		.clk = &sr2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(sr2_fck, cpefuse_fck_parent_names, aes2_ick_ops);
-
-static struct clk sr_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(sr_l4_ick, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(sr_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
-
-static struct clk ssi_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(ssi_l4_ick, "core_l4_clkdm");
-DEFINE_STRUCT_CLK(ssi_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
-
-static struct clk ssi_ick_3430es1;
-
-static const char *ssi_ick_3430es1_parent_names[] = {
-	"ssi_l4_ick",
-};
-
-static struct clk_hw_omap ssi_ick_3430es1_hw = {
-	.hw = {
-		.clk = &ssi_ick_3430es1,
-	},
-	.ops		= &clkhwops_iclk,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(ssi_ick_3430es1, ssi_ick_3430es1_parent_names, aes2_ick_ops);
-
-static struct clk ssi_ick_3430es2;
-
-static struct clk_hw_omap ssi_ick_3430es2_hw = {
-	.hw = {
-		.clk = &ssi_ick_3430es2,
-	},
-	.ops		= &clkhwops_omap3430es2_iclk_ssi_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(ssi_ick_3430es2, ssi_ick_3430es1_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate ssi_ssr_corex2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_clksel[] = {
-	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
-	{ .parent = NULL },
-};
-
-static const char *ssi_ssr_fck_3430es1_parent_names[] = {
-	"corex2_fck",
-};
-
-static const struct clk_ops ssi_ssr_fck_3430es1_ops = {
-	.init		= &omap2_init_clk_clkdm,
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es1, "core_l4_clkdm",
-			 ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_SSI_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_SSI_SHIFT,
-			 NULL, ssi_ssr_fck_3430es1_parent_names,
-			 ssi_ssr_fck_3430es1_ops);
-
-DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es2, "core_l4_clkdm",
-			 ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-			 OMAP3430_CLKSEL_SSI_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-			 OMAP3430_EN_SSI_SHIFT,
-			 NULL, ssi_ssr_fck_3430es1_parent_names,
-			 ssi_ssr_fck_3430es1_ops);
-
-DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es1, "ssi_ssr_fck_3430es1",
-			&ssi_ssr_fck_3430es1, 0x0, 1, 2);
-
-DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es2, "ssi_ssr_fck_3430es2",
-			&ssi_ssr_fck_3430es2, 0x0, 1, 2);
-
-static struct clk sys_clkout1;
-
-static const char *sys_clkout1_parent_names[] = {
-	"osc_sys_ck",
-};
-
-static struct clk_hw_omap sys_clkout1_hw = {
-	.hw = {
-		.clk = &sys_clkout1,
-	},
-	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(sys_clkout1, sys_clkout1_parent_names, aes1_ick_ops);
-
-DEFINE_CLK_DIVIDER(sys_clkout2, "clkout2_src_ck", &clkout2_src_ck, 0x0,
-		   OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_DIV_SHIFT,
-		   OMAP3430_CLKOUT2_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
-
-DEFINE_CLK_MUX(traceclk_src_fck, emu_src_ck_parent_names, NULL, 0x0,
-	       OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	       OMAP3430_TRACE_MUX_CTRL_SHIFT, OMAP3430_TRACE_MUX_CTRL_WIDTH,
-	       0x0, NULL);
-
-DEFINE_CLK_DIVIDER(traceclk_fck, "traceclk_src_fck", &traceclk_src_fck, 0x0,
-		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-		   OMAP3430_CLKSEL_TRACECLK_SHIFT,
-		   OMAP3430_CLKSEL_TRACECLK_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
-
-static struct clk ts_fck;
-
-static struct clk_hw_omap ts_fck_hw = {
-	.hw = {
-		.clk = &ts_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(ts_fck, wkup_32k_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart1_fck;
-
-static struct clk_hw_omap uart1_fck_hw = {
-	.hw = {
-		.clk = &uart1_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart1_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart1_ick;
-
-static struct clk_hw_omap uart1_ick_hw = {
-	.hw = {
-		.clk = &uart1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart1_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk uart2_fck;
-
-static struct clk_hw_omap uart2_fck_hw = {
-	.hw = {
-		.clk = &uart2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart2_fck, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart2_ick;
-
-static struct clk_hw_omap uart2_ick_hw = {
-	.hw = {
-		.clk = &uart2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart2_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static struct clk uart3_fck;
-
-static const char *uart3_fck_parent_names[] = {
-	"per_48m_fck",
-};
-
-static struct clk_hw_omap uart3_fck_hw = {
-	.hw = {
-		.clk = &uart3_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart3_fck, uart3_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart3_ick;
-
-static struct clk_hw_omap uart3_ick_hw = {
-	.hw = {
-		.clk = &uart3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart3_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk uart4_fck;
-
-static struct clk_hw_omap uart4_fck_hw = {
-	.hw = {
-		.clk = &uart4_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart4_fck, uart3_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart4_fck_am35xx;
-
-static struct clk_hw_omap uart4_fck_am35xx_hw = {
-	.hw = {
-		.clk = &uart4_fck_am35xx,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= AM35XX_EN_UART4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart4_fck_am35xx, fshostusb_fck_parent_names, aes2_ick_ops);
-
-static struct clk uart4_ick;
-
-static struct clk_hw_omap uart4_ick_hw = {
-	.hw = {
-		.clk = &uart4_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart4_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-static struct clk uart4_ick_am35xx;
-
-static struct clk_hw_omap uart4_ick_am35xx_hw = {
-	.hw = {
-		.clk = &uart4_ick_am35xx,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= AM35XX_EN_UART4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(uart4_ick_am35xx, aes2_ick_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate div2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel usb_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static const char *usb_l4_ick_parent_names[] = {
-	"l4_ick",
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_clksel,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-			 OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
-			 OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-			 OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-			 &clkhwops_iclk_wait, usb_l4_ick_parent_names,
-			 ssi_ssr_fck_3430es1_ops);
-
-static struct clk usbhost_120m_fck;
-
-static const char *usbhost_120m_fck_parent_names[] = {
-	"dpll5_m2_ck",
-};
-
-static struct clk_hw_omap usbhost_120m_fck_hw = {
-	.hw = {
-		.clk = &usbhost_120m_fck,
-	},
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usbhost_120m_fck, usbhost_120m_fck_parent_names,
-		  aes2_ick_ops);
-
-static struct clk usbhost_48m_fck;
-
-static struct clk_hw_omap usbhost_48m_fck_hw = {
-	.hw = {
-		.clk = &usbhost_48m_fck,
-	},
-	.ops		= &clkhwops_omap3430es2_dss_usbhost_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usbhost_48m_fck, core_48m_fck_parent_names, aes2_ick_ops);
-
-static struct clk usbhost_ick;
-
-static struct clk_hw_omap usbhost_ick_hw = {
-	.hw = {
-		.clk = &usbhost_ick,
-	},
-	.ops		= &clkhwops_omap3430es2_iclk_dss_usbhost_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usbhost_ick, security_l4_ick2_parent_names, aes2_ick_ops);
-
-static struct clk usbtll_fck;
-
-static struct clk_hw_omap usbtll_fck_hw = {
-	.hw = {
-		.clk = &usbtll_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usbtll_fck, usbhost_120m_fck_parent_names, aes2_ick_ops);
-
-static struct clk usbtll_ick;
-
-static struct clk_hw_omap usbtll_ick_hw = {
-	.hw = {
-		.clk = &usbtll_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usbtll_ick, aes2_ick_parent_names, aes2_ick_ops);
-
-static const struct clksel_rate usim_96m_rates[] = {
-	{ .div = 2, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 5, .flags = RATE_IN_3XXX },
-	{ .div = 10, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate usim_120m_rates[] = {
-	{ .div = 4, .val = 7, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
-	{ .div = 16, .val = 9, .flags = RATE_IN_3XXX },
-	{ .div = 20, .val = 10, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel usim_clksel[] = {
-	{ .parent = &omap_96m_fck, .rates = usim_96m_rates },
-	{ .parent = &dpll5_m2_ck, .rates = usim_120m_rates },
-	{ .parent = &sys_ck, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static const char *usim_fck_parent_names[] = {
-	"omap_96m_fck", "dpll5_m2_ck", "sys_ck",
-};
-
-static struct clk usim_fck;
-
-static const struct clk_ops usim_fck_ops = {
-	.enable		= &omap2_dflt_clk_enable,
-	.disable	= &omap2_dflt_clk_disable,
-	.is_enabled	= &omap2_dflt_clk_is_enabled,
-	.recalc_rate	= &omap2_clksel_recalc,
-	.get_parent	= &omap2_clksel_find_parent_index,
-	.set_parent	= &omap2_clksel_set_parent,
-};
-
-DEFINE_CLK_OMAP_MUX_GATE(usim_fck, NULL, usim_clksel,
-			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-			 OMAP3430ES2_CLKSEL_USIMOCP_MASK,
-			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-			 OMAP3430ES2_EN_USIMOCP_SHIFT, &clkhwops_wait,
-			 usim_fck_parent_names, usim_fck_ops);
-
-static struct clk usim_ick;
-
-static struct clk_hw_omap usim_ick_hw = {
-	.hw = {
-		.clk = &usim_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(usim_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-static struct clk vpfe_fck;
-
-static const char *vpfe_fck_parent_names[] = {
-	"pclk_ck",
-};
-
-static struct clk_hw_omap vpfe_fck_hw = {
-	.hw = {
-		.clk = &vpfe_fck,
-	},
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_VPFE_FCLK_SHIFT,
-};
-
-DEFINE_STRUCT_CLK(vpfe_fck, vpfe_fck_parent_names, aes1_ick_ops);
-
-static struct clk vpfe_ick;
-
-static struct clk_hw_omap vpfe_ick_hw = {
-	.hw = {
-		.clk = &vpfe_ick,
-	},
-	.ops		= &clkhwops_am35xx_ipss_module_wait,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_VPFE_VBUSP_CLK_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-};
-
-DEFINE_STRUCT_CLK(vpfe_ick, emac_ick_parent_names, aes2_ick_ops);
-
-static struct clk wdt1_fck;
-
-DEFINE_STRUCT_CLK_HW_OMAP(wdt1_fck, "wkup_clkdm");
-DEFINE_STRUCT_CLK(wdt1_fck, gpt12_fck_parent_names, core_l4_ick_ops);
-
-static struct clk wdt1_ick;
-
-static struct clk_hw_omap wdt1_ick_hw = {
-	.hw = {
-		.clk = &wdt1_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(wdt1_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-static struct clk wdt2_fck;
-
-static struct clk_hw_omap wdt2_fck_hw = {
-	.hw = {
-		.clk = &wdt2_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(wdt2_fck, gpio1_dbck_parent_names, aes2_ick_ops);
-
-static struct clk wdt2_ick;
-
-static struct clk_hw_omap wdt2_ick_hw = {
-	.hw = {
-		.clk = &wdt2_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-DEFINE_STRUCT_CLK(wdt2_ick, gpio1_ick_parent_names, aes2_ick_ops);
-
-static struct clk wdt3_fck;
-
-static struct clk_hw_omap wdt3_fck_hw = {
-	.hw = {
-		.clk = &wdt3_fck,
-	},
-	.ops		= &clkhwops_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(wdt3_fck, gpio2_dbck_parent_names, aes2_ick_ops);
-
-static struct clk wdt3_ick;
-
-static struct clk_hw_omap wdt3_ick_hw = {
-	.hw = {
-		.clk = &wdt3_ick,
-	},
-	.ops		= &clkhwops_iclk_wait,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-};
-
-DEFINE_STRUCT_CLK(wdt3_ick, gpio2_ick_parent_names, aes2_ick_ops);
-
-/*
- * clocks specific to omap3430es1
- */
-static struct omap_clk omap3430es1_clks[] = {
-	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck),
-	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck),
-	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick),
-	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck),
-	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck),
-	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck),
-	CLK(NULL,	"fshostusb_fck", &fshostusb_fck),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1),
-	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es1),
-	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es1),
-	CLK(NULL,	"fac_ick",	&fac_ick),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick),
-	CLK(NULL,	"dss1_alwon_fck",	&dss1_alwon_fck_3430es1),
-	CLK("omapdss_dss",	"ick",		&dss_ick_3430es1),
-	CLK(NULL,	"dss_ick",		&dss_ick_3430es1),
-};
-
-/*
- * clocks specific to am35xx
- */
-static struct omap_clk am35xx_clks[] = {
-	CLK(NULL,	"ipss_ick",	&ipss_ick),
-	CLK(NULL,	"rmii_ck",	&rmii_ck),
-	CLK(NULL,	"pclk_ck",	&pclk_ck),
-	CLK(NULL,	"emac_ick",	&emac_ick),
-	CLK(NULL,	"emac_fck",	&emac_fck),
-	CLK("davinci_emac.0",	NULL,	&emac_ick),
-	CLK("davinci_mdio.0",	NULL,	&emac_fck),
-	CLK("vpfe-capture",	"master",	&vpfe_ick),
-	CLK("vpfe-capture",	"slave",	&vpfe_fck),
-	CLK(NULL,	"hsotgusb_ick",		&hsotgusb_ick_am35xx),
-	CLK(NULL,	"hsotgusb_fck",		&hsotgusb_fck_am35xx),
-	CLK(NULL,	"hecc_ck",	&hecc_ck),
-	CLK(NULL,	"uart4_ick",	&uart4_ick_am35xx),
-	CLK(NULL,	"uart4_fck",	&uart4_fck_am35xx),
-};
-
-/*
- * clocks specific to omap36xx
- */
-static struct omap_clk omap36xx_clks[] = {
-	CLK(NULL,	"omap_192m_alwon_fck", &omap_192m_alwon_fck),
-	CLK(NULL,	"uart4_fck",	&uart4_fck),
-};
-
-/*
- * clocks common to omap36xx omap34xx
- */
-static struct omap_clk omap34xx_omap36xx_clks[] = {
-	CLK(NULL,	"aes1_ick",	&aes1_ick),
-	CLK("omap_rng",	"ick",		&rng_ick),
-	CLK("omap3-rom-rng",	"ick",	&rng_ick),
-	CLK(NULL,	"sha11_ick",	&sha11_ick),
-	CLK(NULL,	"des1_ick",	&des1_ick),
-	CLK(NULL,	"cam_mclk",	&cam_mclk),
-	CLK(NULL,	"cam_ick",	&cam_ick),
-	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck),
-	CLK(NULL,	"security_l3_ick", &security_l3_ick),
-	CLK(NULL,	"pka_ick",	&pka_ick),
-	CLK(NULL,	"icr_ick",	&icr_ick),
-	CLK("omap-aes",	"ick",	&aes2_ick),
-	CLK("omap-sham",	"ick",	&sha12_ick),
-	CLK(NULL,	"des2_ick",	&des2_ick),
-	CLK(NULL,	"mspro_ick",	&mspro_ick),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick),
-	CLK(NULL,	"sr1_fck",	&sr1_fck),
-	CLK(NULL,	"sr2_fck",	&sr2_fck),
-	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick),
-	CLK(NULL,	"security_l4_ick2", &security_l4_ick2),
-	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick),
-	CLK(NULL,	"dpll2_fck",	&dpll2_fck),
-	CLK(NULL,	"iva2_ck",	&iva2_ck),
-	CLK(NULL,	"modem_fck",	&modem_fck),
-	CLK(NULL,	"sad2d_ick",	&sad2d_ick),
-	CLK(NULL,	"mad2d_ick",	&mad2d_ick),
-	CLK(NULL,	"mspro_fck",	&mspro_fck),
-	CLK(NULL,	"dpll2_ck",	&dpll2_ck),
-	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck),
-};
-
-/*
- * clocks common to omap36xx and omap3430es2plus
- */
-static struct omap_clk omap36xx_omap3430es2plus_clks[] = {
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2),
-	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es2),
-	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es2),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2),
-	CLK(NULL,	"usim_fck",	&usim_fck),
-	CLK(NULL,	"usim_ick",	&usim_ick),
-};
-
-/*
- * clocks common to am35xx omap36xx and omap3430es2plus
- */
-static struct omap_clk omap36xx_am35xx_omap3430es2plus_clks[] = {
-	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck),
-	CLK(NULL,	"dpll5_ck",	&dpll5_ck),
-	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck),
-	CLK(NULL,	"sgx_fck",	&sgx_fck),
-	CLK(NULL,	"sgx_ick",	&sgx_ick),
-	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck),
-	CLK(NULL,	"ts_fck",	&ts_fck),
-	CLK(NULL,	"usbtll_fck",	&usbtll_fck),
-	CLK(NULL,	"usbtll_ick",	&usbtll_ick),
-	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick),
-	CLK(NULL,	"mmchs3_ick",	&mmchs3_ick),
-	CLK(NULL,	"mmchs3_fck",	&mmchs3_fck),
-	CLK(NULL,	"dss1_alwon_fck",	&dss1_alwon_fck_3430es2),
-	CLK("omapdss_dss",	"ick",		&dss_ick_3430es2),
-	CLK(NULL,	"dss_ick",		&dss_ick_3430es2),
-	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck),
-	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck),
-	CLK(NULL,	"usbhost_ick",	&usbhost_ick),
-};
-
-/*
- * common clocks
- */
-static struct omap_clk omap3xxx_clks[] = {
-	CLK(NULL,	"apb_pclk",	&dummy_apb_pclk),
-	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck),
-	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck),
-	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck),
-	CLK(NULL,	"virt_19200000_ck", &virt_19200000_ck),
-	CLK(NULL,	"virt_26000000_ck", &virt_26000000_ck),
-	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck),
-	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck),
-	CLK("twl",	"fck",		&osc_sys_ck),
-	CLK(NULL,	"sys_ck",	&sys_ck),
-	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck),
-	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck),
-	CLK(NULL,	"sys_altclk",	&sys_altclk),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks),
-	CLK(NULL,	"sys_clkout1",	&sys_clkout1),
-	CLK(NULL,	"dpll1_ck",	&dpll1_ck),
-	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck),
-	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck),
-	CLK(NULL,	"dpll3_ck",	&dpll3_ck),
-	CLK(NULL,	"core_ck",	&core_ck),
-	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck),
-	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck),
-	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck),
-	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck),
-	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck),
-	CLK(NULL,	"dpll4_ck",	&dpll4_ck),
-	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck),
-	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck),
-	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck),
-	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck),
-	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck),
-	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck),
-	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck),
-	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck),
-	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck),
-	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck),
-	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck),
-	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck),
-	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck),
-	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck),
-	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck),
-	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck),
-	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck),
-	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2),
-	CLK(NULL,	"corex2_fck",	&corex2_fck),
-	CLK(NULL,	"dpll1_fck",	&dpll1_fck),
-	CLK(NULL,	"mpu_ck",	&mpu_ck),
-	CLK(NULL,	"arm_fck",	&arm_fck),
-	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck),
-	CLK(NULL,	"l3_ick",	&l3_ick),
-	CLK(NULL,	"l4_ick",	&l4_ick),
-	CLK(NULL,	"rm_ick",	&rm_ick),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck),
-	CLK(NULL,	"core_96m_fck",	&core_96m_fck),
-	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck),
-	CLK(NULL,	"mmchs1_fck",	&mmchs1_fck),
-	CLK(NULL,	"i2c3_fck",	&i2c3_fck),
-	CLK(NULL,	"i2c2_fck",	&i2c2_fck),
-	CLK(NULL,	"i2c1_fck",	&i2c1_fck),
-	CLK(NULL,	"mcbsp5_fck",	&mcbsp5_fck),
-	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck),
-	CLK(NULL,	"core_48m_fck",	&core_48m_fck),
-	CLK(NULL,	"mcspi4_fck",	&mcspi4_fck),
-	CLK(NULL,	"mcspi3_fck",	&mcspi3_fck),
-	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck),
-	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck),
-	CLK(NULL,	"uart2_fck",	&uart2_fck),
-	CLK(NULL,	"uart1_fck",	&uart1_fck),
-	CLK(NULL,	"core_12m_fck",	&core_12m_fck),
-	CLK("omap_hdq.0",	"fck",	&hdq_fck),
-	CLK(NULL,	"hdq_fck",	&hdq_fck),
-	CLK(NULL,	"core_l3_ick",	&core_l3_ick),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck),
-	CLK(NULL,	"core_l4_ick",	&core_l4_ick),
-	CLK("omap_hsmmc.1",	"ick",	&mmchs2_ick),
-	CLK("omap_hsmmc.0",	"ick",	&mmchs1_ick),
-	CLK(NULL,	"mmchs2_ick",	&mmchs2_ick),
-	CLK(NULL,	"mmchs1_ick",	&mmchs1_ick),
-	CLK("omap_hdq.0", "ick",	&hdq_ick),
-	CLK(NULL,	"hdq_ick",	&hdq_ick),
-	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick),
-	CLK(NULL,	"mcspi4_ick",	&mcspi4_ick),
-	CLK(NULL,	"mcspi3_ick",	&mcspi3_ick),
-	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick),
-	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick),
-	CLK("omap_i2c.3", "ick",	&i2c3_ick),
-	CLK("omap_i2c.2", "ick",	&i2c2_ick),
-	CLK("omap_i2c.1", "ick",	&i2c1_ick),
-	CLK(NULL,	"i2c3_ick",	&i2c3_ick),
-	CLK(NULL,	"i2c2_ick",	&i2c2_ick),
-	CLK(NULL,	"i2c1_ick",	&i2c1_ick),
-	CLK(NULL,	"uart2_ick",	&uart2_ick),
-	CLK(NULL,	"uart1_ick",	&uart1_ick),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick),
-	CLK(NULL,	"mcbsp5_ick",	&mcbsp5_ick),
-	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick),
-	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck),
-	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck),
-	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck),
-	CLK(NULL,	"init_60m_fclk",	&dummy_ck),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck),
-	CLK(NULL,	"aes2_ick",	&aes2_ick),
-	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck),
-	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck),
-	CLK(NULL,	"sha12_ick",	&sha12_ick),
-	CLK(NULL,	"wdt2_fck",		&wdt2_fck),
-	CLK("omap_wdt",	"ick",		&wdt2_ick),
-	CLK(NULL,	"wdt2_ick",	&wdt2_ick),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick),
-	CLK(NULL,	"gpio1_ick",	&gpio1_ick),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick),
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick),
-	CLK(NULL,	"per_96m_fck",	&per_96m_fck),
-	CLK(NULL,	"per_48m_fck",	&per_48m_fck),
-	CLK(NULL,	"uart3_fck",	&uart3_fck),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck),
-	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck),
-	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck),
-	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck),
-	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck),
-	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck),
-	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck),
-	CLK(NULL,	"per_l4_ick",	&per_l4_ick),
-	CLK(NULL,	"gpio6_ick",	&gpio6_ick),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick),
-	CLK(NULL,	"gpio4_ick",	&gpio4_ick),
-	CLK(NULL,	"gpio3_ick",	&gpio3_ick),
-	CLK(NULL,	"gpio2_ick",	&gpio2_ick),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick),
-	CLK(NULL,	"uart3_ick",	&uart3_ick),
-	CLK(NULL,	"uart4_ick",	&uart4_ick),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick),
-	CLK(NULL,	"mcbsp4_ick",	&mcbsp2_ick),
-	CLK(NULL,	"mcbsp3_ick",	&mcbsp3_ick),
-	CLK(NULL,	"mcbsp2_ick",	&mcbsp4_ick),
-	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck),
-	CLK(NULL,	"mcbsp3_fck",	&mcbsp3_fck),
-	CLK(NULL,	"mcbsp4_fck",	&mcbsp4_fck),
-	CLK("etb",	"emu_src_ck",	&emu_src_ck),
-	CLK(NULL,	"emu_src_ck",	&emu_src_ck),
-	CLK(NULL,	"pclk_fck",	&pclk_fck),
-	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck),
-	CLK(NULL,	"atclk_fck",	&atclk_fck),
-	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck),
-	CLK(NULL,	"traceclk_fck",	&traceclk_fck),
-	CLK(NULL,	"secure_32k_fck", &secure_32k_fck),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck),
-	CLK(NULL,	"wdt1_fck",	&wdt1_fck),
-	CLK(NULL,	"timer_32k_ck",	&omap_32k_fck),
-	CLK(NULL,	"timer_sys_ck",	&sys_ck),
-	CLK(NULL,	"cpufreq_ck",	&dpll1_ck),
-};
-
-static const char *enable_init_clks[] = {
-	"sdrc_ick",
-	"gpmc_fck",
-	"omapctrl_ick",
-};
-
-int __init omap3xxx_clk_init(void)
-{
-	if (omap3_has_192mhz_clk())
-		omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
-
-	if (cpu_is_omap3630()) {
-		dpll3_m3x2_ck = dpll3_m3x2_ck_3630;
-		dpll4_m2x2_ck = dpll4_m2x2_ck_3630;
-		dpll4_m3x2_ck = dpll4_m3x2_ck_3630;
-		dpll4_m4x2_ck = dpll4_m4x2_ck_3630;
-		dpll4_m5x2_ck = dpll4_m5x2_ck_3630;
-		dpll4_m6x2_ck = dpll4_m6x2_ck_3630;
-	}
-
-	/*
-	 * XXX This type of dynamic rewriting of the clock tree is
-	 * deprecated and should be revised soon.
-	 */
-	if (cpu_is_omap3630())
-		dpll4_dd = dpll4_dd_3630;
-	else
-		dpll4_dd = dpll4_dd_34xx;
-
-
-	/*
-	 * 3505 must be tested before 3517, since 3517 returns true
-	 * for both AM3517 chips and AM3517 family chips, which
-	 * includes 3505.  Unfortunately there's no obvious family
-	 * test for 3517/3505 :-(
-	 */
-	if (soc_is_am35xx()) {
-		cpu_mask = RATE_IN_34XX;
-		omap_clocks_register(am35xx_clks, ARRAY_SIZE(am35xx_clks));
-		omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks,
-				     ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks));
-		omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks));
-	} else if (cpu_is_omap3630()) {
-		cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
-		omap_clocks_register(omap36xx_clks, ARRAY_SIZE(omap36xx_clks));
-		omap_clocks_register(omap36xx_omap3430es2plus_clks,
-				     ARRAY_SIZE(omap36xx_omap3430es2plus_clks));
-		omap_clocks_register(omap34xx_omap36xx_clks,
-				     ARRAY_SIZE(omap34xx_omap36xx_clks));
-		omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks,
-				     ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks));
-		omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks));
-	} else if (cpu_is_omap34xx()) {
-		if (omap_rev() == OMAP3430_REV_ES1_0) {
-			cpu_mask = RATE_IN_3430ES1;
-			omap_clocks_register(omap3430es1_clks,
-					     ARRAY_SIZE(omap3430es1_clks));
-			omap_clocks_register(omap34xx_omap36xx_clks,
-					     ARRAY_SIZE(omap34xx_omap36xx_clks));
-			omap_clocks_register(omap3xxx_clks,
-					     ARRAY_SIZE(omap3xxx_clks));
-		} else {
-			/*
-			 * Assume that anything that we haven't matched yet
-			 * has 3430ES2-type clocks.
-			 */
-			cpu_mask = RATE_IN_3430ES2PLUS;
-			omap_clocks_register(omap34xx_omap36xx_clks,
-					     ARRAY_SIZE(omap34xx_omap36xx_clks));
-			omap_clocks_register(omap36xx_omap3430es2plus_clks,
-					     ARRAY_SIZE(omap36xx_omap3430es2plus_clks));
-			omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks,
-					     ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks));
-			omap_clocks_register(omap3xxx_clks,
-					     ARRAY_SIZE(omap3xxx_clks));
-		}
-	} else {
-		WARN(1, "clock: could not identify OMAP3 variant\n");
-	}
-
-		omap2_clk_disable_autoidle_all();
-
-	omap2_clk_enable_init_clocks(enable_init_clks,
-				     ARRAY_SIZE(enable_init_clks));
-
-	pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
-		(clk_get_rate(&osc_sys_ck) / 1000000),
-		(clk_get_rate(&osc_sys_ck) / 100000) % 10,
-		(clk_get_rate(&core_ck) / 1000000),
-		(clk_get_rate(&arm_fck) / 1000000));
-
-	/*
-	 * Lock DPLL5 -- here only until other device init code can
-	 * handle this
-	 */
-	if (omap_rev() >= OMAP3430_REV_ES2_0)
-		omap3_clk_lock_dpll5();
-
-	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
-	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
-	arm_fck_p = clk_get(NULL, "arm_fck");
-
-	return 0;
-}

+ 0 - 16
arch/arm/mach-omap2/clock.c

@@ -23,7 +23,6 @@
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
-#include <linux/clk-private.h>
 #include <asm/cpu.h>
 
 #include <trace/events/power.h>
@@ -632,21 +631,6 @@ const struct clk_hw_omap_ops clkhwops_wait = {
 	.find_companion	= omap2_clk_dflt_find_companion,
 };
 
-/**
- * omap_clocks_register - register an array of omap_clk
- * @ocs: pointer to an array of omap_clk to register
- */
-void __init omap_clocks_register(struct omap_clk oclks[], int cnt)
-{
-	struct omap_clk *c;
-
-	for (c = oclks; c < oclks + cnt; c++) {
-		clkdev_add(&c->lk);
-		if (!__clk_init(NULL, c->lk.clk))
-			omap2_init_clk_hw_omap_clocks(c->lk.clk);
-	}
-}
-
 /**
  * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
  * @mpurate_ck_name: clk name of the clock to change rate

+ 8 - 6
arch/arm/mach-omap2/clock.h

@@ -40,23 +40,29 @@ struct omap_clk {
 struct clockdomain;
 
 #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name)	\
-	static struct clk _name = {				\
+	static struct clk_core _name##_core = {			\
 		.name = #_name,					\
 		.hw = &_name##_hw.hw,				\
 		.parent_names = _parent_array_name,		\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.ops = &_clkops_name,				\
+	};							\
+	static struct clk _name = {				\
+		.core = &_name##_core,				\
 	};
 
 #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name,	\
 				_clkops_name, _flags)		\
-	static struct clk _name = {				\
+	static struct clk_core _name##_core = {			\
 		.name = #_name,					\
 		.hw = &_name##_hw.hw,				\
 		.parent_names = _parent_array_name,		\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.ops = &_clkops_name,				\
 		.flags = _flags,				\
+	};							\
+	static struct clk _name = {				\
+		.core = &_name##_core,				\
 	};
 
 #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name)		\
@@ -238,7 +244,6 @@ struct ti_clk_features {
 extern struct ti_clk_features ti_clk_features;
 
 extern const struct clkops clkops_omap2_dflt_wait;
-extern const struct clkops clkops_dummy;
 extern const struct clkops clkops_omap2_dflt;
 
 extern struct clk_functions omap2_clk_functions;
@@ -247,7 +252,6 @@ extern const struct clksel_rate gpt_32k_rates[];
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate dsp_ick_rates[];
-extern struct clk dummy_ck;
 
 extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
 extern const struct clk_hw_omap_ops clkhwops_wait;
@@ -272,7 +276,5 @@ extern void __iomem *clk_memmaps[];
 extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
-extern void omap_clocks_register(struct omap_clk *oclks, int cnt);
-
 void __init ti_clk_init_features(void);
 #endif

+ 0 - 11
arch/arm/mach-omap2/clock_common_data.c

@@ -16,7 +16,6 @@
  * OMAP3xxx clock definition files.
  */
 
-#include <linux/clk-private.h>
 #include "clock.h"
 
 /* clksel_rate data common to 24xx/343x */
@@ -114,13 +113,3 @@ const struct clksel_rate div31_1to31_rates[] = {
 	{ .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
 	{ .div = 0 },
 };
-
-/* Clocks shared between various OMAP SoCs */
-
-static struct clk_ops dummy_ck_ops = {};
-
-struct clk dummy_ck = {
-	.name = "dummy_clk",
-	.ops = &dummy_ck_ops,
-	.flags = CLK_IS_BASIC,
-};

+ 8 - 5
arch/arm/mach-omap2/dpll3xxx.c

@@ -410,7 +410,7 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw)
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	int r;
 	struct dpll_data *dd;
-	struct clk *parent;
+	struct clk_hw *parent;
 
 	dd = clk->dpll_data;
 	if (!dd)
@@ -427,13 +427,13 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw)
 		}
 	}
 
-	parent = __clk_get_parent(hw->clk);
+	parent = __clk_get_hw(__clk_get_parent(hw->clk));
 
 	if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
-		WARN_ON(parent != dd->clk_bypass);
+		WARN_ON(parent != __clk_get_hw(dd->clk_bypass));
 		r = _omap3_noncore_dpll_bypass(clk);
 	} else {
-		WARN_ON(parent != dd->clk_ref);
+		WARN_ON(parent != __clk_get_hw(dd->clk_ref));
 		r = _omap3_noncore_dpll_lock(clk);
 	}
 
@@ -473,6 +473,8 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
  * in failure.
  */
 long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long min_rate,
+				       unsigned long max_rate,
 				       unsigned long *best_parent_rate,
 				       struct clk_hw **best_parent_clk)
 {
@@ -549,7 +551,8 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
 	if (!dd)
 		return -EINVAL;
 
-	if (__clk_get_parent(hw->clk) != dd->clk_ref)
+	if (__clk_get_hw(__clk_get_parent(hw->clk)) !=
+	    __clk_get_hw(dd->clk_ref))
 		return -EINVAL;
 
 	if (dd->last_rounded_rate == 0)

+ 2 - 0
arch/arm/mach-omap2/dpll44xx.c

@@ -202,6 +202,8 @@ out:
  * in failure.
  */
 long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 {

+ 19 - 7
arch/arm/mach-omap2/io.c

@@ -461,7 +461,17 @@ void __init omap3_init_early(void)
 	omap3xxx_clockdomains_init();
 	omap3xxx_hwmod_init();
 	omap_hwmod_init_postsetup();
-	omap_clk_soc_init = omap3xxx_clk_init;
+	if (!of_have_populated_dt()) {
+		omap3_prcm_legacy_iomaps_init();
+		if (soc_is_am35xx())
+			omap_clk_soc_init = am35xx_clk_legacy_init;
+		else if (cpu_is_omap3630())
+			omap_clk_soc_init = omap36xx_clk_legacy_init;
+		else if (omap_rev() == OMAP3430_REV_ES1_0)
+			omap_clk_soc_init = omap3430es1_clk_legacy_init;
+		else
+			omap_clk_soc_init = omap3430_clk_legacy_init;
+	}
 }
 
 void __init omap3430_init_early(void)
@@ -753,15 +763,17 @@ int __init omap_clk_init(void)
 
 	ti_clk_init_features();
 
-	ret = of_prcm_init();
-	if (ret)
-		return ret;
+	if (of_have_populated_dt()) {
+		ret = of_prcm_init();
+		if (ret)
+			return ret;
 
-	of_clk_init(NULL);
+		of_clk_init(NULL);
 
-	ti_dt_clk_init_retry_clks();
+		ti_dt_clk_init_retry_clks();
 
-	ti_dt_clockdomains_setup();
+		ti_dt_clockdomains_setup();
+	}
 
 	ret = omap_clk_soc_init();
 

+ 1 - 0
arch/arm/mach-omap2/prm.h

@@ -20,6 +20,7 @@ extern void __iomem *prm_base;
 extern u16 prm_features;
 extern void omap2_set_globals_prm(void __iomem *prm);
 int of_prcm_init(void);
+void omap3_prcm_legacy_iomaps_init(void);
 # endif
 
 /*

+ 11 - 0
arch/arm/mach-omap2/prm_common.c

@@ -35,6 +35,8 @@
 #include "prm44xx.h"
 #include "common.h"
 #include "clock.h"
+#include "cm.h"
+#include "control.h"
 
 /*
  * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@ -641,6 +643,15 @@ int __init of_prcm_init(void)
 	return 0;
 }
 
+void __init omap3_prcm_legacy_iomaps_init(void)
+{
+	ti_clk_ll_ops = &omap_clk_ll_ops;
+
+	clk_memmaps[TI_CLKM_CM] = cm_base + OMAP3430_IVA2_MOD;
+	clk_memmaps[TI_CLKM_PRM] = prm_base + OMAP3430_IVA2_MOD;
+	clk_memmaps[TI_CLKM_SCRM] = omap_ctrl_base_get();
+}
+
 static int __init prm_late_init(void)
 {
 	if (prm_ll_data->late_init)

+ 0 - 2
arch/arm/mach-tegra/tegra.c

@@ -91,8 +91,6 @@ static void __init tegra_dt_init(void)
 	struct soc_device *soc_dev;
 	struct device *parent = NULL;
 
-	tegra_clocks_apply_init_table();
-
 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
 		goto out;

+ 6 - 0
arch/mips/alchemy/common/clock.c

@@ -546,6 +546,8 @@ static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw,
 }
 
 static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 {
@@ -678,6 +680,8 @@ static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw,
 }
 
 static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 {
@@ -897,6 +901,8 @@ static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate,
 }
 
 static long alchemy_clk_csrc_detr(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 {

+ 1 - 0
arch/powerpc/configs/corenet32_smp_defconfig

@@ -142,6 +142,7 @@ CONFIG_VIRT_DRIVERS=y
 CONFIG_FSL_HV_MANAGER=y
 CONFIG_STAGING=y
 CONFIG_FSL_CORENET_CF=y
+CONFIG_CLK_QORIQ=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set

+ 1 - 0
arch/powerpc/configs/corenet64_smp_defconfig

@@ -122,6 +122,7 @@ CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
 CONFIG_VIRT_DRIVERS=y
 CONFIG_FSL_HV_MANAGER=y
+CONFIG_CLK_QORIQ=y
 CONFIG_FSL_CORENET_CF=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y

+ 5 - 0
arch/powerpc/kernel/time.c

@@ -54,6 +54,7 @@
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/irq_work.h>
+#include <linux/clk-provider.h>
 #include <asm/trace.h>
 
 #include <asm/io.h>
@@ -975,6 +976,10 @@ void __init time_init(void)
 
 	init_decrementer_clockevent();
 	tick_setup_hrtimer_broadcast();
+
+#ifdef CONFIG_COMMON_CLK
+	of_clk_init(NULL);
+#endif
 }
 
 

+ 5 - 6
arch/powerpc/platforms/512x/clock-commonclk.c

@@ -1168,6 +1168,11 @@ static void mpc5121_clk_provide_backwards_compat(void)
 	}
 }
 
+/*
+ * The "fixed-clock" nodes (which includes the oscillator node if the board's
+ * DT provides one) has already been scanned by the of_clk_init() in
+ * time_init().
+ */
 int __init mpc5121_clk_init(void)
 {
 	struct device_node *clk_np;
@@ -1186,12 +1191,6 @@ int __init mpc5121_clk_init(void)
 	/* invalidate all not yet registered clock slots */
 	mpc512x_clk_preset_data();
 
-	/*
-	 * have the device tree scanned for "fixed-clock" nodes (which
-	 * includes the oscillator node if the board's DT provides one)
-	 */
-	of_clk_init(NULL);
-
 	/*
 	 * add a dummy clock for those situations where a clock spec is
 	 * required yet no real clock is involved

+ 13 - 5
drivers/clk/Kconfig

@@ -102,12 +102,12 @@ config COMMON_CLK_AXI_CLKGEN
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  FPGAs. It is commonly used in Analog Devices' reference designs.
 
-config CLK_PPC_CORENET
-	bool "Clock driver for PowerPC corenet platforms"
-	depends on PPC_E500MC && OF
+config CLK_QORIQ
+	bool "Clock driver for Freescale QorIQ platforms"
+	depends on (PPC_E500MC || ARM) && OF
 	---help---
-	  This adds the clock driver support for Freescale PowerPC corenet
-	  platforms using common clock framework.
+	  This adds the clock driver support for Freescale QorIQ platforms
+	  using common clock framework.
 
 config COMMON_CLK_XGENE
 	bool "Clock driver for APM XGene SoC"
@@ -135,6 +135,14 @@ config COMMON_CLK_PXA
 	---help---
 	  Sypport for the Marvell PXA SoC.
 
+config COMMON_CLK_CDCE706
+	tristate "Clock driver for TI CDCE706 clock synthesizer"
+	depends on I2C
+	select REGMAP_I2C
+	select RATIONAL
+	---help---
+	  This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
+
 source "drivers/clk/qcom/Kconfig"
 
 endmenu

+ 3 - 1
drivers/clk/Makefile

@@ -16,9 +16,11 @@ endif
 
 # hardware specific clock types
 # please keep this section sorted lexicographically by file/directory path name
+obj-$(CONFIG_MACH_ASM9260)		+= clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)	+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)		+= clk-axm5516.o
 obj-$(CONFIG_ARCH_BCM2835)		+= clk-bcm2835.o
+obj-$(CONFIG_COMMON_CLK_CDCE706)	+= clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.o
@@ -30,7 +32,7 @@ obj-$(CONFIG_ARCH_MOXART)		+= clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)		+= clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
 obj-$(CONFIG_COMMON_CLK_PALMAS)		+= clk-palmas.o
-obj-$(CONFIG_CLK_PPC_CORENET)		+= clk-ppc-corenet.o
+obj-$(CONFIG_CLK_QORIQ)			+= clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)		+= clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SI5351)		+= clk-si5351.o

+ 2 - 0
drivers/clk/at91/clk-programmable.c

@@ -56,6 +56,8 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
 
 static long clk_programmable_determine_rate(struct clk_hw *hw,
 					    unsigned long rate,
+					    unsigned long min_rate,
+					    unsigned long max_rate,
 					    unsigned long *best_parent_rate,
 					    struct clk_hw **best_parent_hw)
 {

+ 2 - 0
drivers/clk/bcm/clk-kona.c

@@ -1032,6 +1032,8 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 }
 
 static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long min_rate,
+		unsigned long max_rate,
 		unsigned long *best_parent_rate, struct clk_hw **best_parent)
 {
 	struct kona_clk *bcm_clk = to_kona_clk(hw);

+ 348 - 0
drivers/clk/clk-asm9260.c

@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+#define HW_AHBCLKCTRL0		0x0020
+#define HW_AHBCLKCTRL1		0x0030
+#define HW_SYSPLLCTRL		0x0100
+#define HW_MAINCLKSEL		0x0120
+#define HW_MAINCLKUEN		0x0124
+#define HW_UARTCLKSEL		0x0128
+#define HW_UARTCLKUEN		0x012c
+#define HW_I2S0CLKSEL		0x0130
+#define HW_I2S0CLKUEN		0x0134
+#define HW_I2S1CLKSEL		0x0138
+#define HW_I2S1CLKUEN		0x013c
+#define HW_WDTCLKSEL		0x0160
+#define HW_WDTCLKUEN		0x0164
+#define HW_CLKOUTCLKSEL		0x0170
+#define HW_CLKOUTCLKUEN		0x0174
+#define HW_CPUCLKDIV		0x017c
+#define HW_SYSAHBCLKDIV		0x0180
+#define HW_I2S0MCLKDIV		0x0190
+#define HW_I2S0SCLKDIV		0x0194
+#define HW_I2S1MCLKDIV		0x0188
+#define HW_I2S1SCLKDIV		0x018c
+#define HW_UART0CLKDIV		0x0198
+#define HW_UART1CLKDIV		0x019c
+#define HW_UART2CLKDIV		0x01a0
+#define HW_UART3CLKDIV		0x01a4
+#define HW_UART4CLKDIV		0x01a8
+#define HW_UART5CLKDIV		0x01ac
+#define HW_UART6CLKDIV		0x01b0
+#define HW_UART7CLKDIV		0x01b4
+#define HW_UART8CLKDIV		0x01b8
+#define HW_UART9CLKDIV		0x01bc
+#define HW_SPI0CLKDIV		0x01c0
+#define HW_SPI1CLKDIV		0x01c4
+#define HW_QUADSPICLKDIV	0x01c8
+#define HW_SSP0CLKDIV		0x01d0
+#define HW_NANDCLKDIV		0x01d4
+#define HW_TRACECLKDIV		0x01e0
+#define HW_CAMMCLKDIV		0x01e8
+#define HW_WDTCLKDIV		0x01ec
+#define HW_CLKOUTCLKDIV		0x01f4
+#define HW_MACCLKDIV		0x01f8
+#define HW_LCDCLKDIV		0x01fc
+#define HW_ADCANACLKDIV		0x0200
+
+static struct clk *clks[MAX_CLKS];
+static struct clk_onecell_data clk_data;
+static DEFINE_SPINLOCK(asm9260_clk_lock);
+
+struct asm9260_div_clk {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+};
+
+struct asm9260_gate_data {
+	unsigned int idx;
+	const char *name;
+	const char *parent_name;
+	u32 reg;
+	u8 bit_idx;
+	unsigned long flags;
+};
+
+struct asm9260_mux_clock {
+	u8			mask;
+	u32			*table;
+	const char		*name;
+	const char		**parent_names;
+	u8			num_parents;
+	unsigned long		offset;
+	unsigned long		flags;
+};
+
+static void __iomem *base;
+
+static const struct asm9260_div_clk asm9260_div_clks[] __initconst = {
+	{ CLKID_SYS_CPU,	"cpu_div", "main_gate", HW_CPUCLKDIV },
+	{ CLKID_SYS_AHB,	"ahb_div", "cpu_div", HW_SYSAHBCLKDIV },
+
+	/* i2s has two deviders: one for only external mclk and internal
+	 * devider for all clks. */
+	{ CLKID_SYS_I2S0M,	"i2s0m_div", "i2s0_mclk",  HW_I2S0MCLKDIV },
+	{ CLKID_SYS_I2S1M,	"i2s1m_div", "i2s1_mclk",  HW_I2S1MCLKDIV },
+	{ CLKID_SYS_I2S0S,	"i2s0s_div", "i2s0_gate",  HW_I2S0SCLKDIV },
+	{ CLKID_SYS_I2S1S,	"i2s1s_div", "i2s0_gate",  HW_I2S1SCLKDIV },
+
+	{ CLKID_SYS_UART0,	"uart0_div", "uart_gate", HW_UART0CLKDIV },
+	{ CLKID_SYS_UART1,	"uart1_div", "uart_gate", HW_UART1CLKDIV },
+	{ CLKID_SYS_UART2,	"uart2_div", "uart_gate", HW_UART2CLKDIV },
+	{ CLKID_SYS_UART3,	"uart3_div", "uart_gate", HW_UART3CLKDIV },
+	{ CLKID_SYS_UART4,	"uart4_div", "uart_gate", HW_UART4CLKDIV },
+	{ CLKID_SYS_UART5,	"uart5_div", "uart_gate", HW_UART5CLKDIV },
+	{ CLKID_SYS_UART6,	"uart6_div", "uart_gate", HW_UART6CLKDIV },
+	{ CLKID_SYS_UART7,	"uart7_div", "uart_gate", HW_UART7CLKDIV },
+	{ CLKID_SYS_UART8,	"uart8_div", "uart_gate", HW_UART8CLKDIV },
+	{ CLKID_SYS_UART9,	"uart9_div", "uart_gate", HW_UART9CLKDIV },
+
+	{ CLKID_SYS_SPI0,	"spi0_div",	"main_gate", HW_SPI0CLKDIV },
+	{ CLKID_SYS_SPI1,	"spi1_div",	"main_gate", HW_SPI1CLKDIV },
+	{ CLKID_SYS_QUADSPI,	"quadspi_div",	"main_gate", HW_QUADSPICLKDIV },
+	{ CLKID_SYS_SSP0,	"ssp0_div",	"main_gate", HW_SSP0CLKDIV },
+	{ CLKID_SYS_NAND,	"nand_div",	"main_gate", HW_NANDCLKDIV },
+	{ CLKID_SYS_TRACE,	"trace_div",	"main_gate", HW_TRACECLKDIV },
+	{ CLKID_SYS_CAMM,	"camm_div",	"main_gate", HW_CAMMCLKDIV },
+	{ CLKID_SYS_MAC,	"mac_div",	"main_gate", HW_MACCLKDIV },
+	{ CLKID_SYS_LCD,	"lcd_div",	"main_gate", HW_LCDCLKDIV },
+	{ CLKID_SYS_ADCANA,	"adcana_div",	"main_gate", HW_ADCANACLKDIV },
+
+	{ CLKID_SYS_WDT,	"wdt_div",	"wdt_gate",    HW_WDTCLKDIV },
+	{ CLKID_SYS_CLKOUT,	"clkout_div",	"clkout_gate", HW_CLKOUTCLKDIV },
+};
+
+static const struct asm9260_gate_data asm9260_mux_gates[] __initconst = {
+	{ 0, "main_gate",	"main_mux",	HW_MAINCLKUEN,	0 },
+	{ 0, "uart_gate",	"uart_mux",	HW_UARTCLKUEN,	0 },
+	{ 0, "i2s0_gate",	"i2s0_mux",	HW_I2S0CLKUEN,	0 },
+	{ 0, "i2s1_gate",	"i2s1_mux",	HW_I2S1CLKUEN,	0 },
+	{ 0, "wdt_gate",	"wdt_mux",	HW_WDTCLKUEN,	0 },
+	{ 0, "clkout_gate",	"clkout_mux",	HW_CLKOUTCLKUEN, 0 },
+};
+static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
+	/* ahb gates */
+	{ CLKID_AHB_ROM,	"rom",		"ahb_div",
+		HW_AHBCLKCTRL0,	1, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RAM,	"ram",		"ahb_div",
+		HW_AHBCLKCTRL0,	2, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_GPIO,	"gpio",		"ahb_div",
+		HW_AHBCLKCTRL0,	4 },
+	{ CLKID_AHB_MAC,	"mac",		"ahb_div",
+		HW_AHBCLKCTRL0,	5 },
+	{ CLKID_AHB_EMI,	"emi",		"ahb_div",
+		HW_AHBCLKCTRL0,	6, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_USB0,	"usb0",		"ahb_div",
+		HW_AHBCLKCTRL0,	7 },
+	{ CLKID_AHB_USB1,	"usb1",		"ahb_div",
+		HW_AHBCLKCTRL0,	8 },
+	{ CLKID_AHB_DMA0,	"dma0",		"ahb_div",
+		HW_AHBCLKCTRL0,	9 },
+	{ CLKID_AHB_DMA1,	"dma1",		"ahb_div",
+		HW_AHBCLKCTRL0,	10 },
+	{ CLKID_AHB_UART0,	"uart0",	"ahb_div",
+		HW_AHBCLKCTRL0,	11 },
+	{ CLKID_AHB_UART1,	"uart1",	"ahb_div",
+		HW_AHBCLKCTRL0,	12 },
+	{ CLKID_AHB_UART2,	"uart2",	"ahb_div",
+		HW_AHBCLKCTRL0,	13 },
+	{ CLKID_AHB_UART3,	"uart3",	"ahb_div",
+		HW_AHBCLKCTRL0,	14 },
+	{ CLKID_AHB_UART4,	"uart4",	"ahb_div",
+		HW_AHBCLKCTRL0,	15 },
+	{ CLKID_AHB_UART5,	"uart5",	"ahb_div",
+		HW_AHBCLKCTRL0,	16 },
+	{ CLKID_AHB_UART6,	"uart6",	"ahb_div",
+		HW_AHBCLKCTRL0,	17 },
+	{ CLKID_AHB_UART7,	"uart7",	"ahb_div",
+		HW_AHBCLKCTRL0,	18 },
+	{ CLKID_AHB_UART8,	"uart8",	"ahb_div",
+		HW_AHBCLKCTRL0,	19 },
+	{ CLKID_AHB_UART9,	"uart9",	"ahb_div",
+		HW_AHBCLKCTRL0,	20 },
+	{ CLKID_AHB_I2S0,	"i2s0",		"ahb_div",
+		HW_AHBCLKCTRL0,	21 },
+	{ CLKID_AHB_I2C0,	"i2c0",		"ahb_div",
+		HW_AHBCLKCTRL0,	22 },
+	{ CLKID_AHB_I2C1,	"i2c1",		"ahb_div",
+		HW_AHBCLKCTRL0,	23 },
+	{ CLKID_AHB_SSP0,	"ssp0",		"ahb_div",
+		HW_AHBCLKCTRL0,	24 },
+	{ CLKID_AHB_IOCONFIG,	"ioconf",	"ahb_div",
+		HW_AHBCLKCTRL0,	25 },
+	{ CLKID_AHB_WDT,	"wdt",		"ahb_div",
+		HW_AHBCLKCTRL0,	26 },
+	{ CLKID_AHB_CAN0,	"can0",		"ahb_div",
+		HW_AHBCLKCTRL0,	27 },
+	{ CLKID_AHB_CAN1,	"can1",		"ahb_div",
+		HW_AHBCLKCTRL0,	28 },
+	{ CLKID_AHB_MPWM,	"mpwm",		"ahb_div",
+		HW_AHBCLKCTRL0,	29 },
+	{ CLKID_AHB_SPI0,	"spi0",		"ahb_div",
+		HW_AHBCLKCTRL0,	30 },
+	{ CLKID_AHB_SPI1,	"spi1",		"ahb_div",
+		HW_AHBCLKCTRL0,	31 },
+
+	{ CLKID_AHB_QEI,	"qei",		"ahb_div",
+		HW_AHBCLKCTRL1,	0 },
+	{ CLKID_AHB_QUADSPI0,	"quadspi0",	"ahb_div",
+		HW_AHBCLKCTRL1,	1 },
+	{ CLKID_AHB_CAMIF,	"capmif",	"ahb_div",
+		HW_AHBCLKCTRL1,	2 },
+	{ CLKID_AHB_LCDIF,	"lcdif",	"ahb_div",
+		HW_AHBCLKCTRL1,	3 },
+	{ CLKID_AHB_TIMER0,	"timer0",	"ahb_div",
+		HW_AHBCLKCTRL1,	4 },
+	{ CLKID_AHB_TIMER1,	"timer1",	"ahb_div",
+		HW_AHBCLKCTRL1,	5 },
+	{ CLKID_AHB_TIMER2,	"timer2",	"ahb_div",
+		HW_AHBCLKCTRL1,	6 },
+	{ CLKID_AHB_TIMER3,	"timer3",	"ahb_div",
+		HW_AHBCLKCTRL1,	7 },
+	{ CLKID_AHB_IRQ,	"irq",		"ahb_div",
+		HW_AHBCLKCTRL1,	8, CLK_IGNORE_UNUSED},
+	{ CLKID_AHB_RTC,	"rtc",		"ahb_div",
+		HW_AHBCLKCTRL1,	9 },
+	{ CLKID_AHB_NAND,	"nand",		"ahb_div",
+		HW_AHBCLKCTRL1,	10 },
+	{ CLKID_AHB_ADC0,	"adc0",		"ahb_div",
+		HW_AHBCLKCTRL1,	11 },
+	{ CLKID_AHB_LED,	"led",		"ahb_div",
+		HW_AHBCLKCTRL1,	12 },
+	{ CLKID_AHB_DAC0,	"dac0",		"ahb_div",
+		HW_AHBCLKCTRL1,	13 },
+	{ CLKID_AHB_LCD,	"lcd",		"ahb_div",
+		HW_AHBCLKCTRL1,	14 },
+	{ CLKID_AHB_I2S1,	"i2s1",		"ahb_div",
+		HW_AHBCLKCTRL1,	15 },
+	{ CLKID_AHB_MAC1,	"mac1",		"ahb_div",
+		HW_AHBCLKCTRL1,	16 },
+};
+
+static const char __initdata *main_mux_p[] =   { NULL, NULL };
+static const char __initdata *i2s0_mux_p[] =   { NULL, NULL, "i2s0m_div"};
+static const char __initdata *i2s1_mux_p[] =   { NULL, NULL, "i2s1m_div"};
+static const char __initdata *clkout_mux_p[] = { NULL, NULL, "rtc"};
+static u32 three_mux_table[] = {0, 1, 3};
+
+static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
+	{ 1, three_mux_table, "main_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_MAINCLKSEL, },
+	{ 1, three_mux_table, "uart_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_UARTCLKSEL, },
+	{ 1, three_mux_table, "wdt_mux",	main_mux_p,
+		ARRAY_SIZE(main_mux_p), HW_WDTCLKSEL, },
+	{ 3, three_mux_table, "i2s0_mux",	i2s0_mux_p,
+		ARRAY_SIZE(i2s0_mux_p), HW_I2S0CLKSEL, },
+	{ 3, three_mux_table, "i2s1_mux",	i2s1_mux_p,
+		ARRAY_SIZE(i2s1_mux_p), HW_I2S1CLKSEL, },
+	{ 3, three_mux_table, "clkout_mux",	clkout_mux_p,
+		ARRAY_SIZE(clkout_mux_p), HW_CLKOUTCLKSEL, },
+};
+
+static void __init asm9260_acc_init(struct device_node *np)
+{
+	struct clk *clk;
+	const char *ref_clk, *pll_clk = "pll";
+	u32 rate;
+	int n;
+	u32 accuracy = 0;
+
+	base = of_io_request_and_map(np, 0, np->name);
+	if (!base)
+		panic("%s: unable to map resource", np->name);
+
+	/* register pll */
+	rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
+
+	ref_clk = of_clk_get_parent_name(np, 0);
+	accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
+	clk = clk_register_fixed_rate_with_accuracy(NULL, pll_clk,
+			ref_clk, 0, rate, accuracy);
+
+	if (IS_ERR(clk))
+		panic("%s: can't register REFCLK. Check DT!", np->name);
+
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
+		const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
+
+		mc->parent_names[0] = ref_clk;
+		mc->parent_names[1] = pll_clk;
+		clk = clk_register_mux_table(NULL, mc->name, mc->parent_names,
+				mc->num_parents, mc->flags, base + mc->offset,
+				0, mc->mask, 0, mc->table, &asm9260_clk_lock);
+	}
+
+	/* clock mux gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
+
+		clk = clk_register_gate(NULL, gd->name,
+			gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
+			base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* clock div cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
+		const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
+
+		clks[dc->idx] = clk_register_divider(NULL, dc->name,
+				dc->parent_name, CLK_SET_RATE_PARENT,
+				base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
+				&asm9260_clk_lock);
+	}
+
+	/* clock ahb gate cells */
+	for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
+		const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
+
+		clks[gd->idx] = clk_register_gate(NULL, gd->name,
+				gd->parent_name, gd->flags, base + gd->reg,
+				gd->bit_idx, 0, &asm9260_clk_lock);
+	}
+
+	/* check for errors on leaf clocks */
+	for (n = 0; n < MAX_CLKS; n++) {
+		if (!IS_ERR(clks[n]))
+			continue;
+
+		pr_err("%s: Unable to register leaf clock %d\n",
+				np->full_name, n);
+		goto fail;
+	}
+
+	/* register clk-provider */
+	clk_data.clks = clks;
+	clk_data.clk_num = MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+	return;
+fail:
+	iounmap(base);
+}
+CLK_OF_DECLARE(asm9260_acc, "alphascale,asm9260-clock-controller",
+		asm9260_acc_init);

+ 700 - 0
drivers/clk/clk-cdce706.c

@@ -0,0 +1,700 @@
+/*
+ * TI CDCE706 programmable 3-PLL clock synthesizer driver
+ *
+ * Copyright (c) 2014 Cadence Design Systems Inc.
+ *
+ * Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/rational.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define CDCE706_CLKIN_CLOCK		10
+#define CDCE706_CLKIN_SOURCE		11
+#define CDCE706_PLL_M_LOW(pll)		(1 + 3 * (pll))
+#define CDCE706_PLL_N_LOW(pll)		(2 + 3 * (pll))
+#define CDCE706_PLL_HI(pll)		(3 + 3 * (pll))
+#define CDCE706_PLL_MUX			3
+#define CDCE706_PLL_FVCO		6
+#define CDCE706_DIVIDER(div)		(13 + (div))
+#define CDCE706_CLKOUT(out)		(19 + (out))
+
+#define CDCE706_CLKIN_CLOCK_MASK	0x10
+#define CDCE706_CLKIN_SOURCE_SHIFT	6
+#define CDCE706_CLKIN_SOURCE_MASK	0xc0
+#define CDCE706_CLKIN_SOURCE_LVCMOS	0x40
+
+#define CDCE706_PLL_MUX_MASK(pll)	(0x80 >> (pll))
+#define CDCE706_PLL_LOW_M_MASK		0xff
+#define CDCE706_PLL_LOW_N_MASK		0xff
+#define CDCE706_PLL_HI_M_MASK		0x1
+#define CDCE706_PLL_HI_N_MASK		0x1e
+#define CDCE706_PLL_HI_N_SHIFT		1
+#define CDCE706_PLL_M_MAX		0x1ff
+#define CDCE706_PLL_N_MAX		0xfff
+#define CDCE706_PLL_FVCO_MASK(pll)	(0x80 >> (pll))
+#define CDCE706_PLL_FREQ_MIN		 80000000
+#define CDCE706_PLL_FREQ_MAX		300000000
+#define CDCE706_PLL_FREQ_HI		180000000
+
+#define CDCE706_DIVIDER_PLL(div)	(9 + (div) - ((div) > 2) - ((div) > 4))
+#define CDCE706_DIVIDER_PLL_SHIFT(div)	((div) < 2 ? 5 : 3 * ((div) & 1))
+#define CDCE706_DIVIDER_PLL_MASK(div)	(0x7 << CDCE706_DIVIDER_PLL_SHIFT(div))
+#define CDCE706_DIVIDER_DIVIDER_MASK	0x7f
+#define CDCE706_DIVIDER_DIVIDER_MAX	0x7f
+
+#define CDCE706_CLKOUT_DIVIDER_MASK	0x7
+#define CDCE706_CLKOUT_ENABLE_MASK	0x8
+
+static struct regmap_config cdce706_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.val_format_endian = REGMAP_ENDIAN_NATIVE,
+};
+
+#define to_hw_data(phw) (container_of((phw), struct cdce706_hw_data, hw))
+
+struct cdce706_hw_data {
+	struct cdce706_dev_data *dev_data;
+	unsigned idx;
+	unsigned parent;
+	struct clk *clk;
+	struct clk_hw hw;
+	unsigned div;
+	unsigned mul;
+	unsigned mux;
+};
+
+struct cdce706_dev_data {
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct clk_onecell_data onecell;
+	struct clk *clks[6];
+	struct clk *clkin_clk[2];
+	const char *clkin_name[2];
+	struct cdce706_hw_data clkin[1];
+	struct cdce706_hw_data pll[3];
+	struct cdce706_hw_data divider[6];
+	struct cdce706_hw_data clkout[6];
+};
+
+static const char * const cdce706_source_name[] = {
+	"clk_in0", "clk_in1",
+};
+
+static const char *cdce706_clkin_name[] = {
+	"clk_in",
+};
+
+static const char * const cdce706_pll_name[] = {
+	"pll1", "pll2", "pll3",
+};
+
+static const char *cdce706_divider_parent_name[] = {
+	"clk_in", "pll1", "pll2", "pll2", "pll3",
+};
+
+static const char *cdce706_divider_name[] = {
+	"p0", "p1", "p2", "p3", "p4", "p5",
+};
+
+static const char * const cdce706_clkout_name[] = {
+	"clk_out0", "clk_out1", "clk_out2", "clk_out3", "clk_out4", "clk_out5",
+};
+
+static int cdce706_reg_read(struct cdce706_dev_data *dev_data, unsigned reg,
+			    unsigned *val)
+{
+	int rc = regmap_read(dev_data->regmap, reg | 0x80, val);
+
+	if (rc < 0)
+		dev_err(&dev_data->client->dev, "error reading reg %u", reg);
+	return rc;
+}
+
+static int cdce706_reg_write(struct cdce706_dev_data *dev_data, unsigned reg,
+			     unsigned val)
+{
+	int rc = regmap_write(dev_data->regmap, reg | 0x80, val);
+
+	if (rc < 0)
+		dev_err(&dev_data->client->dev, "error writing reg %u", reg);
+	return rc;
+}
+
+static int cdce706_reg_update(struct cdce706_dev_data *dev_data, unsigned reg,
+			      unsigned mask, unsigned val)
+{
+	int rc = regmap_update_bits(dev_data->regmap, reg | 0x80, mask, val);
+
+	if (rc < 0)
+		dev_err(&dev_data->client->dev, "error updating reg %u", reg);
+	return rc;
+}
+
+static int cdce706_clkin_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	hwd->parent = index;
+	return 0;
+}
+
+static u8 cdce706_clkin_get_parent(struct clk_hw *hw)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	return hwd->parent;
+}
+
+static const struct clk_ops cdce706_clkin_ops = {
+	.set_parent = cdce706_clkin_set_parent,
+	.get_parent = cdce706_clkin_get_parent,
+};
+
+static unsigned long cdce706_pll_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, pll: %d, mux: %d, mul: %u, div: %u\n",
+		__func__, hwd->idx, hwd->mux, hwd->mul, hwd->div);
+
+	if (!hwd->mux) {
+		if (hwd->div && hwd->mul) {
+			u64 res = (u64)parent_rate * hwd->mul;
+
+			do_div(res, hwd->div);
+			return res;
+		}
+	} else {
+		if (hwd->div)
+			return parent_rate / hwd->div;
+	}
+	return 0;
+}
+
+static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+	unsigned long mul, div;
+	u64 res;
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, rate: %lu, parent_rate: %lu\n",
+		__func__, rate, *parent_rate);
+
+	rational_best_approximation(rate, *parent_rate,
+				    CDCE706_PLL_N_MAX, CDCE706_PLL_M_MAX,
+				    &mul, &div);
+	hwd->mul = mul;
+	hwd->div = div;
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, pll: %d, mul: %lu, div: %lu\n",
+		__func__, hwd->idx, mul, div);
+
+	res = (u64)*parent_rate * hwd->mul;
+	do_div(res, hwd->div);
+	return res;
+}
+
+static int cdce706_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+	unsigned long mul = hwd->mul, div = hwd->div;
+	int err;
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, pll: %d, mul: %lu, div: %lu\n",
+		__func__, hwd->idx, mul, div);
+
+	err = cdce706_reg_update(hwd->dev_data,
+				 CDCE706_PLL_HI(hwd->idx),
+				 CDCE706_PLL_HI_M_MASK | CDCE706_PLL_HI_N_MASK,
+				 ((div >> 8) & CDCE706_PLL_HI_M_MASK) |
+				 ((mul >> (8 - CDCE706_PLL_HI_N_SHIFT)) &
+				  CDCE706_PLL_HI_N_MASK));
+	if (err < 0)
+		return err;
+
+	err = cdce706_reg_write(hwd->dev_data,
+				CDCE706_PLL_M_LOW(hwd->idx),
+				div & CDCE706_PLL_LOW_M_MASK);
+	if (err < 0)
+		return err;
+
+	err = cdce706_reg_write(hwd->dev_data,
+				CDCE706_PLL_N_LOW(hwd->idx),
+				mul & CDCE706_PLL_LOW_N_MASK);
+	if (err < 0)
+		return err;
+
+	err = cdce706_reg_update(hwd->dev_data,
+				 CDCE706_PLL_FVCO,
+				 CDCE706_PLL_FVCO_MASK(hwd->idx),
+				 rate > CDCE706_PLL_FREQ_HI ?
+				 CDCE706_PLL_FVCO_MASK(hwd->idx) : 0);
+	return err;
+}
+
+static const struct clk_ops cdce706_pll_ops = {
+	.recalc_rate = cdce706_pll_recalc_rate,
+	.round_rate = cdce706_pll_round_rate,
+	.set_rate = cdce706_pll_set_rate,
+};
+
+static int cdce706_divider_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	if (hwd->parent == index)
+		return 0;
+	hwd->parent = index;
+	return cdce706_reg_update(hwd->dev_data,
+				  CDCE706_DIVIDER_PLL(hwd->idx),
+				  CDCE706_DIVIDER_PLL_MASK(hwd->idx),
+				  index << CDCE706_DIVIDER_PLL_SHIFT(hwd->idx));
+}
+
+static u8 cdce706_divider_get_parent(struct clk_hw *hw)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	return hwd->parent;
+}
+
+static unsigned long cdce706_divider_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, divider: %d, div: %u\n",
+		__func__, hwd->idx, hwd->div);
+	if (hwd->div)
+		return parent_rate / hwd->div;
+	return 0;
+}
+
+static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+	struct cdce706_dev_data *cdce = hwd->dev_data;
+	unsigned long mul, div;
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, rate: %lu, parent_rate: %lu\n",
+		__func__, rate, *parent_rate);
+
+	rational_best_approximation(rate, *parent_rate,
+				    1, CDCE706_DIVIDER_DIVIDER_MAX,
+				    &mul, &div);
+	if (!mul)
+		div = CDCE706_DIVIDER_DIVIDER_MAX;
+
+	if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
+		unsigned long best_diff = rate;
+		unsigned long best_div = 0;
+		struct clk *gp_clk = cdce->clkin_clk[cdce->clkin[0].parent];
+		unsigned long gp_rate = gp_clk ? clk_get_rate(gp_clk) : 0;
+
+		for (div = CDCE706_PLL_FREQ_MIN / rate; best_diff &&
+		     div <= CDCE706_PLL_FREQ_MAX / rate; ++div) {
+			unsigned long n, m;
+			unsigned long diff;
+			unsigned long div_rate;
+			u64 div_rate64;
+
+			if (rate * div < CDCE706_PLL_FREQ_MIN)
+				continue;
+
+			rational_best_approximation(rate * div, gp_rate,
+						    CDCE706_PLL_N_MAX,
+						    CDCE706_PLL_M_MAX,
+						    &n, &m);
+			div_rate64 = (u64)gp_rate * n;
+			do_div(div_rate64, m);
+			do_div(div_rate64, div);
+			div_rate = div_rate64;
+			diff = max(div_rate, rate) - min(div_rate, rate);
+
+			if (diff < best_diff) {
+				best_diff = diff;
+				best_div = div;
+				dev_dbg(&hwd->dev_data->client->dev,
+					"%s, %lu * %lu / %lu / %lu = %lu\n",
+					__func__, gp_rate, n, m, div, div_rate);
+			}
+		}
+
+		div = best_div;
+
+		dev_dbg(&hwd->dev_data->client->dev,
+			"%s, altering parent rate: %lu -> %lu\n",
+			__func__, *parent_rate, rate * div);
+		*parent_rate = rate * div;
+	}
+	hwd->div = div;
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, divider: %d, div: %lu\n",
+		__func__, hwd->idx, div);
+
+	return *parent_rate / div;
+}
+
+static int cdce706_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	dev_dbg(&hwd->dev_data->client->dev,
+		"%s, divider: %d, div: %u\n",
+		__func__, hwd->idx, hwd->div);
+
+	return cdce706_reg_update(hwd->dev_data,
+				  CDCE706_DIVIDER(hwd->idx),
+				  CDCE706_DIVIDER_DIVIDER_MASK,
+				  hwd->div);
+}
+
+static const struct clk_ops cdce706_divider_ops = {
+	.set_parent = cdce706_divider_set_parent,
+	.get_parent = cdce706_divider_get_parent,
+	.recalc_rate = cdce706_divider_recalc_rate,
+	.round_rate = cdce706_divider_round_rate,
+	.set_rate = cdce706_divider_set_rate,
+};
+
+static int cdce706_clkout_prepare(struct clk_hw *hw)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	return cdce706_reg_update(hwd->dev_data, CDCE706_CLKOUT(hwd->idx),
+				  CDCE706_CLKOUT_ENABLE_MASK,
+				  CDCE706_CLKOUT_ENABLE_MASK);
+}
+
+static void cdce706_clkout_unprepare(struct clk_hw *hw)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	cdce706_reg_update(hwd->dev_data, CDCE706_CLKOUT(hwd->idx),
+			   CDCE706_CLKOUT_ENABLE_MASK, 0);
+}
+
+static int cdce706_clkout_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	if (hwd->parent == index)
+		return 0;
+	hwd->parent = index;
+	return cdce706_reg_update(hwd->dev_data,
+				  CDCE706_CLKOUT(hwd->idx),
+				  CDCE706_CLKOUT_ENABLE_MASK, index);
+}
+
+static u8 cdce706_clkout_get_parent(struct clk_hw *hw)
+{
+	struct cdce706_hw_data *hwd = to_hw_data(hw);
+
+	return hwd->parent;
+}
+
+static unsigned long cdce706_clkout_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	return parent_rate;
+}
+
+static long cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	*parent_rate = rate;
+	return rate;
+}
+
+static int cdce706_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	return 0;
+}
+
+static const struct clk_ops cdce706_clkout_ops = {
+	.prepare = cdce706_clkout_prepare,
+	.unprepare = cdce706_clkout_unprepare,
+	.set_parent = cdce706_clkout_set_parent,
+	.get_parent = cdce706_clkout_get_parent,
+	.recalc_rate = cdce706_clkout_recalc_rate,
+	.round_rate = cdce706_clkout_round_rate,
+	.set_rate = cdce706_clkout_set_rate,
+};
+
+static int cdce706_register_hw(struct cdce706_dev_data *cdce,
+			       struct cdce706_hw_data *hw, unsigned num_hw,
+			       const char * const *clk_names,
+			       struct clk_init_data *init)
+{
+	unsigned i;
+
+	for (i = 0; i < num_hw; ++i, ++hw) {
+		init->name = clk_names[i];
+		hw->dev_data = cdce;
+		hw->idx = i;
+		hw->hw.init = init;
+		hw->clk = devm_clk_register(&cdce->client->dev,
+					    &hw->hw);
+		if (IS_ERR(hw->clk)) {
+			dev_err(&cdce->client->dev, "Failed to register %s\n",
+				clk_names[i]);
+			return PTR_ERR(hw->clk);
+		}
+	}
+	return 0;
+}
+
+static int cdce706_register_clkin(struct cdce706_dev_data *cdce)
+{
+	struct clk_init_data init = {
+		.ops = &cdce706_clkin_ops,
+		.parent_names = cdce->clkin_name,
+		.num_parents = ARRAY_SIZE(cdce->clkin_name),
+	};
+	unsigned i;
+	int ret;
+	unsigned clock, source;
+
+	for (i = 0; i < ARRAY_SIZE(cdce->clkin_name); ++i) {
+		struct clk *parent = devm_clk_get(&cdce->client->dev,
+						  cdce706_source_name[i]);
+
+		if (IS_ERR(parent)) {
+			cdce->clkin_name[i] = cdce706_source_name[i];
+		} else {
+			cdce->clkin_name[i] = __clk_get_name(parent);
+			cdce->clkin_clk[i] = parent;
+		}
+	}
+
+	ret = cdce706_reg_read(cdce, CDCE706_CLKIN_SOURCE, &source);
+	if (ret < 0)
+		return ret;
+	if ((source & CDCE706_CLKIN_SOURCE_MASK) ==
+	    CDCE706_CLKIN_SOURCE_LVCMOS) {
+		ret = cdce706_reg_read(cdce, CDCE706_CLKIN_CLOCK, &clock);
+		if (ret < 0)
+			return ret;
+		cdce->clkin[0].parent = !!(clock & CDCE706_CLKIN_CLOCK_MASK);
+	}
+
+	ret = cdce706_register_hw(cdce, cdce->clkin,
+				  ARRAY_SIZE(cdce->clkin),
+				  cdce706_clkin_name, &init);
+	return ret;
+}
+
+static int cdce706_register_plls(struct cdce706_dev_data *cdce)
+{
+	struct clk_init_data init = {
+		.ops = &cdce706_pll_ops,
+		.parent_names = cdce706_clkin_name,
+		.num_parents = ARRAY_SIZE(cdce706_clkin_name),
+	};
+	unsigned i;
+	int ret;
+	unsigned mux;
+
+	ret = cdce706_reg_read(cdce, CDCE706_PLL_MUX, &mux);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(cdce->pll); ++i) {
+		unsigned m, n, v;
+
+		ret = cdce706_reg_read(cdce, CDCE706_PLL_M_LOW(i), &m);
+		if (ret < 0)
+			return ret;
+		ret = cdce706_reg_read(cdce, CDCE706_PLL_N_LOW(i), &n);
+		if (ret < 0)
+			return ret;
+		ret = cdce706_reg_read(cdce, CDCE706_PLL_HI(i), &v);
+		if (ret < 0)
+			return ret;
+		cdce->pll[i].div = m | ((v & CDCE706_PLL_HI_M_MASK) << 8);
+		cdce->pll[i].mul = n | ((v & CDCE706_PLL_HI_N_MASK) <<
+					(8 - CDCE706_PLL_HI_N_SHIFT));
+		cdce->pll[i].mux = mux & CDCE706_PLL_MUX_MASK(i);
+		dev_dbg(&cdce->client->dev,
+			"%s: i: %u, div: %u, mul: %u, mux: %d\n", __func__, i,
+			cdce->pll[i].div, cdce->pll[i].mul, cdce->pll[i].mux);
+	}
+
+	ret = cdce706_register_hw(cdce, cdce->pll,
+				  ARRAY_SIZE(cdce->pll),
+				  cdce706_pll_name, &init);
+	return ret;
+}
+
+static int cdce706_register_dividers(struct cdce706_dev_data *cdce)
+{
+	struct clk_init_data init = {
+		.ops = &cdce706_divider_ops,
+		.parent_names = cdce706_divider_parent_name,
+		.num_parents = ARRAY_SIZE(cdce706_divider_parent_name),
+		.flags = CLK_SET_RATE_PARENT,
+	};
+	unsigned i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(cdce->divider); ++i) {
+		unsigned val;
+
+		ret = cdce706_reg_read(cdce, CDCE706_DIVIDER_PLL(i), &val);
+		if (ret < 0)
+			return ret;
+		cdce->divider[i].parent =
+			(val & CDCE706_DIVIDER_PLL_MASK(i)) >>
+			CDCE706_DIVIDER_PLL_SHIFT(i);
+
+		ret = cdce706_reg_read(cdce, CDCE706_DIVIDER(i), &val);
+		if (ret < 0)
+			return ret;
+		cdce->divider[i].div = val & CDCE706_DIVIDER_DIVIDER_MASK;
+		dev_dbg(&cdce->client->dev,
+			"%s: i: %u, parent: %u, div: %u\n", __func__, i,
+			cdce->divider[i].parent, cdce->divider[i].div);
+	}
+
+	ret = cdce706_register_hw(cdce, cdce->divider,
+				  ARRAY_SIZE(cdce->divider),
+				  cdce706_divider_name, &init);
+	return ret;
+}
+
+static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
+{
+	struct clk_init_data init = {
+		.ops = &cdce706_clkout_ops,
+		.parent_names = cdce706_divider_name,
+		.num_parents = ARRAY_SIZE(cdce706_divider_name),
+		.flags = CLK_SET_RATE_PARENT,
+	};
+	unsigned i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i) {
+		unsigned val;
+
+		ret = cdce706_reg_read(cdce, CDCE706_CLKOUT(i), &val);
+		if (ret < 0)
+			return ret;
+		cdce->clkout[i].parent = val & CDCE706_CLKOUT_DIVIDER_MASK;
+		dev_dbg(&cdce->client->dev,
+			"%s: i: %u, parent: %u\n", __func__, i,
+			cdce->clkout[i].parent);
+	}
+
+	ret = cdce706_register_hw(cdce, cdce->clkout,
+				  ARRAY_SIZE(cdce->clkout),
+				  cdce706_clkout_name, &init);
+	for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i)
+		cdce->clks[i] = cdce->clkout[i].clk;
+
+	return ret;
+}
+
+static int cdce706_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct cdce706_dev_data *cdce;
+	int ret;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	cdce = devm_kzalloc(&client->dev, sizeof(*cdce), GFP_KERNEL);
+	if (!cdce)
+		return -ENOMEM;
+
+	cdce->client = client;
+	cdce->regmap = devm_regmap_init_i2c(client, &cdce706_regmap_config);
+	if (IS_ERR(cdce->regmap)) {
+		dev_err(&client->dev, "Failed to initialize regmap\n");
+		return -EINVAL;
+	}
+
+	i2c_set_clientdata(client, cdce);
+
+	ret = cdce706_register_clkin(cdce);
+	if (ret < 0)
+		return ret;
+	ret = cdce706_register_plls(cdce);
+	if (ret < 0)
+		return ret;
+	ret = cdce706_register_dividers(cdce);
+	if (ret < 0)
+		return ret;
+	ret = cdce706_register_clkouts(cdce);
+	if (ret < 0)
+		return ret;
+	cdce->onecell.clks = cdce->clks;
+	cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks);
+	ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
+				  &cdce->onecell);
+
+	return ret;
+}
+
+static int cdce706_remove(struct i2c_client *client)
+{
+	return 0;
+}
+
+
+#ifdef CONFIG_OF
+static const struct of_device_id cdce706_dt_match[] = {
+	{ .compatible = "ti,cdce706" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cdce706_dt_match);
+#endif
+
+static const struct i2c_device_id cdce706_id[] = {
+	{ "cdce706", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cdce706_id);
+
+static struct i2c_driver cdce706_i2c_driver = {
+	.driver	= {
+		.name	= "cdce706",
+		.of_match_table = of_match_ptr(cdce706_dt_match),
+	},
+	.probe		= cdce706_probe,
+	.remove		= cdce706_remove,
+	.id_table	= cdce706_id,
+};
+module_i2c_driver(cdce706_i2c_driver);
+
+MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>");
+MODULE_DESCRIPTION("TI CDCE 706 clock synthesizer driver");
+MODULE_LICENSE("GPL");

+ 17 - 12
drivers/clk/clk-composite.c

@@ -27,7 +27,7 @@ static u8 clk_composite_get_parent(struct clk_hw *hw)
 	const struct clk_ops *mux_ops = composite->mux_ops;
 	struct clk_hw *mux_hw = composite->mux_hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return mux_ops->get_parent(mux_hw);
 }
@@ -38,7 +38,7 @@ static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
 	const struct clk_ops *mux_ops = composite->mux_ops;
 	struct clk_hw *mux_hw = composite->mux_hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return mux_ops->set_parent(mux_hw, index);
 }
@@ -50,12 +50,14 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
 	const struct clk_ops *rate_ops = composite->rate_ops;
 	struct clk_hw *rate_hw = composite->rate_hw;
 
-	rate_hw->clk = hw->clk;
+	__clk_hw_set_clk(rate_hw, hw);
 
 	return rate_ops->recalc_rate(rate_hw, parent_rate);
 }
 
 static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_p)
 {
@@ -72,8 +74,10 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 	int i;
 
 	if (rate_hw && rate_ops && rate_ops->determine_rate) {
-		rate_hw->clk = hw->clk;
-		return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
+		__clk_hw_set_clk(rate_hw, hw);
+		return rate_ops->determine_rate(rate_hw, rate, min_rate,
+						max_rate,
+						best_parent_rate,
 						best_parent_p);
 	} else if (rate_hw && rate_ops && rate_ops->round_rate &&
 		   mux_hw && mux_ops && mux_ops->set_parent) {
@@ -116,8 +120,9 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 
 		return best_rate;
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
-		mux_hw->clk = hw->clk;
-		return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
+		__clk_hw_set_clk(mux_hw, hw);
+		return mux_ops->determine_rate(mux_hw, rate, min_rate,
+					       max_rate, best_parent_rate,
 					       best_parent_p);
 	} else {
 		pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
@@ -132,7 +137,7 @@ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *rate_ops = composite->rate_ops;
 	struct clk_hw *rate_hw = composite->rate_hw;
 
-	rate_hw->clk = hw->clk;
+	__clk_hw_set_clk(rate_hw, hw);
 
 	return rate_ops->round_rate(rate_hw, rate, prate);
 }
@@ -144,7 +149,7 @@ static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *rate_ops = composite->rate_ops;
 	struct clk_hw *rate_hw = composite->rate_hw;
 
-	rate_hw->clk = hw->clk;
+	__clk_hw_set_clk(rate_hw, hw);
 
 	return rate_ops->set_rate(rate_hw, rate, parent_rate);
 }
@@ -155,7 +160,7 @@ static int clk_composite_is_enabled(struct clk_hw *hw)
 	const struct clk_ops *gate_ops = composite->gate_ops;
 	struct clk_hw *gate_hw = composite->gate_hw;
 
-	gate_hw->clk = hw->clk;
+	__clk_hw_set_clk(gate_hw, hw);
 
 	return gate_ops->is_enabled(gate_hw);
 }
@@ -166,7 +171,7 @@ static int clk_composite_enable(struct clk_hw *hw)
 	const struct clk_ops *gate_ops = composite->gate_ops;
 	struct clk_hw *gate_hw = composite->gate_hw;
 
-	gate_hw->clk = hw->clk;
+	__clk_hw_set_clk(gate_hw, hw);
 
 	return gate_ops->enable(gate_hw);
 }
@@ -177,7 +182,7 @@ static void clk_composite_disable(struct clk_hw *hw)
 	const struct clk_ops *gate_ops = composite->gate_ops;
 	struct clk_hw *gate_hw = composite->gate_hw;
 
-	gate_hw->clk = hw->clk;
+	__clk_hw_set_clk(gate_hw, hw);
 
 	gate_ops->disable(gate_hw);
 }

+ 144 - 84
drivers/clk/clk-divider.c

@@ -30,7 +30,7 @@
 
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 
-#define div_mask(d)	((1 << ((d)->width)) - 1)
+#define div_mask(width)	((1 << (width)) - 1)
 
 static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
 {
@@ -54,15 +54,16 @@ static unsigned int _get_table_mindiv(const struct clk_div_table *table)
 	return mindiv;
 }
 
-static unsigned int _get_maxdiv(struct clk_divider *divider)
+static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
+				unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_ONE_BASED)
-		return div_mask(divider);
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
-		return 1 << div_mask(divider);
-	if (divider->table)
-		return _get_table_maxdiv(divider->table);
-	return div_mask(divider) + 1;
+	if (flags & CLK_DIVIDER_ONE_BASED)
+		return div_mask(width);
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
+		return 1 << div_mask(width);
+	if (table)
+		return _get_table_maxdiv(table);
+	return div_mask(width) + 1;
 }
 
 static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -76,14 +77,15 @@ static unsigned int _get_table_div(const struct clk_div_table *table,
 	return 0;
 }
 
-static unsigned int _get_div(struct clk_divider *divider, unsigned int val)
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val, unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_ONE_BASED)
+	if (flags & CLK_DIVIDER_ONE_BASED)
 		return val;
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return 1 << val;
-	if (divider->table)
-		return _get_table_div(divider->table, val);
+	if (table)
+		return _get_table_div(table, val);
 	return val + 1;
 }
 
@@ -98,29 +100,28 @@ static unsigned int _get_table_val(const struct clk_div_table *table,
 	return 0;
 }
 
-static unsigned int _get_val(struct clk_divider *divider, unsigned int div)
+static unsigned int _get_val(const struct clk_div_table *table,
+			     unsigned int div, unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_ONE_BASED)
+	if (flags & CLK_DIVIDER_ONE_BASED)
 		return div;
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return __ffs(div);
-	if (divider->table)
-		return  _get_table_val(divider->table, div);
+	if (table)
+		return  _get_table_val(table, div);
 	return div - 1;
 }
 
-static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
-		unsigned long parent_rate)
+unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
+				  unsigned int val,
+				  const struct clk_div_table *table,
+				  unsigned long flags)
 {
-	struct clk_divider *divider = to_clk_divider(hw);
-	unsigned int div, val;
+	unsigned int div;
 
-	val = clk_readl(divider->reg) >> divider->shift;
-	val &= div_mask(divider);
-
-	div = _get_div(divider, val);
+	div = _get_div(table, val, flags);
 	if (!div) {
-		WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
+		WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
 			"%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
 			__clk_get_name(hw->clk));
 		return parent_rate;
@@ -128,6 +129,20 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
 
 	return DIV_ROUND_UP(parent_rate, div);
 }
+EXPORT_SYMBOL_GPL(divider_recalc_rate);
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int val;
+
+	val = clk_readl(divider->reg) >> divider->shift;
+	val &= div_mask(divider->width);
+
+	return divider_recalc_rate(hw, parent_rate, val, divider->table,
+				   divider->flags);
+}
 
 /*
  * The reverse of DIV_ROUND_UP: The maximum number which
@@ -146,12 +161,13 @@ static bool _is_valid_table_div(const struct clk_div_table *table,
 	return false;
 }
 
-static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
+static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
+			  unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return is_power_of_2(div);
-	if (divider->table)
-		return _is_valid_table_div(divider->table, div);
+	if (table)
+		return _is_valid_table_div(table, div);
 	return true;
 }
 
@@ -191,71 +207,76 @@ static int _round_down_table(const struct clk_div_table *table, int div)
 	return down;
 }
 
-static int _div_round_up(struct clk_divider *divider,
-		unsigned long parent_rate, unsigned long rate)
+static int _div_round_up(const struct clk_div_table *table,
+			 unsigned long parent_rate, unsigned long rate,
+			 unsigned long flags)
 {
 	int div = DIV_ROUND_UP(parent_rate, rate);
 
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		div = __roundup_pow_of_two(div);
-	if (divider->table)
-		div = _round_up_table(divider->table, div);
+	if (table)
+		div = _round_up_table(table, div);
 
 	return div;
 }
 
-static int _div_round_closest(struct clk_divider *divider,
-		unsigned long parent_rate, unsigned long rate)
+static int _div_round_closest(const struct clk_div_table *table,
+			      unsigned long parent_rate, unsigned long rate,
+			      unsigned long flags)
 {
 	int up, down, div;
 
 	up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
 
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) {
+	if (flags & CLK_DIVIDER_POWER_OF_TWO) {
 		up = __roundup_pow_of_two(div);
 		down = __rounddown_pow_of_two(div);
-	} else if (divider->table) {
-		up = _round_up_table(divider->table, div);
-		down = _round_down_table(divider->table, div);
+	} else if (table) {
+		up = _round_up_table(table, div);
+		down = _round_down_table(table, div);
 	}
 
 	return (up - div) <= (div - down) ? up : down;
 }
 
-static int _div_round(struct clk_divider *divider, unsigned long parent_rate,
-		unsigned long rate)
+static int _div_round(const struct clk_div_table *table,
+		      unsigned long parent_rate, unsigned long rate,
+		      unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_ROUND_CLOSEST)
-		return _div_round_closest(divider, parent_rate, rate);
+	if (flags & CLK_DIVIDER_ROUND_CLOSEST)
+		return _div_round_closest(table, parent_rate, rate, flags);
 
-	return _div_round_up(divider, parent_rate, rate);
+	return _div_round_up(table, parent_rate, rate, flags);
 }
 
-static bool _is_best_div(struct clk_divider *divider,
-		unsigned long rate, unsigned long now, unsigned long best)
+static bool _is_best_div(unsigned long rate, unsigned long now,
+			 unsigned long best, unsigned long flags)
 {
-	if (divider->flags & CLK_DIVIDER_ROUND_CLOSEST)
+	if (flags & CLK_DIVIDER_ROUND_CLOSEST)
 		return abs(rate - now) < abs(rate - best);
 
 	return now <= rate && now > best;
 }
 
-static int _next_div(struct clk_divider *divider, int div)
+static int _next_div(const struct clk_div_table *table, int div,
+		     unsigned long flags)
 {
 	div++;
 
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return __roundup_pow_of_two(div);
-	if (divider->table)
-		return _round_up_table(divider->table, div);
+	if (table)
+		return _round_up_table(table, div);
 
 	return div;
 }
 
 static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
-		unsigned long *best_parent_rate)
+			       unsigned long *best_parent_rate,
+			       const struct clk_div_table *table, u8 width,
+			       unsigned long flags)
 {
-	struct clk_divider *divider = to_clk_divider(hw);
 	int i, bestdiv = 0;
 	unsigned long parent_rate, best = 0, now, maxdiv;
 	unsigned long parent_rate_saved = *best_parent_rate;
@@ -263,19 +284,11 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 	if (!rate)
 		rate = 1;
 
-	/* if read only, just return current value */
-	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
-		bestdiv = readl(divider->reg) >> divider->shift;
-		bestdiv &= div_mask(divider);
-		bestdiv = _get_div(divider, bestdiv);
-		return bestdiv;
-	}
-
-	maxdiv = _get_maxdiv(divider);
+	maxdiv = _get_maxdiv(table, width, flags);
 
 	if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
 		parent_rate = *best_parent_rate;
-		bestdiv = _div_round(divider, parent_rate, rate);
+		bestdiv = _div_round(table, parent_rate, rate, flags);
 		bestdiv = bestdiv == 0 ? 1 : bestdiv;
 		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
 		return bestdiv;
@@ -287,8 +300,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 	 */
 	maxdiv = min(ULONG_MAX / rate, maxdiv);
 
-	for (i = 1; i <= maxdiv; i = _next_div(divider, i)) {
-		if (!_is_valid_div(divider, i))
+	for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) {
+		if (!_is_valid_div(table, i, flags))
 			continue;
 		if (rate * i == parent_rate_saved) {
 			/*
@@ -302,7 +315,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 		parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
 				MULT_ROUND_UP(rate, i));
 		now = DIV_ROUND_UP(parent_rate, i);
-		if (_is_best_div(divider, rate, now, best)) {
+		if (_is_best_div(rate, now, best, flags)) {
 			bestdiv = i;
 			best = now;
 			*best_parent_rate = parent_rate;
@@ -310,48 +323,79 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 	}
 
 	if (!bestdiv) {
-		bestdiv = _get_maxdiv(divider);
+		bestdiv = _get_maxdiv(table, width, flags);
 		*best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1);
 	}
 
 	return bestdiv;
 }
 
-static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long *prate)
+long divider_round_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long *prate, const struct clk_div_table *table,
+			u8 width, unsigned long flags)
 {
 	int div;
-	div = clk_divider_bestdiv(hw, rate, prate);
+
+	div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
 
 	return DIV_ROUND_UP(*prate, div);
 }
+EXPORT_SYMBOL_GPL(divider_round_rate);
 
-static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
-				unsigned long parent_rate)
+static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
 {
 	struct clk_divider *divider = to_clk_divider(hw);
+	int bestdiv;
+
+	/* if read only, just return current value */
+	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+		bestdiv = readl(divider->reg) >> divider->shift;
+		bestdiv &= div_mask(divider->width);
+		bestdiv = _get_div(divider->table, bestdiv, divider->flags);
+		return bestdiv;
+	}
+
+	return divider_round_rate(hw, rate, prate, divider->table,
+				  divider->width, divider->flags);
+}
+
+int divider_get_val(unsigned long rate, unsigned long parent_rate,
+		    const struct clk_div_table *table, u8 width,
+		    unsigned long flags)
+{
 	unsigned int div, value;
-	unsigned long flags = 0;
-	u32 val;
 
 	div = DIV_ROUND_UP(parent_rate, rate);
 
-	if (!_is_valid_div(divider, div))
+	if (!_is_valid_div(table, div, flags))
 		return -EINVAL;
 
-	value = _get_val(divider, div);
+	value = _get_val(table, div, flags);
+
+	return min_t(unsigned int, value, div_mask(width));
+}
+EXPORT_SYMBOL_GPL(divider_get_val);
+
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int value;
+	unsigned long flags = 0;
+	u32 val;
 
-	if (value > div_mask(divider))
-		value = div_mask(divider);
+	value = divider_get_val(rate, parent_rate, divider->table,
+				divider->width, divider->flags);
 
 	if (divider->lock)
 		spin_lock_irqsave(divider->lock, flags);
 
 	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
-		val = div_mask(divider) << (divider->shift + 16);
+		val = div_mask(divider->width) << (divider->shift + 16);
 	} else {
 		val = clk_readl(divider->reg);
-		val &= ~(div_mask(divider) << divider->shift);
+		val &= ~(div_mask(divider->width) << divider->shift);
 	}
 	val |= value << divider->shift;
 	clk_writel(val, divider->reg);
@@ -463,3 +507,19 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 			width, clk_divider_flags, table, lock);
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
+
+void clk_unregister_divider(struct clk *clk)
+{
+	struct clk_divider *div;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	div = to_clk_divider(hw);
+
+	clk_unregister(clk);
+	kfree(div);
+}
+EXPORT_SYMBOL_GPL(clk_unregister_divider);

+ 17 - 1
drivers/clk/clk-gate.c

@@ -128,7 +128,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	struct clk_init_data init;
 
 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
-		if (bit_idx > 16) {
+		if (bit_idx > 15) {
 			pr_err("gate bit exceeds LOWORD field\n");
 			return ERR_PTR(-EINVAL);
 		}
@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	return clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_gate);
+
+void clk_unregister_gate(struct clk *clk)
+{
+	struct clk_gate *gate;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	gate = to_clk_gate(hw);
+
+	clk_unregister(clk);
+	kfree(gate);
+}
+EXPORT_SYMBOL_GPL(clk_unregister_gate);

+ 16 - 0
drivers/clk/clk-mux.c

@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 				      NULL, lock);
 }
 EXPORT_SYMBOL_GPL(clk_register_mux);
+
+void clk_unregister_mux(struct clk *clk)
+{
+	struct clk_mux *mux;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	mux = to_clk_mux(hw);
+
+	clk_unregister(clk);
+	kfree(mux);
+}
+EXPORT_SYMBOL_GPL(clk_unregister_mux);

+ 117 - 61
drivers/clk/clk-ppc-corenet.c → drivers/clk/clk-qoriq.c

@@ -5,8 +5,11 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * clock driver for Freescale PowerPC corenet SoCs.
+ * clock driver for Freescale QorIQ SoCs.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -19,6 +22,7 @@
 struct cmux_clk {
 	struct clk_hw hw;
 	void __iomem *reg;
+	unsigned int clk_per_pll;
 	u32 flags;
 };
 
@@ -27,14 +31,12 @@ struct cmux_clk {
 #define CLKSEL_ADJUST		BIT(0)
 #define to_cmux_clk(p)		container_of(p, struct cmux_clk, hw)
 
-static unsigned int clocks_per_pll;
-
 static int cmux_set_parent(struct clk_hw *hw, u8 idx)
 {
 	struct cmux_clk *clk = to_cmux_clk(hw);
 	u32 clksel;
 
-	clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll;
+	clksel = ((idx / clk->clk_per_pll) << 2) + idx % clk->clk_per_pll;
 	if (clk->flags & CLKSEL_ADJUST)
 		clksel += 8;
 	clksel = (clksel & 0xf) << CLKSEL_SHIFT;
@@ -52,12 +54,12 @@ static u8 cmux_get_parent(struct clk_hw *hw)
 	clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
 	if (clk->flags & CLKSEL_ADJUST)
 		clksel -= 8;
-	clksel = (clksel >> 2) * clocks_per_pll + clksel % 4;
+	clksel = (clksel >> 2) * clk->clk_per_pll + clksel % 4;
 
 	return clksel;
 }
 
-const struct clk_ops cmux_ops = {
+static const struct clk_ops cmux_ops = {
 	.get_parent = cmux_get_parent,
 	.set_parent = cmux_set_parent,
 };
@@ -72,6 +74,7 @@ static void __init core_mux_init(struct device_node *np)
 	u32	offset;
 	const char *clk_name;
 	const char **parent_names;
+	struct of_phandle_args clkspec;
 
 	rc = of_property_read_u32(np, "reg", &offset);
 	if (rc) {
@@ -85,32 +88,40 @@ static void __init core_mux_init(struct device_node *np)
 		pr_err("%s: get clock count error\n", np->name);
 		return;
 	}
-	parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
-	if (!parent_names) {
-		pr_err("%s: could not allocate parent_names\n", __func__);
+	parent_names = kcalloc(count, sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
 		return;
-	}
 
 	for (i = 0; i < count; i++)
 		parent_names[i] = of_clk_get_parent_name(np, i);
 
-	cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
-	if (!cmux_clk) {
-		pr_err("%s: could not allocate cmux_clk\n", __func__);
+	cmux_clk = kzalloc(sizeof(*cmux_clk), GFP_KERNEL);
+	if (!cmux_clk)
 		goto err_name;
-	}
+
 	cmux_clk->reg = of_iomap(np, 0);
 	if (!cmux_clk->reg) {
 		pr_err("%s: could not map register\n", __func__);
 		goto err_clk;
 	}
 
+	rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
+					&clkspec);
+	if (rc) {
+		pr_err("%s: parse clock node error\n", __func__);
+		goto err_clk;
+	}
+
+	cmux_clk->clk_per_pll = of_property_count_strings(clkspec.np,
+			"clock-output-names");
+	of_node_put(clkspec.np);
+
 	node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
 	if (node && (offset >= 0x80))
 		cmux_clk->flags = CLKSEL_ADJUST;
 
 	rc = of_property_read_string_index(np, "clock-output-names",
-			0, &clk_name);
+					   0, &clk_name);
 	if (rc) {
 		pr_err("%s: read clock names error\n", np->name);
 		goto err_clk;
@@ -132,7 +143,7 @@ static void __init core_mux_init(struct device_node *np)
 	rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
 	if (rc) {
 		pr_err("Could not register clock provider for node:%s\n",
-			 np->name);
+		       np->name);
 		goto err_clk;
 	}
 	goto err_name;
@@ -155,7 +166,7 @@ static void __init core_pll_init(struct device_node *np)
 
 	base = of_iomap(np, 0);
 	if (!base) {
-		pr_err("clk-ppc: iomap error\n");
+		pr_err("iomap error\n");
 		return;
 	}
 
@@ -181,24 +192,17 @@ static void __init core_pll_init(struct device_node *np)
 		goto err_map;
 	}
 
-	/* output clock number per PLL */
-	clocks_per_pll = count;
-
-	subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
-	if (!subclks) {
-		pr_err("%s: could not allocate subclks\n", __func__);
+	subclks = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
+	if (!subclks)
 		goto err_map;
-	}
 
-	onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
-	if (!onecell_data) {
-		pr_err("%s: could not allocate onecell_data\n", __func__);
+	onecell_data = kmalloc(sizeof(*onecell_data), GFP_KERNEL);
+	if (!onecell_data)
 		goto err_clks;
-	}
 
 	for (i = 0; i < count; i++) {
 		rc = of_property_read_string_index(np, "clock-output-names",
-				i, &clk_name);
+						   i, &clk_name);
 		if (rc) {
 			pr_err("%s: could not get clock names\n", np->name);
 			goto err_cell;
@@ -230,7 +234,7 @@ static void __init core_pll_init(struct device_node *np)
 	rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
 	if (rc) {
 		pr_err("Could not register clk provider for node:%s\n",
-			 np->name);
+		       np->name);
 		goto err_cell;
 	}
 
@@ -252,7 +256,7 @@ static void __init sysclk_init(struct device_node *node)
 	u32 rate;
 
 	if (!np) {
-		pr_err("ppc-clk: could not get parent node\n");
+		pr_err("could not get parent node\n");
 		return;
 	}
 
@@ -268,39 +272,91 @@ static void __init sysclk_init(struct device_node *node)
 		of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
 
-static const struct of_device_id clk_match[] __initconst = {
-	{ .compatible = "fsl,qoriq-sysclk-1.0", .data = sysclk_init, },
-	{ .compatible = "fsl,qoriq-sysclk-2.0", .data = sysclk_init, },
-	{ .compatible = "fsl,qoriq-core-pll-1.0", .data = core_pll_init, },
-	{ .compatible = "fsl,qoriq-core-pll-2.0", .data = core_pll_init, },
-	{ .compatible = "fsl,qoriq-core-mux-1.0", .data = core_mux_init, },
-	{ .compatible = "fsl,qoriq-core-mux-2.0", .data = core_mux_init, },
-	{}
-};
-
-static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
+static void __init pltfrm_pll_init(struct device_node *np)
 {
-	of_clk_init(clk_match);
+	void __iomem *base;
+	uint32_t mult;
+	const char *parent_name, *clk_name;
+	int i, _errno;
+	struct clk_onecell_data *cod;
 
-	return 0;
-}
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
+		return;
+	}
 
-static const struct of_device_id ppc_clk_ids[] __initconst = {
-	{ .compatible = "fsl,qoriq-clockgen-1.0", },
-	{ .compatible = "fsl,qoriq-clockgen-2.0", },
-	{}
-};
+	/* Get the multiple of PLL */
+	mult = ioread32be(base);
 
-static struct platform_driver ppc_corenet_clk_driver = {
-	.driver = {
-		.name = "ppc_corenet_clock",
-		.of_match_table = ppc_clk_ids,
-	},
-	.probe = ppc_corenet_clk_probe,
-};
+	iounmap(base);
 
-static int __init ppc_corenet_clk_init(void)
-{
-	return platform_driver_register(&ppc_corenet_clk_driver);
+	/* Check if this PLL is disabled */
+	if (mult & PLL_KILL) {
+		pr_debug("%s(): %s: Disabled\n", __func__, np->name);
+		return;
+	}
+	mult = (mult & GENMASK(6, 1)) >> 1;
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (!parent_name) {
+		pr_err("%s(): %s: of_clk_get_parent_name() failed\n",
+		       __func__, np->name);
+		return;
+	}
+
+	i = of_property_count_strings(np, "clock-output-names");
+	if (i < 0) {
+		pr_err("%s(): %s: of_property_count_strings(clock-output-names) = %d\n",
+		       __func__, np->name, i);
+		return;
+	}
+
+	cod = kmalloc(sizeof(*cod) + i * sizeof(struct clk *), GFP_KERNEL);
+	if (!cod)
+		return;
+	cod->clks = (struct clk **)(cod + 1);
+	cod->clk_num = i;
+
+	for (i = 0; i < cod->clk_num; i++) {
+		_errno = of_property_read_string_index(np, "clock-output-names",
+						       i, &clk_name);
+		if (_errno < 0) {
+			pr_err("%s(): %s: of_property_read_string_index(clock-output-names) = %d\n",
+			       __func__, np->name, _errno);
+			goto return_clk_unregister;
+		}
+
+		cod->clks[i] = clk_register_fixed_factor(NULL, clk_name,
+					       parent_name, 0, mult, 1 + i);
+		if (IS_ERR(cod->clks[i])) {
+			pr_err("%s(): %s: clk_register_fixed_factor(%s) = %ld\n",
+			       __func__, np->name,
+			       clk_name, PTR_ERR(cod->clks[i]));
+			goto return_clk_unregister;
+		}
+	}
+
+	_errno = of_clk_add_provider(np, of_clk_src_onecell_get, cod);
+	if (_errno < 0) {
+		pr_err("%s(): %s: of_clk_add_provider() = %d\n",
+		       __func__, np->name, _errno);
+		goto return_clk_unregister;
+	}
+
+	return;
+
+return_clk_unregister:
+	while (--i >= 0)
+		clk_unregister(cod->clks[i]);
+	kfree(cod);
 }
-subsys_initcall(ppc_corenet_clk_init);
+
+CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);
+CLK_OF_DECLARE(qoriq_sysclk_2, "fsl,qoriq-sysclk-2.0", sysclk_init);
+CLK_OF_DECLARE(qoriq_core_pll_1, "fsl,qoriq-core-pll-1.0", core_pll_init);
+CLK_OF_DECLARE(qoriq_core_pll_2, "fsl,qoriq-core-pll-2.0", core_pll_init);
+CLK_OF_DECLARE(qoriq_core_mux_1, "fsl,qoriq-core-mux-1.0", core_mux_init);
+CLK_OF_DECLARE(qoriq_core_mux_2, "fsl,qoriq-core-mux-2.0", core_mux_init);
+CLK_OF_DECLARE(qoriq_pltfrm_pll_1, "fsl,qoriq-platform-pll-1.0", pltfrm_pll_init);
+CLK_OF_DECLARE(qoriq_pltfrm_pll_2, "fsl,qoriq-platform-pll-2.0", pltfrm_pll_init);

+ 705 - 304
drivers/clk/clk.c

@@ -9,7 +9,7 @@
  * Standard functionality for the common clock API.  See Documentation/clk.txt
  */
 
-#include <linux/clk-private.h>
+#include <linux/clk-provider.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -37,6 +37,55 @@ static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+static long clk_core_get_accuracy(struct clk_core *clk);
+static unsigned long clk_core_get_rate(struct clk_core *clk);
+static int clk_core_get_phase(struct clk_core *clk);
+static bool clk_core_is_prepared(struct clk_core *clk);
+static bool clk_core_is_enabled(struct clk_core *clk);
+static struct clk_core *clk_core_lookup(const char *name);
+
+/***    private data structures    ***/
+
+struct clk_core {
+	const char		*name;
+	const struct clk_ops	*ops;
+	struct clk_hw		*hw;
+	struct module		*owner;
+	struct clk_core		*parent;
+	const char		**parent_names;
+	struct clk_core		**parents;
+	u8			num_parents;
+	u8			new_parent_index;
+	unsigned long		rate;
+	unsigned long		req_rate;
+	unsigned long		new_rate;
+	struct clk_core		*new_parent;
+	struct clk_core		*new_child;
+	unsigned long		flags;
+	unsigned int		enable_count;
+	unsigned int		prepare_count;
+	unsigned long		accuracy;
+	int			phase;
+	struct hlist_head	children;
+	struct hlist_node	child_node;
+	struct hlist_node	debug_node;
+	struct hlist_head	clks;
+	unsigned int		notifier_count;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*dentry;
+#endif
+	struct kref		ref;
+};
+
+struct clk {
+	struct clk_core	*core;
+	const char *dev_id;
+	const char *con_id;
+	unsigned long min_rate;
+	unsigned long max_rate;
+	struct hlist_node child_node;
+};
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
@@ -114,7 +163,8 @@ static struct hlist_head *orphan_list[] = {
 	NULL,
 };
 
-static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
+static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
+				 int level)
 {
 	if (!c)
 		return;
@@ -122,14 +172,14 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
 	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
-		   c->enable_count, c->prepare_count, clk_get_rate(c),
-		   clk_get_accuracy(c), clk_get_phase(c));
+		   c->enable_count, c->prepare_count, clk_core_get_rate(c),
+		   clk_core_get_accuracy(c), clk_core_get_phase(c));
 }
 
-static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
+static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
 				     int level)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	if (!c)
 		return;
@@ -142,7 +192,7 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
 
 static int clk_summary_show(struct seq_file *s, void *data)
 {
-	struct clk *c;
+	struct clk_core *c;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
 	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase\n");
@@ -172,7 +222,7 @@ static const struct file_operations clk_summary_fops = {
 	.release	= single_release,
 };
 
-static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
+static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 {
 	if (!c)
 		return;
@@ -180,14 +230,14 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
 	seq_printf(s, "\"%s\": { ", c->name);
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
-	seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
-	seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
-	seq_printf(s, "\"phase\": %d", clk_get_phase(c));
+	seq_printf(s, "\"rate\": %lu", clk_core_get_rate(c));
+	seq_printf(s, "\"accuracy\": %lu", clk_core_get_accuracy(c));
+	seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
 }
 
-static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
+static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	if (!c)
 		return;
@@ -204,7 +254,7 @@ static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
 
 static int clk_dump(struct seq_file *s, void *data)
 {
-	struct clk *c;
+	struct clk_core *c;
 	bool first_node = true;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
@@ -240,7 +290,7 @@ static const struct file_operations clk_dump_fops = {
 	.release	= single_release,
 };
 
-static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+static int clk_debug_create_one(struct clk_core *clk, struct dentry *pdentry)
 {
 	struct dentry *d;
 	int ret = -ENOMEM;
@@ -315,7 +365,7 @@ out:
  * initialized.  Otherwise it bails out early since the debugfs clk tree
  * will be created lazily by clk_debug_init as part of a late_initcall.
  */
-static int clk_debug_register(struct clk *clk)
+static int clk_debug_register(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -340,16 +390,12 @@ unlock:
  * debugfs clk tree if clk->dentry points to debugfs created by
  * clk_debug_register in __clk_init.
  */
-static void clk_debug_unregister(struct clk *clk)
+static void clk_debug_unregister(struct clk_core *clk)
 {
 	mutex_lock(&clk_debug_lock);
-	if (!clk->dentry)
-		goto out;
-
 	hlist_del_init(&clk->debug_node);
 	debugfs_remove_recursive(clk->dentry);
 	clk->dentry = NULL;
-out:
 	mutex_unlock(&clk_debug_lock);
 }
 
@@ -358,8 +404,9 @@ struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
 {
 	struct dentry *d = NULL;
 
-	if (hw->clk->dentry)
-		d = debugfs_create_file(name, mode, hw->clk->dentry, data, fops);
+	if (hw->core->dentry)
+		d = debugfs_create_file(name, mode, hw->core->dentry, data,
+					fops);
 
 	return d;
 }
@@ -379,7 +426,7 @@ EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
  */
 static int __init clk_debug_init(void)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 	struct dentry *d;
 
 	rootdir = debugfs_create_dir("clk", NULL);
@@ -418,22 +465,20 @@ static int __init clk_debug_init(void)
 }
 late_initcall(clk_debug_init);
 #else
-static inline int clk_debug_register(struct clk *clk) { return 0; }
-static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
+static inline int clk_debug_register(struct clk_core *clk) { return 0; }
+static inline void clk_debug_reparent(struct clk_core *clk,
+				      struct clk_core *new_parent)
 {
 }
-static inline void clk_debug_unregister(struct clk *clk)
+static inline void clk_debug_unregister(struct clk_core *clk)
 {
 }
 #endif
 
 /* caller must hold prepare_lock */
-static void clk_unprepare_unused_subtree(struct clk *clk)
+static void clk_unprepare_unused_subtree(struct clk_core *clk)
 {
-	struct clk *child;
-
-	if (!clk)
-		return;
+	struct clk_core *child;
 
 	hlist_for_each_entry(child, &clk->children, child_node)
 		clk_unprepare_unused_subtree(child);
@@ -444,7 +489,7 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
 	if (clk->flags & CLK_IGNORE_UNUSED)
 		return;
 
-	if (__clk_is_prepared(clk)) {
+	if (clk_core_is_prepared(clk)) {
 		if (clk->ops->unprepare_unused)
 			clk->ops->unprepare_unused(clk->hw);
 		else if (clk->ops->unprepare)
@@ -453,14 +498,11 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
 }
 
 /* caller must hold prepare_lock */
-static void clk_disable_unused_subtree(struct clk *clk)
+static void clk_disable_unused_subtree(struct clk_core *clk)
 {
-	struct clk *child;
+	struct clk_core *child;
 	unsigned long flags;
 
-	if (!clk)
-		goto out;
-
 	hlist_for_each_entry(child, &clk->children, child_node)
 		clk_disable_unused_subtree(child);
 
@@ -477,7 +519,7 @@ static void clk_disable_unused_subtree(struct clk *clk)
 	 * sequence.  call .disable_unused if available, otherwise fall
 	 * back to .disable
 	 */
-	if (__clk_is_enabled(clk)) {
+	if (clk_core_is_enabled(clk)) {
 		if (clk->ops->disable_unused)
 			clk->ops->disable_unused(clk->hw);
 		else if (clk->ops->disable)
@@ -486,9 +528,6 @@ static void clk_disable_unused_subtree(struct clk *clk)
 
 unlock_out:
 	clk_enable_unlock(flags);
-
-out:
-	return;
 }
 
 static bool clk_ignore_unused;
@@ -501,7 +540,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup);
 
 static int clk_disable_unused(void)
 {
-	struct clk *clk;
+	struct clk_core *clk;
 
 	if (clk_ignore_unused) {
 		pr_warn("clk: Not disabling unused clocks\n");
@@ -532,48 +571,65 @@ late_initcall_sync(clk_disable_unused);
 
 const char *__clk_get_name(struct clk *clk)
 {
-	return !clk ? NULL : clk->name;
+	return !clk ? NULL : clk->core->name;
 }
 EXPORT_SYMBOL_GPL(__clk_get_name);
 
 struct clk_hw *__clk_get_hw(struct clk *clk)
 {
-	return !clk ? NULL : clk->hw;
+	return !clk ? NULL : clk->core->hw;
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
 u8 __clk_get_num_parents(struct clk *clk)
 {
-	return !clk ? 0 : clk->num_parents;
+	return !clk ? 0 : clk->core->num_parents;
 }
 EXPORT_SYMBOL_GPL(__clk_get_num_parents);
 
 struct clk *__clk_get_parent(struct clk *clk)
 {
-	return !clk ? NULL : clk->parent;
+	if (!clk)
+		return NULL;
+
+	/* TODO: Create a per-user clk and change callers to call clk_put */
+	return !clk->core->parent ? NULL : clk->core->parent->hw->clk;
 }
 EXPORT_SYMBOL_GPL(__clk_get_parent);
 
-struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
+static struct clk_core *clk_core_get_parent_by_index(struct clk_core *clk,
+							 u8 index)
 {
 	if (!clk || index >= clk->num_parents)
 		return NULL;
 	else if (!clk->parents)
-		return __clk_lookup(clk->parent_names[index]);
+		return clk_core_lookup(clk->parent_names[index]);
 	else if (!clk->parents[index])
 		return clk->parents[index] =
-			__clk_lookup(clk->parent_names[index]);
+			clk_core_lookup(clk->parent_names[index]);
 	else
 		return clk->parents[index];
 }
+
+struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
+{
+	struct clk_core *parent;
+
+	if (!clk)
+		return NULL;
+
+	parent = clk_core_get_parent_by_index(clk->core, index);
+
+	return !parent ? NULL : parent->hw->clk;
+}
 EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
 
 unsigned int __clk_get_enable_count(struct clk *clk)
 {
-	return !clk ? 0 : clk->enable_count;
+	return !clk ? 0 : clk->core->enable_count;
 }
 
-unsigned long __clk_get_rate(struct clk *clk)
+static unsigned long clk_core_get_rate_nolock(struct clk_core *clk)
 {
 	unsigned long ret;
 
@@ -593,9 +649,17 @@ unsigned long __clk_get_rate(struct clk *clk)
 out:
 	return ret;
 }
+
+unsigned long __clk_get_rate(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return clk_core_get_rate_nolock(clk->core);
+}
 EXPORT_SYMBOL_GPL(__clk_get_rate);
 
-static unsigned long __clk_get_accuracy(struct clk *clk)
+static unsigned long __clk_get_accuracy(struct clk_core *clk)
 {
 	if (!clk)
 		return 0;
@@ -605,11 +669,11 @@ static unsigned long __clk_get_accuracy(struct clk *clk)
 
 unsigned long __clk_get_flags(struct clk *clk)
 {
-	return !clk ? 0 : clk->flags;
+	return !clk ? 0 : clk->core->flags;
 }
 EXPORT_SYMBOL_GPL(__clk_get_flags);
 
-bool __clk_is_prepared(struct clk *clk)
+static bool clk_core_is_prepared(struct clk_core *clk)
 {
 	int ret;
 
@@ -630,7 +694,15 @@ out:
 	return !!ret;
 }
 
-bool __clk_is_enabled(struct clk *clk)
+bool __clk_is_prepared(struct clk *clk)
+{
+	if (!clk)
+		return false;
+
+	return clk_core_is_prepared(clk->core);
+}
+
+static bool clk_core_is_enabled(struct clk_core *clk)
 {
 	int ret;
 
@@ -650,12 +722,21 @@ bool __clk_is_enabled(struct clk *clk)
 out:
 	return !!ret;
 }
+
+bool __clk_is_enabled(struct clk *clk)
+{
+	if (!clk)
+		return false;
+
+	return clk_core_is_enabled(clk->core);
+}
 EXPORT_SYMBOL_GPL(__clk_is_enabled);
 
-static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
+static struct clk_core *__clk_lookup_subtree(const char *name,
+					     struct clk_core *clk)
 {
-	struct clk *child;
-	struct clk *ret;
+	struct clk_core *child;
+	struct clk_core *ret;
 
 	if (!strcmp(clk->name, name))
 		return clk;
@@ -669,10 +750,10 @@ static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
 	return NULL;
 }
 
-struct clk *__clk_lookup(const char *name)
+static struct clk_core *clk_core_lookup(const char *name)
 {
-	struct clk *root_clk;
-	struct clk *ret;
+	struct clk_core *root_clk;
+	struct clk_core *ret;
 
 	if (!name)
 		return NULL;
@@ -694,42 +775,53 @@ struct clk *__clk_lookup(const char *name)
 	return NULL;
 }
 
-/*
- * Helper for finding best parent to provide a given frequency. This can be used
- * directly as a determine_rate callback (e.g. for a mux), or from a more
- * complex clock that may combine a mux with other operations.
- */
-long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
-			      unsigned long *best_parent_rate,
-			      struct clk_hw **best_parent_p)
+static bool mux_is_better_rate(unsigned long rate, unsigned long now,
+			   unsigned long best, unsigned long flags)
 {
-	struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+	if (flags & CLK_MUX_ROUND_CLOSEST)
+		return abs(now - rate) < abs(best - rate);
+
+	return now <= rate && now > best;
+}
+
+static long
+clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
+			     unsigned long min_rate,
+			     unsigned long max_rate,
+			     unsigned long *best_parent_rate,
+			     struct clk_hw **best_parent_p,
+			     unsigned long flags)
+{
+	struct clk_core *core = hw->core, *parent, *best_parent = NULL;
 	int i, num_parents;
 	unsigned long parent_rate, best = 0;
 
 	/* if NO_REPARENT flag set, pass through to current parent */
-	if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
-		parent = clk->parent;
-		if (clk->flags & CLK_SET_RATE_PARENT)
-			best = __clk_round_rate(parent, rate);
+	if (core->flags & CLK_SET_RATE_NO_REPARENT) {
+		parent = core->parent;
+		if (core->flags & CLK_SET_RATE_PARENT)
+			best = __clk_determine_rate(parent ? parent->hw : NULL,
+						    rate, min_rate, max_rate);
 		else if (parent)
-			best = __clk_get_rate(parent);
+			best = clk_core_get_rate_nolock(parent);
 		else
-			best = __clk_get_rate(clk);
+			best = clk_core_get_rate_nolock(core);
 		goto out;
 	}
 
 	/* find the parent that can provide the fastest rate <= rate */
-	num_parents = clk->num_parents;
+	num_parents = core->num_parents;
 	for (i = 0; i < num_parents; i++) {
-		parent = clk_get_parent_by_index(clk, i);
+		parent = clk_core_get_parent_by_index(core, i);
 		if (!parent)
 			continue;
-		if (clk->flags & CLK_SET_RATE_PARENT)
-			parent_rate = __clk_round_rate(parent, rate);
+		if (core->flags & CLK_SET_RATE_PARENT)
+			parent_rate = __clk_determine_rate(parent->hw, rate,
+							   min_rate,
+							   max_rate);
 		else
-			parent_rate = __clk_get_rate(parent);
-		if (parent_rate <= rate && parent_rate > best) {
+			parent_rate = clk_core_get_rate_nolock(parent);
+		if (mux_is_better_rate(rate, parent_rate, best, flags)) {
 			best_parent = parent;
 			best = parent_rate;
 		}
@@ -742,11 +834,63 @@ out:
 
 	return best;
 }
+
+struct clk *__clk_lookup(const char *name)
+{
+	struct clk_core *core = clk_core_lookup(name);
+
+	return !core ? NULL : core->hw->clk;
+}
+
+static void clk_core_get_boundaries(struct clk_core *clk,
+				    unsigned long *min_rate,
+				    unsigned long *max_rate)
+{
+	struct clk *clk_user;
+
+	*min_rate = 0;
+	*max_rate = ULONG_MAX;
+
+	hlist_for_each_entry(clk_user, &clk->clks, child_node)
+		*min_rate = max(*min_rate, clk_user->min_rate);
+
+	hlist_for_each_entry(clk_user, &clk->clks, child_node)
+		*max_rate = min(*max_rate, clk_user->max_rate);
+}
+
+/*
+ * Helper for finding best parent to provide a given frequency. This can be used
+ * directly as a determine_rate callback (e.g. for a mux), or from a more
+ * complex clock that may combine a mux with other operations.
+ */
+long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long min_rate,
+			      unsigned long max_rate,
+			      unsigned long *best_parent_rate,
+			      struct clk_hw **best_parent_p)
+{
+	return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate,
+					    best_parent_rate,
+					    best_parent_p, 0);
+}
 EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
 
+long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
+			      unsigned long min_rate,
+			      unsigned long max_rate,
+			      unsigned long *best_parent_rate,
+			      struct clk_hw **best_parent_p)
+{
+	return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate,
+					    best_parent_rate,
+					    best_parent_p,
+					    CLK_MUX_ROUND_CLOSEST);
+}
+EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
+
 /***        clk api        ***/
 
-void __clk_unprepare(struct clk *clk)
+static void clk_core_unprepare(struct clk_core *clk)
 {
 	if (!clk)
 		return;
@@ -762,7 +906,7 @@ void __clk_unprepare(struct clk *clk)
 	if (clk->ops->unprepare)
 		clk->ops->unprepare(clk->hw);
 
-	__clk_unprepare(clk->parent);
+	clk_core_unprepare(clk->parent);
 }
 
 /**
@@ -782,12 +926,12 @@ void clk_unprepare(struct clk *clk)
 		return;
 
 	clk_prepare_lock();
-	__clk_unprepare(clk);
+	clk_core_unprepare(clk->core);
 	clk_prepare_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
-int __clk_prepare(struct clk *clk)
+static int clk_core_prepare(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -795,14 +939,14 @@ int __clk_prepare(struct clk *clk)
 		return 0;
 
 	if (clk->prepare_count == 0) {
-		ret = __clk_prepare(clk->parent);
+		ret = clk_core_prepare(clk->parent);
 		if (ret)
 			return ret;
 
 		if (clk->ops->prepare) {
 			ret = clk->ops->prepare(clk->hw);
 			if (ret) {
-				__clk_unprepare(clk->parent);
+				clk_core_unprepare(clk->parent);
 				return ret;
 			}
 		}
@@ -829,15 +973,18 @@ int clk_prepare(struct clk *clk)
 {
 	int ret;
 
+	if (!clk)
+		return 0;
+
 	clk_prepare_lock();
-	ret = __clk_prepare(clk);
+	ret = clk_core_prepare(clk->core);
 	clk_prepare_unlock();
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
 
-static void __clk_disable(struct clk *clk)
+static void clk_core_disable(struct clk_core *clk)
 {
 	if (!clk)
 		return;
@@ -851,7 +998,15 @@ static void __clk_disable(struct clk *clk)
 	if (clk->ops->disable)
 		clk->ops->disable(clk->hw);
 
-	__clk_disable(clk->parent);
+	clk_core_disable(clk->parent);
+}
+
+static void __clk_disable(struct clk *clk)
+{
+	if (!clk)
+		return;
+
+	clk_core_disable(clk->core);
 }
 
 /**
@@ -879,7 +1034,7 @@ void clk_disable(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
-static int __clk_enable(struct clk *clk)
+static int clk_core_enable(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -890,7 +1045,7 @@ static int __clk_enable(struct clk *clk)
 		return -ESHUTDOWN;
 
 	if (clk->enable_count == 0) {
-		ret = __clk_enable(clk->parent);
+		ret = clk_core_enable(clk->parent);
 
 		if (ret)
 			return ret;
@@ -898,7 +1053,7 @@ static int __clk_enable(struct clk *clk)
 		if (clk->ops->enable) {
 			ret = clk->ops->enable(clk->hw);
 			if (ret) {
-				__clk_disable(clk->parent);
+				clk_core_disable(clk->parent);
 				return ret;
 			}
 		}
@@ -908,6 +1063,14 @@ static int __clk_enable(struct clk *clk)
 	return 0;
 }
 
+static int __clk_enable(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return clk_core_enable(clk->core);
+}
+
 /**
  * clk_enable - ungate a clock
  * @clk: the clk being ungated
@@ -934,17 +1097,13 @@ int clk_enable(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_enable);
 
-/**
- * __clk_round_rate - round the given rate for a clk
- * @clk: round the rate of this clock
- * @rate: the rate which is to be rounded
- *
- * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
- */
-unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
+						unsigned long rate,
+						unsigned long min_rate,
+						unsigned long max_rate)
 {
 	unsigned long parent_rate = 0;
-	struct clk *parent;
+	struct clk_core *parent;
 	struct clk_hw *parent_hw;
 
 	if (!clk)
@@ -956,15 +1115,59 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
 
 	if (clk->ops->determine_rate) {
 		parent_hw = parent ? parent->hw : NULL;
-		return clk->ops->determine_rate(clk->hw, rate, &parent_rate,
-						&parent_hw);
+		return clk->ops->determine_rate(clk->hw, rate,
+						min_rate, max_rate,
+						&parent_rate, &parent_hw);
 	} else if (clk->ops->round_rate)
 		return clk->ops->round_rate(clk->hw, rate, &parent_rate);
 	else if (clk->flags & CLK_SET_RATE_PARENT)
-		return __clk_round_rate(clk->parent, rate);
+		return clk_core_round_rate_nolock(clk->parent, rate, min_rate,
+						  max_rate);
 	else
 		return clk->rate;
 }
+
+/**
+ * __clk_determine_rate - get the closest rate actually supported by a clock
+ * @hw: determine the rate of this clock
+ * @rate: target rate
+ * @min_rate: returned rate must be greater than this rate
+ * @max_rate: returned rate must be less than this rate
+ *
+ * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate and
+ * .determine_rate.
+ */
+unsigned long __clk_determine_rate(struct clk_hw *hw,
+				   unsigned long rate,
+				   unsigned long min_rate,
+				   unsigned long max_rate)
+{
+	if (!hw)
+		return 0;
+
+	return clk_core_round_rate_nolock(hw->core, rate, min_rate, max_rate);
+}
+EXPORT_SYMBOL_GPL(__clk_determine_rate);
+
+/**
+ * __clk_round_rate - round the given rate for a clk
+ * @clk: round the rate of this clock
+ * @rate: the rate which is to be rounded
+ *
+ * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
+ */
+unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long min_rate;
+	unsigned long max_rate;
+
+	if (!clk)
+		return 0;
+
+	clk_core_get_boundaries(clk->core, &min_rate, &max_rate);
+
+	return clk_core_round_rate_nolock(clk->core, rate, min_rate, max_rate);
+}
 EXPORT_SYMBOL_GPL(__clk_round_rate);
 
 /**
@@ -980,6 +1183,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long ret;
 
+	if (!clk)
+		return 0;
+
 	clk_prepare_lock();
 	ret = __clk_round_rate(clk, rate);
 	clk_prepare_unlock();
@@ -1002,22 +1208,21 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
  * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
  * a driver returns that.
  */
-static int __clk_notify(struct clk *clk, unsigned long msg,
+static int __clk_notify(struct clk_core *clk, unsigned long msg,
 		unsigned long old_rate, unsigned long new_rate)
 {
 	struct clk_notifier *cn;
 	struct clk_notifier_data cnd;
 	int ret = NOTIFY_DONE;
 
-	cnd.clk = clk;
 	cnd.old_rate = old_rate;
 	cnd.new_rate = new_rate;
 
 	list_for_each_entry(cn, &clk_notifier_list, node) {
-		if (cn->clk == clk) {
+		if (cn->clk->core == clk) {
+			cnd.clk = cn->clk;
 			ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
 					&cnd);
-			break;
 		}
 	}
 
@@ -1035,10 +1240,10 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
  *
  * Caller must hold prepare_lock.
  */
-static void __clk_recalc_accuracies(struct clk *clk)
+static void __clk_recalc_accuracies(struct clk_core *clk)
 {
 	unsigned long parent_accuracy = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 	if (clk->parent)
 		parent_accuracy = clk->parent->accuracy;
@@ -1053,6 +1258,20 @@ static void __clk_recalc_accuracies(struct clk *clk)
 		__clk_recalc_accuracies(child);
 }
 
+static long clk_core_get_accuracy(struct clk_core *clk)
+{
+	unsigned long accuracy;
+
+	clk_prepare_lock();
+	if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
+		__clk_recalc_accuracies(clk);
+
+	accuracy = __clk_get_accuracy(clk);
+	clk_prepare_unlock();
+
+	return accuracy;
+}
+
 /**
  * clk_get_accuracy - return the accuracy of clk
  * @clk: the clk whose accuracy is being returned
@@ -1064,20 +1283,15 @@ static void __clk_recalc_accuracies(struct clk *clk)
  */
 long clk_get_accuracy(struct clk *clk)
 {
-	unsigned long accuracy;
-
-	clk_prepare_lock();
-	if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
-		__clk_recalc_accuracies(clk);
-
-	accuracy = __clk_get_accuracy(clk);
-	clk_prepare_unlock();
+	if (!clk)
+		return 0;
 
-	return accuracy;
+	return clk_core_get_accuracy(clk->core);
 }
 EXPORT_SYMBOL_GPL(clk_get_accuracy);
 
-static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate)
+static unsigned long clk_recalc(struct clk_core *clk,
+				unsigned long parent_rate)
 {
 	if (clk->ops->recalc_rate)
 		return clk->ops->recalc_rate(clk->hw, parent_rate);
@@ -1098,11 +1312,11 @@ static unsigned long clk_recalc(struct clk *clk, unsigned long parent_rate)
  *
  * Caller must hold prepare_lock.
  */
-static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
+static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg)
 {
 	unsigned long old_rate;
 	unsigned long parent_rate = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 	old_rate = clk->rate;
 
@@ -1122,15 +1336,7 @@ static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
 		__clk_recalc_rates(child, msg);
 }
 
-/**
- * clk_get_rate - return the rate of clk
- * @clk: the clk whose rate is being returned
- *
- * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
- * is set, which means a recalc_rate will be issued.
- * If clk is NULL then returns 0.
- */
-unsigned long clk_get_rate(struct clk *clk)
+static unsigned long clk_core_get_rate(struct clk_core *clk)
 {
 	unsigned long rate;
 
@@ -1139,14 +1345,32 @@ unsigned long clk_get_rate(struct clk *clk)
 	if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
 		__clk_recalc_rates(clk, 0);
 
-	rate = __clk_get_rate(clk);
+	rate = clk_core_get_rate_nolock(clk);
 	clk_prepare_unlock();
 
 	return rate;
 }
+EXPORT_SYMBOL_GPL(clk_core_get_rate);
+
+/**
+ * clk_get_rate - return the rate of clk
+ * @clk: the clk whose rate is being returned
+ *
+ * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
+ * is set, which means a recalc_rate will be issued.
+ * If clk is NULL then returns 0.
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return clk_core_get_rate(clk->core);
+}
 EXPORT_SYMBOL_GPL(clk_get_rate);
 
-static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
+static int clk_fetch_parent_index(struct clk_core *clk,
+				  struct clk_core *parent)
 {
 	int i;
 
@@ -1160,7 +1384,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 	/*
 	 * find index of new parent clock using cached parent ptrs,
 	 * or if not yet cached, use string name comparison and cache
-	 * them now to avoid future calls to __clk_lookup.
+	 * them now to avoid future calls to clk_core_lookup.
 	 */
 	for (i = 0; i < clk->num_parents; i++) {
 		if (clk->parents[i] == parent)
@@ -1170,7 +1394,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 			continue;
 
 		if (!strcmp(clk->parent_names[i], parent->name)) {
-			clk->parents[i] = __clk_lookup(parent->name);
+			clk->parents[i] = clk_core_lookup(parent->name);
 			return i;
 		}
 	}
@@ -1178,7 +1402,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 	return -EINVAL;
 }
 
-static void clk_reparent(struct clk *clk, struct clk *new_parent)
+static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent)
 {
 	hlist_del(&clk->child_node);
 
@@ -1195,10 +1419,11 @@ static void clk_reparent(struct clk *clk, struct clk *new_parent)
 	clk->parent = new_parent;
 }
 
-static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
+static struct clk_core *__clk_set_parent_before(struct clk_core *clk,
+					   struct clk_core *parent)
 {
 	unsigned long flags;
-	struct clk *old_parent = clk->parent;
+	struct clk_core *old_parent = clk->parent;
 
 	/*
 	 * Migrate prepare state between parents and prevent race with
@@ -1218,9 +1443,9 @@ static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
 	 * See also: Comment for clk_set_parent() below.
 	 */
 	if (clk->prepare_count) {
-		__clk_prepare(parent);
-		clk_enable(parent);
-		clk_enable(clk);
+		clk_core_prepare(parent);
+		clk_core_enable(parent);
+		clk_core_enable(clk);
 	}
 
 	/* update the clk tree topology */
@@ -1231,25 +1456,27 @@ static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
 	return old_parent;
 }
 
-static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
-		struct clk *old_parent)
+static void __clk_set_parent_after(struct clk_core *core,
+				   struct clk_core *parent,
+				   struct clk_core *old_parent)
 {
 	/*
 	 * Finish the migration of prepare state and undo the changes done
 	 * for preventing a race with clk_enable().
 	 */
-	if (clk->prepare_count) {
-		clk_disable(clk);
-		clk_disable(old_parent);
-		__clk_unprepare(old_parent);
+	if (core->prepare_count) {
+		clk_core_disable(core);
+		clk_core_disable(old_parent);
+		clk_core_unprepare(old_parent);
 	}
 }
 
-static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
+			    u8 p_index)
 {
 	unsigned long flags;
 	int ret = 0;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 	old_parent = __clk_set_parent_before(clk, parent);
 
@@ -1263,9 +1490,9 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
 		clk_enable_unlock(flags);
 
 		if (clk->prepare_count) {
-			clk_disable(clk);
-			clk_disable(parent);
-			__clk_unprepare(parent);
+			clk_core_disable(clk);
+			clk_core_disable(parent);
+			clk_core_unprepare(parent);
 		}
 		return ret;
 	}
@@ -1291,9 +1518,10 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
  *
  * Caller must hold prepare_lock.
  */
-static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
+static int __clk_speculate_rates(struct clk_core *clk,
+				 unsigned long parent_rate)
 {
-	struct clk *child;
+	struct clk_core *child;
 	unsigned long new_rate;
 	int ret = NOTIFY_DONE;
 
@@ -1319,10 +1547,10 @@ out:
 	return ret;
 }
 
-static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
-			     struct clk *new_parent, u8 p_index)
+static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
+			     struct clk_core *new_parent, u8 p_index)
 {
-	struct clk *child;
+	struct clk_core *child;
 
 	clk->new_rate = new_rate;
 	clk->new_parent = new_parent;
@@ -1342,13 +1570,16 @@ static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
  * calculate the new rates returning the topmost clock that has to be
  * changed.
  */
-static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
+static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
+					   unsigned long rate)
 {
-	struct clk *top = clk;
-	struct clk *old_parent, *parent;
+	struct clk_core *top = clk;
+	struct clk_core *old_parent, *parent;
 	struct clk_hw *parent_hw;
 	unsigned long best_parent_rate = 0;
 	unsigned long new_rate;
+	unsigned long min_rate;
+	unsigned long max_rate;
 	int p_index = 0;
 
 	/* sanity */
@@ -1360,16 +1591,22 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
 	if (parent)
 		best_parent_rate = parent->rate;
 
+	clk_core_get_boundaries(clk, &min_rate, &max_rate);
+
 	/* find the closest rate and parent clk/rate */
 	if (clk->ops->determine_rate) {
 		parent_hw = parent ? parent->hw : NULL;
 		new_rate = clk->ops->determine_rate(clk->hw, rate,
+						    min_rate,
+						    max_rate,
 						    &best_parent_rate,
 						    &parent_hw);
-		parent = parent_hw ? parent_hw->clk : NULL;
+		parent = parent_hw ? parent_hw->core : NULL;
 	} else if (clk->ops->round_rate) {
 		new_rate = clk->ops->round_rate(clk->hw, rate,
 						&best_parent_rate);
+		if (new_rate < min_rate || new_rate > max_rate)
+			return NULL;
 	} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
 		/* pass-through clock without adjustable parent */
 		clk->new_rate = clk->rate;
@@ -1390,7 +1627,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
 	}
 
 	/* try finding the new parent index */
-	if (parent) {
+	if (parent && clk->num_parents > 1) {
 		p_index = clk_fetch_parent_index(clk, parent);
 		if (p_index < 0) {
 			pr_debug("%s: clk %s can not be parent of clk %s\n",
@@ -1414,9 +1651,10 @@ out:
  * so that in case of an error we can walk down the whole tree again and
  * abort the change.
  */
-static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
+static struct clk_core *clk_propagate_rate_change(struct clk_core *clk,
+						  unsigned long event)
 {
-	struct clk *child, *tmp_clk, *fail_clk = NULL;
+	struct clk_core *child, *tmp_clk, *fail_clk = NULL;
 	int ret = NOTIFY_DONE;
 
 	if (clk->rate == clk->new_rate)
@@ -1451,14 +1689,14 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
  * walk down a subtree and set the new rates notifying the rate
  * change on the way
  */
-static void clk_change_rate(struct clk *clk)
+static void clk_change_rate(struct clk_core *clk)
 {
-	struct clk *child;
+	struct clk_core *child;
 	struct hlist_node *tmp;
 	unsigned long old_rate;
 	unsigned long best_parent_rate = 0;
 	bool skip_set_rate = false;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 	old_rate = clk->rate;
 
@@ -1506,6 +1744,45 @@ static void clk_change_rate(struct clk *clk)
 		clk_change_rate(clk->new_child);
 }
 
+static int clk_core_set_rate_nolock(struct clk_core *clk,
+				    unsigned long req_rate)
+{
+	struct clk_core *top, *fail_clk;
+	unsigned long rate = req_rate;
+	int ret = 0;
+
+	if (!clk)
+		return 0;
+
+	/* bail early if nothing to do */
+	if (rate == clk_core_get_rate_nolock(clk))
+		return 0;
+
+	if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count)
+		return -EBUSY;
+
+	/* calculate new rates and get the topmost changed clock */
+	top = clk_calc_new_rates(clk, rate);
+	if (!top)
+		return -EINVAL;
+
+	/* notify that we are about to change rates */
+	fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
+	if (fail_clk) {
+		pr_debug("%s: failed to set %s rate\n", __func__,
+				fail_clk->name);
+		clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
+		return -EBUSY;
+	}
+
+	/* change the rates */
+	clk_change_rate(top);
+
+	clk->req_rate = req_rate;
+
+	return ret;
+}
+
 /**
  * clk_set_rate - specify a new rate for clk
  * @clk: the clk whose rate is being changed
@@ -1529,8 +1806,7 @@ static void clk_change_rate(struct clk *clk)
  */
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-	struct clk *top, *fail_clk;
-	int ret = 0;
+	int ret;
 
 	if (!clk)
 		return 0;
@@ -1538,41 +1814,81 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	/* prevent racing with updates to the clock topology */
 	clk_prepare_lock();
 
-	/* bail early if nothing to do */
-	if (rate == clk_get_rate(clk))
-		goto out;
+	ret = clk_core_set_rate_nolock(clk->core, rate);
 
-	if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
-		ret = -EBUSY;
-		goto out;
-	}
+	clk_prepare_unlock();
 
-	/* calculate new rates and get the topmost changed clock */
-	top = clk_calc_new_rates(clk, rate);
-	if (!top) {
-		ret = -EINVAL;
-		goto out;
-	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
 
-	/* notify that we are about to change rates */
-	fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
-	if (fail_clk) {
-		pr_debug("%s: failed to set %s rate\n", __func__,
-				fail_clk->name);
-		clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
-		ret = -EBUSY;
-		goto out;
+/**
+ * clk_set_rate_range - set a rate range for a clock source
+ * @clk: clock source
+ * @min: desired minimum clock rate in Hz, inclusive
+ * @max: desired maximum clock rate in Hz, inclusive
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
+{
+	int ret = 0;
+
+	if (!clk)
+		return 0;
+
+	if (min > max) {
+		pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n",
+		       __func__, clk->core->name, clk->dev_id, clk->con_id,
+		       min, max);
+		return -EINVAL;
 	}
 
-	/* change the rates */
-	clk_change_rate(top);
+	clk_prepare_lock();
+
+	if (min != clk->min_rate || max != clk->max_rate) {
+		clk->min_rate = min;
+		clk->max_rate = max;
+		ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
+	}
 
-out:
 	clk_prepare_unlock();
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(clk_set_rate);
+EXPORT_SYMBOL_GPL(clk_set_rate_range);
+
+/**
+ * clk_set_min_rate - set a minimum clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired minimum clock rate in Hz, inclusive
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_min_rate(struct clk *clk, unsigned long rate)
+{
+	if (!clk)
+		return 0;
+
+	return clk_set_rate_range(clk, rate, clk->max_rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_min_rate);
+
+/**
+ * clk_set_max_rate - set a maximum clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired maximum clock rate in Hz, inclusive
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_max_rate(struct clk *clk, unsigned long rate)
+{
+	if (!clk)
+		return 0;
+
+	return clk_set_rate_range(clk, clk->min_rate, rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_max_rate);
 
 /**
  * clk_get_parent - return the parent of a clk
@@ -1599,11 +1915,11 @@ EXPORT_SYMBOL_GPL(clk_get_parent);
  *
  * For single-parent clocks without .get_parent, first check to see if the
  * .parents array exists, and if so use it to avoid an expensive tree
- * traversal.  If .parents does not exist then walk the tree with __clk_lookup.
+ * traversal.  If .parents does not exist then walk the tree.
  */
-static struct clk *__clk_init_parent(struct clk *clk)
+static struct clk_core *__clk_init_parent(struct clk_core *clk)
 {
-	struct clk *ret = NULL;
+	struct clk_core *ret = NULL;
 	u8 index;
 
 	/* handle the trivial cases */
@@ -1613,7 +1929,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
 
 	if (clk->num_parents == 1) {
 		if (IS_ERR_OR_NULL(clk->parent))
-			clk->parent = __clk_lookup(clk->parent_names[0]);
+			clk->parent = clk_core_lookup(clk->parent_names[0]);
 		ret = clk->parent;
 		goto out;
 	}
@@ -1627,8 +1943,8 @@ static struct clk *__clk_init_parent(struct clk *clk)
 
 	/*
 	 * Do our best to cache parent clocks in clk->parents.  This prevents
-	 * unnecessary and expensive calls to __clk_lookup.  We don't set
-	 * clk->parent here; that is done by the calling function
+	 * unnecessary and expensive lookups.  We don't set clk->parent here;
+	 * that is done by the calling function.
 	 */
 
 	index = clk->ops->get_parent(clk->hw);
@@ -1638,13 +1954,14 @@ static struct clk *__clk_init_parent(struct clk *clk)
 			kcalloc(clk->num_parents, sizeof(struct clk *),
 					GFP_KERNEL);
 
-	ret = clk_get_parent_by_index(clk, index);
+	ret = clk_core_get_parent_by_index(clk, index);
 
 out:
 	return ret;
 }
 
-void __clk_reparent(struct clk *clk, struct clk *new_parent)
+static void clk_core_reparent(struct clk_core *clk,
+				  struct clk_core *new_parent)
 {
 	clk_reparent(clk, new_parent);
 	__clk_recalc_accuracies(clk);
@@ -1652,23 +1969,40 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent)
 }
 
 /**
- * clk_set_parent - switch the parent of a mux clk
- * @clk: the mux clk whose input we are switching
- * @parent: the new input to clk
+ * clk_has_parent - check if a clock is a possible parent for another
+ * @clk: clock source
+ * @parent: parent clock source
  *
- * Re-parent clk to use parent as its new input source.  If clk is in
- * prepared state, the clk will get enabled for the duration of this call. If
- * that's not acceptable for a specific clk (Eg: the consumer can't handle
- * that, the reparenting is glitchy in hardware, etc), use the
- * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
- *
- * After successfully changing clk's parent clk_set_parent will update the
- * clk topology, sysfs topology and propagate rate recalculation via
- * __clk_recalc_rates.
+ * This function can be used in drivers that need to check that a clock can be
+ * the parent of another without actually changing the parent.
  *
- * Returns 0 on success, -EERROR otherwise.
+ * Returns true if @parent is a possible parent for @clk, false otherwise.
  */
-int clk_set_parent(struct clk *clk, struct clk *parent)
+bool clk_has_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk_core *core, *parent_core;
+	unsigned int i;
+
+	/* NULL clocks should be nops, so return success if either is NULL. */
+	if (!clk || !parent)
+		return true;
+
+	core = clk->core;
+	parent_core = parent->core;
+
+	/* Optimize for the case where the parent is already the parent. */
+	if (core->parent == parent_core)
+		return true;
+
+	for (i = 0; i < core->num_parents; i++)
+		if (strcmp(core->parent_names[i], parent_core->name) == 0)
+			return true;
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(clk_has_parent);
+
+static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent)
 {
 	int ret = 0;
 	int p_index = 0;
@@ -1728,6 +2062,31 @@ out:
 
 	return ret;
 }
+
+/**
+ * clk_set_parent - switch the parent of a mux clk
+ * @clk: the mux clk whose input we are switching
+ * @parent: the new input to clk
+ *
+ * Re-parent clk to use parent as its new input source.  If clk is in
+ * prepared state, the clk will get enabled for the duration of this call. If
+ * that's not acceptable for a specific clk (Eg: the consumer can't handle
+ * that, the reparenting is glitchy in hardware, etc), use the
+ * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
+ *
+ * After successfully changing clk's parent clk_set_parent will update the
+ * clk topology, sysfs topology and propagate rate recalculation via
+ * __clk_recalc_rates.
+ *
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (!clk)
+		return 0;
+
+	return clk_core_set_parent(clk->core, parent ? parent->core : NULL);
+}
 EXPORT_SYMBOL_GPL(clk_set_parent);
 
 /**
@@ -1764,13 +2123,13 @@ int clk_set_phase(struct clk *clk, int degrees)
 
 	clk_prepare_lock();
 
-	if (!clk->ops->set_phase)
+	if (!clk->core->ops->set_phase)
 		goto out_unlock;
 
-	ret = clk->ops->set_phase(clk->hw, degrees);
+	ret = clk->core->ops->set_phase(clk->core->hw, degrees);
 
 	if (!ret)
-		clk->phase = degrees;
+		clk->core->phase = degrees;
 
 out_unlock:
 	clk_prepare_unlock();
@@ -1778,15 +2137,9 @@ out_unlock:
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(clk_set_phase);
 
-/**
- * clk_get_phase - return the phase shift of a clock signal
- * @clk: clock signal source
- *
- * Returns the phase shift of a clock node in degrees, otherwise returns
- * -EERROR.
- */
-int clk_get_phase(struct clk *clk)
+static int clk_core_get_phase(struct clk_core *clk)
 {
 	int ret = 0;
 
@@ -1800,28 +2153,48 @@ int clk_get_phase(struct clk *clk)
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(clk_get_phase);
+
+/**
+ * clk_get_phase - return the phase shift of a clock signal
+ * @clk: clock signal source
+ *
+ * Returns the phase shift of a clock node in degrees, otherwise returns
+ * -EERROR.
+ */
+int clk_get_phase(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return clk_core_get_phase(clk->core);
+}
 
 /**
  * __clk_init - initialize the data structures in a struct clk
  * @dev:	device initializing this clk, placeholder for now
  * @clk:	clk being initialized
  *
- * Initializes the lists in struct clk, queries the hardware for the
+ * Initializes the lists in struct clk_core, queries the hardware for the
  * parent and rate and sets them both.
  */
-int __clk_init(struct device *dev, struct clk *clk)
+static int __clk_init(struct device *dev, struct clk *clk_user)
 {
 	int i, ret = 0;
-	struct clk *orphan;
+	struct clk_core *orphan;
 	struct hlist_node *tmp2;
+	struct clk_core *clk;
+	unsigned long rate;
 
-	if (!clk)
+	if (!clk_user)
 		return -EINVAL;
 
+	clk = clk_user->core;
+
 	clk_prepare_lock();
 
 	/* check to see if a clock with this name is already registered */
-	if (__clk_lookup(clk->name)) {
+	if (clk_core_lookup(clk->name)) {
 		pr_debug("%s: clk %s already initialized\n",
 				__func__, clk->name);
 		ret = -EEXIST;
@@ -1873,7 +2246,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 		clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
 					GFP_KERNEL);
 		/*
-		 * __clk_lookup returns NULL for parents that have not been
+		 * clk_core_lookup returns NULL for parents that have not been
 		 * clk_init'd; thus any access to clk->parents[] must check
 		 * for a NULL pointer.  We can always perform lazy lookups for
 		 * missing parents later on.
@@ -1881,7 +2254,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 		if (clk->parents)
 			for (i = 0; i < clk->num_parents; i++)
 				clk->parents[i] =
-					__clk_lookup(clk->parent_names[i]);
+					clk_core_lookup(clk->parent_names[i]);
 	}
 
 	clk->parent = __clk_init_parent(clk);
@@ -1936,12 +2309,13 @@ int __clk_init(struct device *dev, struct clk *clk)
 	 * then rate is set to zero.
 	 */
 	if (clk->ops->recalc_rate)
-		clk->rate = clk->ops->recalc_rate(clk->hw,
-				__clk_get_rate(clk->parent));
+		rate = clk->ops->recalc_rate(clk->hw,
+				clk_core_get_rate_nolock(clk->parent));
 	else if (clk->parent)
-		clk->rate = clk->parent->rate;
+		rate = clk->parent->rate;
 	else
-		clk->rate = 0;
+		rate = 0;
+	clk->rate = clk->req_rate = rate;
 
 	/*
 	 * walk the list of orphan clocks and reparent any that are children of
@@ -1951,13 +2325,13 @@ int __clk_init(struct device *dev, struct clk *clk)
 		if (orphan->num_parents && orphan->ops->get_parent) {
 			i = orphan->ops->get_parent(orphan->hw);
 			if (!strcmp(clk->name, orphan->parent_names[i]))
-				__clk_reparent(orphan, clk);
+				clk_core_reparent(orphan, clk);
 			continue;
 		}
 
 		for (i = 0; i < orphan->num_parents; i++)
 			if (!strcmp(clk->name, orphan->parent_names[i])) {
-				__clk_reparent(orphan, clk);
+				clk_core_reparent(orphan, clk);
 				break;
 			}
 	 }
@@ -1983,47 +2357,39 @@ out:
 	return ret;
 }
 
-/**
- * __clk_register - register a clock and return a cookie.
- *
- * Same as clk_register, except that the .clk field inside hw shall point to a
- * preallocated (generally statically allocated) struct clk. None of the fields
- * of the struct clk need to be initialized.
- *
- * The data pointed to by .init and .clk field shall NOT be marked as init
- * data.
- *
- * __clk_register is only exposed via clk-private.h and is intended for use with
- * very large numbers of clocks that need to be statically initialized.  It is
- * a layering violation to include clk-private.h from any code which implements
- * a clock's .ops; as such any statically initialized clock data MUST be in a
- * separate C file from the logic that implements its operations.  Returns 0
- * on success, otherwise an error code.
- */
-struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
+struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+			     const char *con_id)
 {
-	int ret;
 	struct clk *clk;
 
-	clk = hw->clk;
-	clk->name = hw->init->name;
-	clk->ops = hw->init->ops;
-	clk->hw = hw;
-	clk->flags = hw->init->flags;
-	clk->parent_names = hw->init->parent_names;
-	clk->num_parents = hw->init->num_parents;
-	if (dev && dev->driver)
-		clk->owner = dev->driver->owner;
-	else
-		clk->owner = NULL;
+	/* This is to allow this function to be chained to others */
+	if (!hw || IS_ERR(hw))
+		return (struct clk *) hw;
 
-	ret = __clk_init(dev, clk);
-	if (ret)
-		return ERR_PTR(ret);
+	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	clk->core = hw->core;
+	clk->dev_id = dev_id;
+	clk->con_id = con_id;
+	clk->max_rate = ULONG_MAX;
+
+	clk_prepare_lock();
+	hlist_add_head(&clk->child_node, &hw->core->clks);
+	clk_prepare_unlock();
 
 	return clk;
 }
-EXPORT_SYMBOL_GPL(__clk_register);
+
+void __clk_free_clk(struct clk *clk)
+{
+	clk_prepare_lock();
+	hlist_del(&clk->child_node);
+	clk_prepare_unlock();
+
+	kfree(clk);
+}
 
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
@@ -2039,7 +2405,7 @@ EXPORT_SYMBOL_GPL(__clk_register);
 struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 {
 	int i, ret;
-	struct clk *clk;
+	struct clk_core *clk;
 
 	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
 	if (!clk) {
@@ -2060,7 +2426,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 	clk->hw = hw;
 	clk->flags = hw->init->flags;
 	clk->num_parents = hw->init->num_parents;
-	hw->clk = clk;
+	hw->core = clk;
 
 	/* allocate local copy in case parent_names is __initdata */
 	clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
@@ -2084,9 +2450,21 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 		}
 	}
 
-	ret = __clk_init(dev, clk);
+	INIT_HLIST_HEAD(&clk->clks);
+
+	hw->clk = __clk_create_clk(hw, NULL, NULL);
+	if (IS_ERR(hw->clk)) {
+		pr_err("%s: could not allocate per-user clk\n", __func__);
+		ret = PTR_ERR(hw->clk);
+		goto fail_parent_names_copy;
+	}
+
+	ret = __clk_init(dev, hw->clk);
 	if (!ret)
-		return clk;
+		return hw->clk;
+
+	__clk_free_clk(hw->clk);
+	hw->clk = NULL;
 
 fail_parent_names_copy:
 	while (--i >= 0)
@@ -2107,7 +2485,7 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
 static void __clk_release(struct kref *ref)
 {
-	struct clk *clk = container_of(ref, struct clk, ref);
+	struct clk_core *clk = container_of(ref, struct clk_core, ref);
 	int i = clk->num_parents;
 
 	kfree(clk->parents);
@@ -2165,12 +2543,13 @@ void clk_unregister(struct clk *clk)
 	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
 		return;
 
-	clk_debug_unregister(clk);
+	clk_debug_unregister(clk->core);
 
 	clk_prepare_lock();
 
-	if (clk->ops == &clk_nodrv_ops) {
-		pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
+	if (clk->core->ops == &clk_nodrv_ops) {
+		pr_err("%s: unregistered clock: %s\n", __func__,
+		       clk->core->name);
 		return;
 	}
 	/*
@@ -2178,24 +2557,25 @@ void clk_unregister(struct clk *clk)
 	 * a reference to this clock.
 	 */
 	flags = clk_enable_lock();
-	clk->ops = &clk_nodrv_ops;
+	clk->core->ops = &clk_nodrv_ops;
 	clk_enable_unlock(flags);
 
-	if (!hlist_empty(&clk->children)) {
-		struct clk *child;
+	if (!hlist_empty(&clk->core->children)) {
+		struct clk_core *child;
 		struct hlist_node *t;
 
 		/* Reparent all children to the orphan list. */
-		hlist_for_each_entry_safe(child, t, &clk->children, child_node)
-			clk_set_parent(child, NULL);
+		hlist_for_each_entry_safe(child, t, &clk->core->children,
+					  child_node)
+			clk_core_set_parent(child, NULL);
 	}
 
-	hlist_del_init(&clk->child_node);
+	hlist_del_init(&clk->core->child_node);
 
-	if (clk->prepare_count)
+	if (clk->core->prepare_count)
 		pr_warn("%s: unregistering prepared clock: %s\n",
-					__func__, clk->name);
-	kref_put(&clk->ref, __clk_release);
+					__func__, clk->core->name);
+	kref_put(&clk->core->ref, __clk_release);
 
 	clk_prepare_unlock();
 }
@@ -2263,11 +2643,13 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
  */
 int __clk_get(struct clk *clk)
 {
-	if (clk) {
-		if (!try_module_get(clk->owner))
+	struct clk_core *core = !clk ? NULL : clk->core;
+
+	if (core) {
+		if (!try_module_get(core->owner))
 			return 0;
 
-		kref_get(&clk->ref);
+		kref_get(&core->ref);
 	}
 	return 1;
 }
@@ -2280,11 +2662,20 @@ void __clk_put(struct clk *clk)
 		return;
 
 	clk_prepare_lock();
-	owner = clk->owner;
-	kref_put(&clk->ref, __clk_release);
+
+	hlist_del(&clk->child_node);
+	if (clk->min_rate > clk->core->req_rate ||
+	    clk->max_rate < clk->core->req_rate)
+		clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
+
+	owner = clk->core->owner;
+	kref_put(&clk->core->ref, __clk_release);
+
 	clk_prepare_unlock();
 
 	module_put(owner);
+
+	kfree(clk);
 }
 
 /***        clk rate change notifiers        ***/
@@ -2339,7 +2730,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
 
 	ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
 
-	clk->notifier_count++;
+	clk->core->notifier_count++;
 
 out:
 	clk_prepare_unlock();
@@ -2376,7 +2767,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
 	if (cn->clk == clk) {
 		ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
 
-		clk->notifier_count--;
+		clk->core->notifier_count--;
 
 		/* XXX the notifier code should handle this better */
 		if (!cn->notifier_head.head) {
@@ -2506,7 +2897,8 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
-struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
+struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
+				       const char *dev_id, const char *con_id)
 {
 	struct of_clk_provider *provider;
 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
@@ -2515,8 +2907,17 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
 	list_for_each_entry(provider, &of_clk_providers, link) {
 		if (provider->node == clkspec->np)
 			clk = provider->get(clkspec, provider->data);
-		if (!IS_ERR(clk))
+		if (!IS_ERR(clk)) {
+			clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
+					       con_id);
+
+			if (!IS_ERR(clk) && !__clk_get(clk)) {
+				__clk_free_clk(clk);
+				clk = ERR_PTR(-ENOENT);
+			}
+
 			break;
+		}
 	}
 
 	return clk;
@@ -2527,7 +2928,7 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 	struct clk *clk;
 
 	mutex_lock(&of_clk_mutex);
-	clk = __of_clk_get_from_provider(clkspec);
+	clk = __of_clk_get_from_provider(clkspec, NULL, __func__);
 	mutex_unlock(&of_clk_mutex);
 
 	return clk;

+ 23 - 1
drivers/clk/clk.h

@@ -9,9 +9,31 @@
  * published by the Free Software Foundation.
  */
 
+struct clk_hw;
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec);
-struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
+struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
+				       const char *dev_id, const char *con_id);
 void of_clk_lock(void);
 void of_clk_unlock(void);
 #endif
+
+#ifdef CONFIG_COMMON_CLK
+struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+			     const char *con_id);
+void __clk_free_clk(struct clk *clk);
+#else
+/* All these casts to avoid ifdefs in clkdev... */
+static inline struct clk *
+__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
+{
+	return (struct clk *)hw;
+}
+static inline void __clk_free_clk(struct clk *clk) { }
+static struct clk_hw *__clk_get_hw(struct clk *clk)
+{
+	return (struct clk_hw *)clk;
+}
+
+#endif

+ 76 - 34
drivers/clk/clkdev.c

@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/of.h>
 
 #include "clk.h"
@@ -28,6 +29,20 @@ static DEFINE_MUTEX(clocks_mutex);
 
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 
+static struct clk *__of_clk_get_by_clkspec(struct of_phandle_args *clkspec,
+					 const char *dev_id, const char *con_id)
+{
+	struct clk *clk;
+
+	if (!clkspec)
+		return ERR_PTR(-EINVAL);
+
+	of_clk_lock();
+	clk = __of_clk_get_from_provider(clkspec, dev_id, con_id);
+	of_clk_unlock();
+	return clk;
+}
+
 /**
  * of_clk_get_by_clkspec() - Lookup a clock form a clock provider
  * @clkspec: pointer to a clock specifier data structure
@@ -38,22 +53,11 @@ static DEFINE_MUTEX(clocks_mutex);
  */
 struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
 {
-	struct clk *clk;
-
-	if (!clkspec)
-		return ERR_PTR(-EINVAL);
-
-	of_clk_lock();
-	clk = __of_clk_get_from_provider(clkspec);
-
-	if (!IS_ERR(clk) && !__clk_get(clk))
-		clk = ERR_PTR(-ENOENT);
-
-	of_clk_unlock();
-	return clk;
+	return __of_clk_get_by_clkspec(clkspec, NULL, __func__);
 }
 
-struct clk *of_clk_get(struct device_node *np, int index)
+static struct clk *__of_clk_get(struct device_node *np, int index,
+			       const char *dev_id, const char *con_id)
 {
 	struct of_phandle_args clkspec;
 	struct clk *clk;
@@ -67,22 +71,21 @@ struct clk *of_clk_get(struct device_node *np, int index)
 	if (rc)
 		return ERR_PTR(rc);
 
-	clk = of_clk_get_by_clkspec(&clkspec);
+	clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
 	of_node_put(clkspec.np);
+
 	return clk;
 }
+
+struct clk *of_clk_get(struct device_node *np, int index)
+{
+	return __of_clk_get(np, index, np->full_name, NULL);
+}
 EXPORT_SYMBOL(of_clk_get);
 
-/**
- * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
- * @np: pointer to clock consumer node
- * @name: name of consumer's clock input, or NULL for the first clock reference
- *
- * This function parses the clocks and clock-names properties,
- * and uses them to look up the struct clk from the registered list of clock
- * providers.
- */
-struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+static struct clk *__of_clk_get_by_name(struct device_node *np,
+					const char *dev_id,
+					const char *name)
 {
 	struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -97,10 +100,10 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 		 */
 		if (name)
 			index = of_property_match_string(np, "clock-names", name);
-		clk = of_clk_get(np, index);
-		if (!IS_ERR(clk))
+		clk = __of_clk_get(np, index, dev_id, name);
+		if (!IS_ERR(clk)) {
 			break;
-		else if (name && index >= 0) {
+		} else if (name && index >= 0) {
 			if (PTR_ERR(clk) != -EPROBE_DEFER)
 				pr_err("ERROR: could not get clock %s:%s(%i)\n",
 					np->full_name, name ? name : "", index);
@@ -119,7 +122,33 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 
 	return clk;
 }
+
+/**
+ * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ */
+struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+{
+	if (!np)
+		return ERR_PTR(-ENOENT);
+
+	return __of_clk_get_by_name(np, np->full_name, name);
+}
 EXPORT_SYMBOL(of_clk_get_by_name);
+
+#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
+
+static struct clk *__of_clk_get_by_name(struct device_node *np,
+					const char *dev_id,
+					const char *name)
+{
+	return ERR_PTR(-ENOENT);
+}
 #endif
 
 /*
@@ -168,14 +197,28 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
 struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 {
 	struct clk_lookup *cl;
+	struct clk *clk = NULL;
 
 	mutex_lock(&clocks_mutex);
+
 	cl = clk_find(dev_id, con_id);
-	if (cl && !__clk_get(cl->clk))
+	if (!cl)
+		goto out;
+
+	clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id);
+	if (IS_ERR(clk))
+		goto out;
+
+	if (!__clk_get(clk)) {
+		__clk_free_clk(clk);
 		cl = NULL;
+		goto out;
+	}
+
+out:
 	mutex_unlock(&clocks_mutex);
 
-	return cl ? cl->clk : ERR_PTR(-ENOENT);
+	return cl ? clk : ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL(clk_get_sys);
 
@@ -185,10 +228,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
 	struct clk *clk;
 
 	if (dev) {
-		clk = of_clk_get_by_name(dev->of_node, con_id);
-		if (!IS_ERR(clk))
-			return clk;
-		if (PTR_ERR(clk) == -EPROBE_DEFER)
+		clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+		if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
 			return clk;
 	}
 
@@ -331,6 +372,7 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 
 	return 0;
 }
+EXPORT_SYMBOL(clk_register_clkdev);
 
 /**
  * clk_register_clkdevs - register a set of clk_lookup for a struct clk

+ 2 - 0
drivers/clk/hisilicon/clk-hi3620.c

@@ -295,6 +295,8 @@ static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
 }
 
 static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long min_rate,
+			      unsigned long max_rate,
 			      unsigned long *best_parent_rate,
 			      struct clk_hw **best_parent_p)
 {

+ 2 - 0
drivers/clk/mmp/clk-mix.c

@@ -202,6 +202,8 @@ error:
 }
 
 static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 {

+ 1 - 0
drivers/clk/pxa/Makefile

@@ -1,3 +1,4 @@
 obj-y				+= clk-pxa.o
 obj-$(CONFIG_PXA25x)		+= clk-pxa25x.o
 obj-$(CONFIG_PXA27x)		+= clk-pxa27x.o
+obj-$(CONFIG_PXA3xx)		+= clk-pxa3xx.o

+ 1 - 1
drivers/clk/pxa/clk-pxa.c

@@ -46,7 +46,7 @@ static unsigned long cken_recalc_rate(struct clk_hw *hw,
 		fix = &pclk->lp;
 	else
 		fix = &pclk->hp;
-	fix->hw.clk = hw->clk;
+	__clk_hw_set_clk(&fix->hw, hw);
 	return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate);
 }
 

+ 364 - 0
drivers/clk/pxa/clk-pxa3xx.c

@@ -0,0 +1,364 @@
+/*
+ * Marvell PXA3xxx family clocks
+ *
+ * Copyright (C) 2014 Robert Jarzmik
+ *
+ * Heavily inspired from former arch/arm/mach-pxa/pxa3xx.c
+ *
+ * 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; version 2 of the License.
+ *
+ * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
+ * should go away.
+ */
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
+
+#include <dt-bindings/clock/pxa-clock.h>
+#include "clk-pxa.h"
+
+#define KHz 1000
+#define MHz (1000 * 1000)
+
+enum {
+	PXA_CORE_60Mhz = 0,
+	PXA_CORE_RUN,
+	PXA_CORE_TURBO,
+};
+
+enum {
+	PXA_BUS_60Mhz = 0,
+	PXA_BUS_HSS,
+};
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
+
+/* crystal frequency to static memory controller multiplier (SMCFS) */
+static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
+static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 };
+
+static const char * const get_freq_khz[] = {
+	"core", "ring_osc_60mhz", "run", "cpll", "system_bus"
+};
+
+/*
+ * Get the clock frequency as reflected by ACSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa3xx_get_clk_frequency_khz(int info)
+{
+	struct clk *clk;
+	unsigned long clks[5];
+	int i;
+
+	for (i = 0; i < 5; i++) {
+		clk = clk_get(NULL, get_freq_khz[i]);
+		if (IS_ERR(clk)) {
+			clks[i] = 0;
+		} else {
+			clks[i] = clk_get_rate(clk);
+			clk_put(clk);
+		}
+	}
+	if (info) {
+		pr_info("RO Mode clock: %ld.%02ldMHz\n",
+			clks[1] / 1000000, (clks[0] % 1000000) / 10000);
+		pr_info("Run Mode clock: %ld.%02ldMHz\n",
+			clks[2] / 1000000, (clks[1] % 1000000) / 10000);
+		pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
+			clks[3] / 1000000, (clks[2] % 1000000) / 10000);
+		pr_info("System bus clock: %ld.%02ldMHz\n",
+			clks[4] / 1000000, (clks[4] % 1000000) / 10000);
+	}
+	return (unsigned int)clks[0];
+}
+
+static unsigned long clk_pxa3xx_ac97_get_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	unsigned long ac97_div, rate;
+
+	ac97_div = AC97_DIV;
+
+	/* This may loose precision for some rates but won't for the
+	 * standard 24.576MHz.
+	 */
+	rate = parent_rate / 2;
+	rate /= ((ac97_div >> 12) & 0x7fff);
+	rate *= (ac97_div & 0xfff);
+
+	return rate;
+}
+PARENTS(clk_pxa3xx_ac97) = { "spll_624mhz" };
+RATE_RO_OPS(clk_pxa3xx_ac97, "ac97");
+
+static unsigned long clk_pxa3xx_smemc_get_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	unsigned long acsr = ACSR;
+	unsigned long memclkcfg = __raw_readl(MEMCLKCFG);
+
+	return (parent_rate / 48)  * smcfs_mult[(acsr >> 23) & 0x7] /
+		df_clkdiv[(memclkcfg >> 16) & 0x3];
+}
+PARENTS(clk_pxa3xx_smemc) = { "spll_624mhz" };
+RATE_RO_OPS(clk_pxa3xx_smemc, "smemc");
+
+static bool pxa3xx_is_ring_osc_forced(void)
+{
+	unsigned long acsr = ACSR;
+
+	return acsr & ACCR_D0CS;
+}
+
+PARENTS(pxa3xx_pbus) = { "ring_osc_60mhz", "spll_624mhz" };
+PARENTS(pxa3xx_32Khz_bus) = { "osc_32_768khz", "osc_32_768khz" };
+PARENTS(pxa3xx_13MHz_bus) = { "osc_13mhz", "osc_13mhz" };
+PARENTS(pxa3xx_ac97_bus) = { "ring_osc_60mhz", "ac97" };
+PARENTS(pxa3xx_sbus) = { "ring_osc_60mhz", "system_bus" };
+PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
+
+#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENA : &CKENB)
+#define PXA3XX_CKEN(dev_id, con_id, parents, mult_lp, div_lp, mult_hp,	\
+		    div_hp, bit, is_lp, flags)				\
+	PXA_CKEN(dev_id, con_id, bit, parents, mult_lp, div_lp,		\
+		 mult_hp, div_hp, is_lp,  CKEN_AB(bit),			\
+		 (CKEN_ ## bit % 32), flags)
+#define PXA3XX_PBUS_CKEN(dev_id, con_id, bit, mult_lp, div_lp,		\
+			 mult_hp, div_hp, delay)			\
+	PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp,	\
+		    div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, 0)
+#define PXA3XX_CKEN_1RATE(dev_id, con_id, bit, parents)			\
+	PXA_CKEN_1RATE(dev_id, con_id, bit, parents,			\
+		       CKEN_AB(bit), (CKEN_ ## bit % 32), 0)
+
+static struct desc_clk_cken pxa3xx_clocks[] __initdata = {
+	PXA3XX_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 4, 1, 42, 1),
+	PXA3XX_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 4, 1, 42, 1),
+	PXA3XX_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 4, 1, 42, 1),
+	PXA3XX_PBUS_CKEN("pxa2xx-i2c.0", NULL, I2C, 2, 5, 1, 19, 0),
+	PXA3XX_PBUS_CKEN("pxa27x-udc", NULL, UDC, 1, 4, 1, 13, 5),
+	PXA3XX_PBUS_CKEN("pxa27x-ohci", NULL, USBH, 1, 4, 1, 13, 0),
+	PXA3XX_PBUS_CKEN("pxa3xx-u2d", NULL, USB2, 1, 4, 1, 13, 0),
+	PXA3XX_PBUS_CKEN("pxa27x-pwm.0", NULL, PWM0, 1, 6, 1, 48, 0),
+	PXA3XX_PBUS_CKEN("pxa27x-pwm.1", NULL, PWM1, 1, 6, 1, 48, 0),
+	PXA3XX_PBUS_CKEN("pxa2xx-mci.0", NULL, MMC1, 1, 4, 1, 24, 0),
+	PXA3XX_PBUS_CKEN("pxa2xx-mci.1", NULL, MMC2, 1, 4, 1, 24, 0),
+	PXA3XX_PBUS_CKEN("pxa2xx-mci.2", NULL, MMC3, 1, 4, 1, 24, 0),
+
+	PXA3XX_CKEN_1RATE("pxa27x-keypad", NULL, KEYPAD,
+			  pxa3xx_32Khz_bus_parents),
+	PXA3XX_CKEN_1RATE("pxa3xx-ssp.0", NULL, SSP1, pxa3xx_13MHz_bus_parents),
+	PXA3XX_CKEN_1RATE("pxa3xx-ssp.1", NULL, SSP2, pxa3xx_13MHz_bus_parents),
+	PXA3XX_CKEN_1RATE("pxa3xx-ssp.2", NULL, SSP3, pxa3xx_13MHz_bus_parents),
+	PXA3XX_CKEN_1RATE("pxa3xx-ssp.3", NULL, SSP4, pxa3xx_13MHz_bus_parents),
+
+	PXA3XX_CKEN(NULL, "AC97CLK", pxa3xx_ac97_bus_parents, 1, 4, 1, 1, AC97,
+		    pxa3xx_is_ring_osc_forced, 0),
+	PXA3XX_CKEN(NULL, "CAMCLK", pxa3xx_sbus_parents, 1, 2, 1, 1, CAMERA,
+		    pxa3xx_is_ring_osc_forced, 0),
+	PXA3XX_CKEN("pxa2xx-fb", NULL, pxa3xx_sbus_parents, 1, 1, 1, 1, LCD,
+		    pxa3xx_is_ring_osc_forced, 0),
+	PXA3XX_CKEN("pxa2xx-pcmcia", NULL, pxa3xx_smemcbus_parents, 1, 4,
+		    1, 1, SMC, pxa3xx_is_ring_osc_forced, CLK_IGNORE_UNUSED),
+};
+
+static struct desc_clk_cken pxa300_310_clocks[] __initdata = {
+
+	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
+	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
+	PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
+};
+
+static struct desc_clk_cken pxa320_clocks[] __initdata = {
+	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 6, 0),
+	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA320_GCU, 1, 1, 1, 1, 0),
+	PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
+};
+
+static struct desc_clk_cken pxa93x_clocks[] __initdata = {
+
+	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
+	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
+	PXA3XX_CKEN_1RATE("pxa93x-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
+};
+
+static unsigned long clk_pxa3xx_system_bus_get_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	unsigned long acsr = ACSR;
+	unsigned int hss = (acsr >> 14) & 0x3;
+
+	if (pxa3xx_is_ring_osc_forced())
+		return parent_rate;
+	return parent_rate / 48 * hss_mult[hss];
+}
+
+static u8 clk_pxa3xx_system_bus_get_parent(struct clk_hw *hw)
+{
+	if (pxa3xx_is_ring_osc_forced())
+		return PXA_BUS_60Mhz;
+	else
+		return PXA_BUS_HSS;
+}
+
+PARENTS(clk_pxa3xx_system_bus) = { "ring_osc_60mhz", "spll_624mhz" };
+MUX_RO_RATE_RO_OPS(clk_pxa3xx_system_bus, "system_bus");
+
+static unsigned long clk_pxa3xx_core_get_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	return parent_rate;
+}
+
+static u8 clk_pxa3xx_core_get_parent(struct clk_hw *hw)
+{
+	unsigned long xclkcfg;
+	unsigned int t;
+
+	if (pxa3xx_is_ring_osc_forced())
+		return PXA_CORE_60Mhz;
+
+	/* Read XCLKCFG register turbo bit */
+	__asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+	t = xclkcfg & 0x1;
+
+	if (t)
+		return PXA_CORE_TURBO;
+	return PXA_CORE_RUN;
+}
+PARENTS(clk_pxa3xx_core) = { "ring_osc_60mhz", "run", "cpll" };
+MUX_RO_RATE_RO_OPS(clk_pxa3xx_core, "core");
+
+static unsigned long clk_pxa3xx_run_get_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	unsigned long acsr = ACSR;
+	unsigned int xn = (acsr & ACCR_XN_MASK) >> 8;
+	unsigned int t, xclkcfg;
+
+	/* Read XCLKCFG register turbo bit */
+	__asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+	t = xclkcfg & 0x1;
+
+	return t ? (parent_rate / xn) * 2 : parent_rate;
+}
+PARENTS(clk_pxa3xx_run) = { "cpll" };
+RATE_RO_OPS(clk_pxa3xx_run, "run");
+
+static unsigned long clk_pxa3xx_cpll_get_rate(struct clk_hw *hw,
+	unsigned long parent_rate)
+{
+	unsigned long acsr = ACSR;
+	unsigned int xn = (acsr & ACCR_XN_MASK) >> 8;
+	unsigned int xl = acsr & ACCR_XL_MASK;
+	unsigned int t, xclkcfg;
+
+	/* Read XCLKCFG register turbo bit */
+	__asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+	t = xclkcfg & 0x1;
+
+	pr_info("RJK: parent_rate=%lu, xl=%u, xn=%u\n", parent_rate, xl, xn);
+	return t ? parent_rate * xl * xn : parent_rate * xl;
+}
+PARENTS(clk_pxa3xx_cpll) = { "osc_13mhz" };
+RATE_RO_OPS(clk_pxa3xx_cpll, "cpll");
+
+static void __init pxa3xx_register_core(void)
+{
+	clk_register_clk_pxa3xx_cpll();
+	clk_register_clk_pxa3xx_run();
+
+	clkdev_pxa_register(CLK_CORE, "core", NULL,
+			    clk_register_clk_pxa3xx_core());
+}
+
+static void __init pxa3xx_register_plls(void)
+{
+	clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
+				CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
+				13 * MHz);
+	clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
+				CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
+				32768);
+	clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL,
+				CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
+				120 * MHz);
+	clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
+	clk_register_fixed_factor(NULL, "spll_624mhz", "osc_13mhz", 0, 48, 1);
+	clk_register_fixed_factor(NULL, "ring_osc_60mhz", "ring_osc_120mhz",
+				  0, 1, 2);
+}
+
+#define DUMMY_CLK(_con_id, _dev_id, _parent) \
+	{ .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
+struct dummy_clk {
+	const char *con_id;
+	const char *dev_id;
+	const char *parent;
+};
+static struct dummy_clk dummy_clks[] __initdata = {
+	DUMMY_CLK(NULL, "pxa93x-gpio", "osc_13mhz"),
+	DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
+	DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
+	DUMMY_CLK(NULL, "pxa3xx-pwri2c.1", "osc_13mhz"),
+};
+
+static void __init pxa3xx_dummy_clocks_init(void)
+{
+	struct clk *clk;
+	struct dummy_clk *d;
+	const char *name;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
+		d = &dummy_clks[i];
+		name = d->dev_id ? d->dev_id : d->con_id;
+		clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
+		clk_register_clkdev(clk, d->con_id, d->dev_id);
+	}
+}
+
+static void __init pxa3xx_base_clocks_init(void)
+{
+	pxa3xx_register_plls();
+	pxa3xx_register_core();
+	clk_register_clk_pxa3xx_system_bus();
+	clk_register_clk_pxa3xx_ac97();
+	clk_register_clk_pxa3xx_smemc();
+	clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0,
+			  (void __iomem *)&OSCC, 11, 0, NULL);
+}
+
+int __init pxa3xx_clocks_init(void)
+{
+	int ret;
+
+	pxa3xx_base_clocks_init();
+	pxa3xx_dummy_clocks_init();
+	ret = clk_pxa_cken_init(pxa3xx_clocks, ARRAY_SIZE(pxa3xx_clocks));
+	if (ret)
+		return ret;
+	if (cpu_is_pxa320())
+		return clk_pxa_cken_init(pxa320_clocks,
+					 ARRAY_SIZE(pxa320_clocks));
+	if (cpu_is_pxa300() || cpu_is_pxa310())
+		return clk_pxa_cken_init(pxa300_310_clocks,
+					 ARRAY_SIZE(pxa300_310_clocks));
+	return clk_pxa_cken_init(pxa93x_clocks, ARRAY_SIZE(pxa93x_clocks));
+}
+
+static void __init pxa3xx_dt_clocks_init(struct device_node *np)
+{
+	pxa3xx_clocks_init();
+	clk_pxa_dt_common_init(np);
+}
+CLK_OF_DECLARE(pxa_clks, "marvell,pxa300-clocks", pxa3xx_dt_clocks_init);

+ 18 - 0
drivers/clk/qcom/Kconfig

@@ -29,6 +29,15 @@ config IPQ_GCC_806X
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  i2c, USB, SD/eMMC, etc.
 
+config IPQ_LCC_806X
+	tristate "IPQ806x LPASS Clock Controller"
+	select IPQ_GCC_806X
+	depends on COMMON_CLK_QCOM
+	help
+	  Support for the LPASS clock controller on ipq806x devices.
+	  Say Y if you want to use audio devices such as i2s, pcm,
+	  S/PDIF, etc.
+
 config MSM_GCC_8660
 	tristate "MSM8660 Global Clock Controller"
 	depends on COMMON_CLK_QCOM
@@ -45,6 +54,15 @@ config MSM_GCC_8960
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  i2c, USB, SD/eMMC, SATA, PCIe, etc.
 
+config MSM_LCC_8960
+	tristate "APQ8064/MSM8960 LPASS Clock Controller"
+	select MSM_GCC_8960
+	depends on COMMON_CLK_QCOM
+	help
+	  Support for the LPASS clock controller on apq8064/msm8960 devices.
+	  Say Y if you want to use audio devices such as i2s, pcm,
+	  SLIMBus, etc.
+
 config MSM_MMCC_8960
 	tristate "MSM8960 Multimedia Clock Controller"
 	select MSM_GCC_8960

+ 4 - 0
drivers/clk/qcom/Makefile

@@ -6,13 +6,17 @@ clk-qcom-y += clk-pll.o
 clk-qcom-y += clk-rcg.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-branch.o
+clk-qcom-y += clk-regmap-divider.o
+clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += reset.o
 
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
+obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
+obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
 obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o

+ 1 - 0
drivers/clk/qcom/clk-pll.c

@@ -141,6 +141,7 @@ struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
 
 static long
 clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
+		       unsigned long min_rate, unsigned long max_rate,
 		       unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_pll *pll = to_clk_pll(hw);

+ 8 - 2
drivers/clk/qcom/clk-rcg.c

@@ -368,6 +368,7 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 
 static long _freq_tbl_determine_rate(struct clk_hw *hw,
 		const struct freq_tbl *f, unsigned long rate,
+		unsigned long min_rate, unsigned long max_rate,
 		unsigned long *p_rate, struct clk_hw **p_hw)
 {
 	unsigned long clk_flags;
@@ -397,22 +398,27 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
 }
 
 static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long min_rate, unsigned long max_rate,
 		unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_rcg *rcg = to_clk_rcg(hw);
 
-	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
+	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
+			max_rate, p_rate, p);
 }
 
 static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long min_rate, unsigned long max_rate,
 		unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
 
-	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
+	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
+			max_rate, p_rate, p);
 }
 
 static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long min_rate, unsigned long max_rate,
 		unsigned long *p_rate, struct clk_hw **p_hw)
 {
 	struct clk_rcg *rcg = to_clk_rcg(hw);

+ 6 - 0
drivers/clk/qcom/clk-rcg2.c

@@ -208,6 +208,7 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
 }
 
 static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long min_rate, unsigned long max_rate,
 		unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -361,6 +362,8 @@ static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
 }
 
 static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long min_rate,
+				 unsigned long max_rate,
 				 unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -412,6 +415,7 @@ const struct clk_ops clk_edp_pixel_ops = {
 EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
 
 static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
+			 unsigned long min_rate, unsigned long max_rate,
 			 unsigned long *p_rate, struct clk_hw **p_hw)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -476,6 +480,8 @@ static const struct frac_entry frac_table_pixel[] = {
 };
 
 static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long min_rate,
+				 unsigned long max_rate,
 				 unsigned long *p_rate, struct clk_hw **p)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

+ 70 - 0
drivers/clk/qcom/clk-regmap-divider.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/export.h>
+
+#include "clk-regmap-divider.h"
+
+static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
+{
+	return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
+}
+
+static long div_round_rate(struct clk_hw *hw, unsigned long rate,
+			   unsigned long *prate)
+{
+	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
+
+	return divider_round_rate(hw, rate, prate, NULL, divider->width,
+				  CLK_DIVIDER_ROUND_CLOSEST);
+}
+
+static int div_set_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long parent_rate)
+{
+	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
+	struct clk_regmap *clkr = &divider->clkr;
+	u32 div;
+
+	div = divider_get_val(rate, parent_rate, NULL, divider->width,
+			      CLK_DIVIDER_ROUND_CLOSEST);
+
+	return regmap_update_bits(clkr->regmap, divider->reg,
+				  (BIT(divider->width) - 1) << divider->shift,
+				  div << divider->shift);
+}
+
+static unsigned long div_recalc_rate(struct clk_hw *hw,
+				     unsigned long parent_rate)
+{
+	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
+	struct clk_regmap *clkr = &divider->clkr;
+	u32 div;
+
+	regmap_read(clkr->regmap, divider->reg, &div);
+	div >>= divider->shift;
+	div &= BIT(divider->width) - 1;
+
+	return divider_recalc_rate(hw, parent_rate, div, NULL,
+				   CLK_DIVIDER_ROUND_CLOSEST);
+}
+
+const struct clk_ops clk_regmap_div_ops = {
+	.round_rate = div_round_rate,
+	.set_rate = div_set_rate,
+	.recalc_rate = div_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_regmap_div_ops);

+ 29 - 0
drivers/clk/qcom/clk-regmap-divider.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#ifndef __QCOM_CLK_REGMAP_DIVIDER_H__
+#define __QCOM_CLK_REGMAP_DIVIDER_H__
+
+#include <linux/clk-provider.h>
+#include "clk-regmap.h"
+
+struct clk_regmap_div {
+	u32			reg;
+	u32			shift;
+	u32			width;
+	struct clk_regmap	clkr;
+};
+
+extern const struct clk_ops clk_regmap_div_ops;
+
+#endif

+ 59 - 0
drivers/clk/qcom/clk-regmap-mux.c

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/export.h>
+
+#include "clk-regmap-mux.h"
+
+static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw)
+{
+	return container_of(to_clk_regmap(hw), struct clk_regmap_mux, clkr);
+}
+
+static u8 mux_get_parent(struct clk_hw *hw)
+{
+	struct clk_regmap_mux *mux = to_clk_regmap_mux(hw);
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+	unsigned int mask = GENMASK(mux->width - 1, 0);
+	unsigned int val;
+
+	regmap_read(clkr->regmap, mux->reg, &val);
+
+	val >>= mux->shift;
+	val &= mask;
+
+	return val;
+}
+
+static int mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_regmap_mux *mux = to_clk_regmap_mux(hw);
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+	unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+	unsigned int val;
+
+	val = index;
+	val <<= mux->shift;
+
+	return regmap_update_bits(clkr->regmap, mux->reg, mask, val);
+}
+
+const struct clk_ops clk_regmap_mux_closest_ops = {
+	.get_parent = mux_get_parent,
+	.set_parent = mux_set_parent,
+	.determine_rate = __clk_mux_determine_rate_closest,
+};
+EXPORT_SYMBOL_GPL(clk_regmap_mux_closest_ops);

+ 29 - 0
drivers/clk/qcom/clk-regmap-mux.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#ifndef __QCOM_CLK_REGMAP_MUX_H__
+#define __QCOM_CLK_REGMAP_MUX_H__
+
+#include <linux/clk-provider.h>
+#include "clk-regmap.h"
+
+struct clk_regmap_mux {
+	u32			reg;
+	u32			shift;
+	u32			width;
+	struct clk_regmap	clkr;
+};
+
+extern const struct clk_ops clk_regmap_mux_closest_ops;
+
+#endif

+ 12 - 0
drivers/clk/qcom/gcc-ipq806x.c

@@ -75,6 +75,17 @@ static struct clk_pll pll3 = {
 	},
 };
 
+static struct clk_regmap pll4_vote = {
+	.enable_reg = 0x34c0,
+	.enable_mask = BIT(4),
+	.hw.init = &(struct clk_init_data){
+		.name = "pll4_vote",
+		.parent_names = (const char *[]){ "pll4" },
+		.num_parents = 1,
+		.ops = &clk_pll_vote_ops,
+	},
+};
+
 static struct clk_pll pll8 = {
 	.l_reg = 0x3144,
 	.m_reg = 0x3148,
@@ -2163,6 +2174,7 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
 	[PLL0] = &pll0.clkr,
 	[PLL0_VOTE] = &pll0_vote,
 	[PLL3] = &pll3.clkr,
+	[PLL4_VOTE] = &pll4_vote,
 	[PLL8] = &pll8.clkr,
 	[PLL8_VOTE] = &pll8_vote,
 	[PLL14] = &pll14.clkr,

+ 473 - 0
drivers/clk/qcom/lcc-ipq806x.c

@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+
+static struct clk_pll pll4 = {
+	.l_reg = 0x4,
+	.m_reg = 0x8,
+	.n_reg = 0xc,
+	.config_reg = 0x14,
+	.mode_reg = 0x0,
+	.status_reg = 0x18,
+	.status_bit = 16,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "pll4",
+		.parent_names = (const char *[]){ "pxo" },
+		.num_parents = 1,
+		.ops = &clk_pll_ops,
+	},
+};
+
+static const struct pll_config pll4_config = {
+	.l = 0xf,
+	.m = 0x91,
+	.n = 0xc7,
+	.vco_val = 0x0,
+	.vco_mask = BIT(17) | BIT(16),
+	.pre_div_val = 0x0,
+	.pre_div_mask = BIT(19),
+	.post_div_val = 0x0,
+	.post_div_mask = BIT(21) | BIT(20),
+	.mn_ena_mask = BIT(22),
+	.main_output_mask = BIT(23),
+};
+
+#define P_PXO	0
+#define P_PLL4	1
+
+static const u8 lcc_pxo_pll4_map[] = {
+	[P_PXO]		= 0,
+	[P_PLL4]	= 2,
+};
+
+static const char *lcc_pxo_pll4[] = {
+	"pxo",
+	"pll4_vote",
+};
+
+static struct freq_tbl clk_tbl_aif_mi2s[] = {
+	{  1024000, P_PLL4, 4,  1,  96 },
+	{  1411200, P_PLL4, 4,  2, 139 },
+	{  1536000, P_PLL4, 4,  1,  64 },
+	{  2048000, P_PLL4, 4,  1,  48 },
+	{  2116800, P_PLL4, 4,  2,  93 },
+	{  2304000, P_PLL4, 4,  2,  85 },
+	{  2822400, P_PLL4, 4,  6, 209 },
+	{  3072000, P_PLL4, 4,  1,  32 },
+	{  3175200, P_PLL4, 4,  1,  31 },
+	{  4096000, P_PLL4, 4,  1,  24 },
+	{  4233600, P_PLL4, 4,  9, 209 },
+	{  4608000, P_PLL4, 4,  3,  64 },
+	{  5644800, P_PLL4, 4, 12, 209 },
+	{  6144000, P_PLL4, 4,  1,  16 },
+	{  6350400, P_PLL4, 4,  2,  31 },
+	{  8192000, P_PLL4, 4,  1,  12 },
+	{  8467200, P_PLL4, 4, 18, 209 },
+	{  9216000, P_PLL4, 4,  3,  32 },
+	{ 11289600, P_PLL4, 4, 24, 209 },
+	{ 12288000, P_PLL4, 4,  1,   8 },
+	{ 12700800, P_PLL4, 4, 27, 209 },
+	{ 13824000, P_PLL4, 4,  9,  64 },
+	{ 16384000, P_PLL4, 4,  1,   6 },
+	{ 16934400, P_PLL4, 4, 41, 238 },
+	{ 18432000, P_PLL4, 4,  3,  16 },
+	{ 22579200, P_PLL4, 2, 24, 209 },
+	{ 24576000, P_PLL4, 4,  1,   4 },
+	{ 27648000, P_PLL4, 4,  9,  32 },
+	{ 33868800, P_PLL4, 4, 41, 119 },
+	{ 36864000, P_PLL4, 4,  3,   8 },
+	{ 45158400, P_PLL4, 1, 24, 209 },
+	{ 49152000, P_PLL4, 4,  1,   2 },
+	{ 50803200, P_PLL4, 1, 27, 209 },
+	{ }
+};
+
+static struct clk_rcg mi2s_osr_src = {
+	.ns_reg = 0x48,
+	.md_reg = 0x4c,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 24,
+		.m_val_shift = 8,
+		.width = 8,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_aif_mi2s,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_osr_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static const char *lcc_mi2s_parents[] = {
+	"mi2s_osr_src",
+};
+
+static struct clk_branch mi2s_osr_clk = {
+	.halt_reg = 0x50,
+	.halt_bit = 1,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(17),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_osr_clk",
+			.parent_names = lcc_mi2s_parents,
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap_div mi2s_div_clk = {
+	.reg = 0x48,
+	.shift = 10,
+	.width = 4,
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_div_clk",
+			.parent_names = lcc_mi2s_parents,
+			.num_parents = 1,
+			.ops = &clk_regmap_div_ops,
+		},
+	},
+};
+
+static struct clk_branch mi2s_bit_div_clk = {
+	.halt_reg = 0x50,
+	.halt_bit = 0,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(15),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_bit_div_clk",
+			.parent_names = (const char *[]){ "mi2s_div_clk" },
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+
+static struct clk_regmap_mux mi2s_bit_clk = {
+	.reg = 0x48,
+	.shift = 14,
+	.width = 1,
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_bit_clk",
+			.parent_names = (const char *[]){
+				"mi2s_bit_div_clk",
+				"mi2s_codec_clk",
+			},
+			.num_parents = 2,
+			.ops = &clk_regmap_mux_closest_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct freq_tbl clk_tbl_pcm[] = {
+	{   64000, P_PLL4, 4, 1, 1536 },
+	{  128000, P_PLL4, 4, 1,  768 },
+	{  256000, P_PLL4, 4, 1,  384 },
+	{  512000, P_PLL4, 4, 1,  192 },
+	{ 1024000, P_PLL4, 4, 1,   96 },
+	{ 2048000, P_PLL4, 4, 1,   48 },
+	{ },
+};
+
+static struct clk_rcg pcm_src = {
+	.ns_reg = 0x54,
+	.md_reg = 0x58,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 16,
+		.m_val_shift = 16,
+		.width = 16,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_pcm,
+	.clkr = {
+		.enable_reg = 0x54,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static struct clk_branch pcm_clk_out = {
+	.halt_reg = 0x5c,
+	.halt_bit = 0,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x54,
+		.enable_mask = BIT(11),
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_clk_out",
+			.parent_names = (const char *[]){ "pcm_src" },
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap_mux pcm_clk = {
+	.reg = 0x54,
+	.shift = 10,
+	.width = 1,
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_clk",
+			.parent_names = (const char *[]){
+				"pcm_clk_out",
+				"pcm_codec_clk",
+			},
+			.num_parents = 2,
+			.ops = &clk_regmap_mux_closest_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct freq_tbl clk_tbl_aif_osr[] = {
+	{  22050, P_PLL4, 1, 147, 20480 },
+	{  32000, P_PLL4, 1,   1,    96 },
+	{  44100, P_PLL4, 1, 147, 10240 },
+	{  48000, P_PLL4, 1,   1,    64 },
+	{  88200, P_PLL4, 1, 147,  5120 },
+	{  96000, P_PLL4, 1,   1,    32 },
+	{ 176400, P_PLL4, 1, 147,  2560 },
+	{ 192000, P_PLL4, 1,   1,    16 },
+	{ },
+};
+
+static struct clk_rcg spdif_src = {
+	.ns_reg = 0xcc,
+	.md_reg = 0xd0,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 16,
+		.m_val_shift = 16,
+		.width = 8,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_aif_osr,
+	.clkr = {
+		.enable_reg = 0xcc,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "spdif_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static const char *lcc_spdif_parents[] = {
+	"spdif_src",
+};
+
+static struct clk_branch spdif_clk = {
+	.halt_reg = 0xd4,
+	.halt_bit = 1,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0xcc,
+		.enable_mask = BIT(12),
+		.hw.init = &(struct clk_init_data){
+			.name = "spdif_clk",
+			.parent_names = lcc_spdif_parents,
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct freq_tbl clk_tbl_ahbix[] = {
+	{ 131072, P_PLL4, 1, 1, 3 },
+	{ },
+};
+
+static struct clk_rcg ahbix_clk = {
+	.ns_reg = 0x38,
+	.md_reg = 0x3c,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 24,
+		.m_val_shift = 8,
+		.width = 8,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_ahbix,
+	.clkr = {
+		.enable_reg = 0x38,
+		.enable_mask = BIT(10), /* toggle the gfmux to select mn/pxo */
+		.hw.init = &(struct clk_init_data){
+			.name = "ahbix",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static struct clk_regmap *lcc_ipq806x_clks[] = {
+	[PLL4] = &pll4.clkr,
+	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
+	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
+	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
+	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
+	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
+	[PCM_SRC] = &pcm_src.clkr,
+	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
+	[PCM_CLK] = &pcm_clk.clkr,
+	[SPDIF_SRC] = &spdif_src.clkr,
+	[SPDIF_CLK] = &spdif_clk.clkr,
+	[AHBIX_CLK] = &ahbix_clk.clkr,
+};
+
+static const struct regmap_config lcc_ipq806x_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= 0xfc,
+	.fast_io	= true,
+};
+
+static const struct qcom_cc_desc lcc_ipq806x_desc = {
+	.config = &lcc_ipq806x_regmap_config,
+	.clks = lcc_ipq806x_clks,
+	.num_clks = ARRAY_SIZE(lcc_ipq806x_clks),
+};
+
+static const struct of_device_id lcc_ipq806x_match_table[] = {
+	{ .compatible = "qcom,lcc-ipq8064" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lcc_ipq806x_match_table);
+
+static int lcc_ipq806x_probe(struct platform_device *pdev)
+{
+	u32 val;
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &lcc_ipq806x_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	/* Configure the rate of PLL4 if the bootloader hasn't already */
+	val = regmap_read(regmap, 0x0, &val);
+	if (!val)
+		clk_pll_configure_sr(&pll4, regmap, &pll4_config, true);
+	/* Enable PLL4 source on the LPASS Primary PLL Mux */
+	regmap_write(regmap, 0xc4, 0x1);
+
+	return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
+}
+
+static int lcc_ipq806x_remove(struct platform_device *pdev)
+{
+	qcom_cc_remove(pdev);
+	return 0;
+}
+
+static struct platform_driver lcc_ipq806x_driver = {
+	.probe		= lcc_ipq806x_probe,
+	.remove		= lcc_ipq806x_remove,
+	.driver		= {
+		.name	= "lcc-ipq806x",
+		.owner	= THIS_MODULE,
+		.of_match_table = lcc_ipq806x_match_table,
+	},
+};
+module_platform_driver(lcc_ipq806x_driver);
+
+MODULE_DESCRIPTION("QCOM LCC IPQ806x Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:lcc-ipq806x");

+ 585 - 0
drivers/clk/qcom/lcc-msm8960.c

@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,lcc-msm8960.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+
+static struct clk_pll pll4 = {
+	.l_reg = 0x4,
+	.m_reg = 0x8,
+	.n_reg = 0xc,
+	.config_reg = 0x14,
+	.mode_reg = 0x0,
+	.status_reg = 0x18,
+	.status_bit = 16,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "pll4",
+		.parent_names = (const char *[]){ "pxo" },
+		.num_parents = 1,
+		.ops = &clk_pll_ops,
+	},
+};
+
+#define P_PXO	0
+#define P_PLL4	1
+
+static const u8 lcc_pxo_pll4_map[] = {
+	[P_PXO]		= 0,
+	[P_PLL4]	= 2,
+};
+
+static const char *lcc_pxo_pll4[] = {
+	"pxo",
+	"pll4_vote",
+};
+
+static struct freq_tbl clk_tbl_aif_osr_492[] = {
+	{   512000, P_PLL4, 4, 1, 240 },
+	{   768000, P_PLL4, 4, 1, 160 },
+	{  1024000, P_PLL4, 4, 1, 120 },
+	{  1536000, P_PLL4, 4, 1,  80 },
+	{  2048000, P_PLL4, 4, 1,  60 },
+	{  3072000, P_PLL4, 4, 1,  40 },
+	{  4096000, P_PLL4, 4, 1,  30 },
+	{  6144000, P_PLL4, 4, 1,  20 },
+	{  8192000, P_PLL4, 4, 1,  15 },
+	{ 12288000, P_PLL4, 4, 1,  10 },
+	{ 24576000, P_PLL4, 4, 1,   5 },
+	{ 27000000, P_PXO,  1, 0,   0 },
+	{ }
+};
+
+static struct freq_tbl clk_tbl_aif_osr_393[] = {
+	{   512000, P_PLL4, 4, 1, 192 },
+	{   768000, P_PLL4, 4, 1, 128 },
+	{  1024000, P_PLL4, 4, 1,  96 },
+	{  1536000, P_PLL4, 4, 1,  64 },
+	{  2048000, P_PLL4, 4, 1,  48 },
+	{  3072000, P_PLL4, 4, 1,  32 },
+	{  4096000, P_PLL4, 4, 1,  24 },
+	{  6144000, P_PLL4, 4, 1,  16 },
+	{  8192000, P_PLL4, 4, 1,  12 },
+	{ 12288000, P_PLL4, 4, 1,   8 },
+	{ 24576000, P_PLL4, 4, 1,   4 },
+	{ 27000000, P_PXO,  1, 0,   0 },
+	{ }
+};
+
+static struct clk_rcg mi2s_osr_src = {
+	.ns_reg = 0x48,
+	.md_reg = 0x4c,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 24,
+		.m_val_shift = 8,
+		.width = 8,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_aif_osr_393,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_osr_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static const char *lcc_mi2s_parents[] = {
+	"mi2s_osr_src",
+};
+
+static struct clk_branch mi2s_osr_clk = {
+	.halt_reg = 0x50,
+	.halt_bit = 1,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(17),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_osr_clk",
+			.parent_names = lcc_mi2s_parents,
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap_div mi2s_div_clk = {
+	.reg = 0x48,
+	.shift = 10,
+	.width = 4,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(15),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_div_clk",
+			.parent_names = lcc_mi2s_parents,
+			.num_parents = 1,
+			.ops = &clk_regmap_div_ops,
+		},
+	},
+};
+
+static struct clk_branch mi2s_bit_div_clk = {
+	.halt_reg = 0x50,
+	.halt_bit = 0,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x48,
+		.enable_mask = BIT(15),
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_bit_div_clk",
+			.parent_names = (const char *[]){ "mi2s_div_clk" },
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap_mux mi2s_bit_clk = {
+	.reg = 0x48,
+	.shift = 14,
+	.width = 1,
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "mi2s_bit_clk",
+			.parent_names = (const char *[]){
+				"mi2s_bit_div_clk",
+				"mi2s_codec_clk",
+			},
+			.num_parents = 2,
+			.ops = &clk_regmap_mux_closest_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)			\
+static struct clk_rcg prefix##_osr_src = {			\
+	.ns_reg = _ns,						\
+	.md_reg = _md,						\
+	.mn = {							\
+		.mnctr_en_bit = 8,				\
+		.mnctr_reset_bit = 7,				\
+		.mnctr_mode_shift = 5,				\
+		.n_val_shift = 24,				\
+		.m_val_shift = 8,				\
+		.width = 8,					\
+	},							\
+	.p = {							\
+		.pre_div_shift = 3,				\
+		.pre_div_width = 2,				\
+	},							\
+	.s = {							\
+		.src_sel_shift = 0,				\
+		.parent_map = lcc_pxo_pll4_map,			\
+	},							\
+	.freq_tbl = clk_tbl_aif_osr_393,			\
+	.clkr = {						\
+		.enable_reg = _ns,				\
+		.enable_mask = BIT(9),				\
+		.hw.init = &(struct clk_init_data){		\
+			.name = #prefix "_osr_src",		\
+			.parent_names = lcc_pxo_pll4,		\
+			.num_parents = 2,			\
+			.ops = &clk_rcg_ops,			\
+			.flags = CLK_SET_RATE_GATE,		\
+		},						\
+	},							\
+};								\
+								\
+static const char *lcc_##prefix##_parents[] = {			\
+	#prefix "_osr_src",					\
+};								\
+								\
+static struct clk_branch prefix##_osr_clk = {			\
+	.halt_reg = hr,						\
+	.halt_bit = 1,						\
+	.halt_check = BRANCH_HALT_ENABLE,			\
+	.clkr = {						\
+		.enable_reg = _ns,				\
+		.enable_mask = BIT(21),				\
+		.hw.init = &(struct clk_init_data){		\
+			.name = #prefix "_osr_clk",		\
+			.parent_names = lcc_##prefix##_parents,	\
+			.num_parents = 1,			\
+			.ops = &clk_branch_ops,			\
+			.flags = CLK_SET_RATE_PARENT,		\
+		},						\
+	},							\
+};								\
+								\
+static struct clk_regmap_div prefix##_div_clk = {		\
+	.reg = _ns,						\
+	.shift = 10,						\
+	.width = 8,						\
+	.clkr = {						\
+		.hw.init = &(struct clk_init_data){		\
+			.name = #prefix "_div_clk",		\
+			.parent_names = lcc_##prefix##_parents,	\
+			.num_parents = 1,			\
+			.ops = &clk_regmap_div_ops,		\
+		},						\
+	},							\
+};								\
+								\
+static struct clk_branch prefix##_bit_div_clk = {		\
+	.halt_reg = hr,						\
+	.halt_bit = 0,						\
+	.halt_check = BRANCH_HALT_ENABLE,			\
+	.clkr = {						\
+		.enable_reg = _ns,				\
+		.enable_mask = BIT(19),				\
+		.hw.init = &(struct clk_init_data){		\
+			.name = #prefix "_bit_div_clk",		\
+			.parent_names = (const char *[]){	\
+				#prefix "_div_clk"		\
+			}, 					\
+			.num_parents = 1,			\
+			.ops = &clk_branch_ops,			\
+			.flags = CLK_SET_RATE_PARENT,		\
+		},						\
+	},							\
+};								\
+								\
+static struct clk_regmap_mux prefix##_bit_clk = {		\
+	.reg = _ns,						\
+	.shift = 18,						\
+	.width = 1,						\
+	.clkr = {						\
+		.hw.init = &(struct clk_init_data){		\
+			.name = #prefix "_bit_clk",		\
+			.parent_names = (const char *[]){	\
+				#prefix "_bit_div_clk",		\
+				#prefix "_codec_clk",		\
+			},					\
+			.num_parents = 2,			\
+			.ops = &clk_regmap_mux_closest_ops,	\
+			.flags = CLK_SET_RATE_PARENT,		\
+		},						\
+	},							\
+}
+
+CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
+CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
+CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
+CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
+
+static struct freq_tbl clk_tbl_pcm_492[] = {
+	{   256000, P_PLL4, 4, 1, 480 },
+	{   512000, P_PLL4, 4, 1, 240 },
+	{   768000, P_PLL4, 4, 1, 160 },
+	{  1024000, P_PLL4, 4, 1, 120 },
+	{  1536000, P_PLL4, 4, 1,  80 },
+	{  2048000, P_PLL4, 4, 1,  60 },
+	{  3072000, P_PLL4, 4, 1,  40 },
+	{  4096000, P_PLL4, 4, 1,  30 },
+	{  6144000, P_PLL4, 4, 1,  20 },
+	{  8192000, P_PLL4, 4, 1,  15 },
+	{ 12288000, P_PLL4, 4, 1,  10 },
+	{ 24576000, P_PLL4, 4, 1,   5 },
+	{ 27000000, P_PXO,  1, 0,   0 },
+	{ }
+};
+
+static struct freq_tbl clk_tbl_pcm_393[] = {
+	{   256000, P_PLL4, 4, 1, 384 },
+	{   512000, P_PLL4, 4, 1, 192 },
+	{   768000, P_PLL4, 4, 1, 128 },
+	{  1024000, P_PLL4, 4, 1,  96 },
+	{  1536000, P_PLL4, 4, 1,  64 },
+	{  2048000, P_PLL4, 4, 1,  48 },
+	{  3072000, P_PLL4, 4, 1,  32 },
+	{  4096000, P_PLL4, 4, 1,  24 },
+	{  6144000, P_PLL4, 4, 1,  16 },
+	{  8192000, P_PLL4, 4, 1,  12 },
+	{ 12288000, P_PLL4, 4, 1,   8 },
+	{ 24576000, P_PLL4, 4, 1,   4 },
+	{ 27000000, P_PXO,  1, 0,   0 },
+	{ }
+};
+
+static struct clk_rcg pcm_src = {
+	.ns_reg = 0x54,
+	.md_reg = 0x58,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 16,
+		.m_val_shift = 16,
+		.width = 16,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_pcm_393,
+	.clkr = {
+		.enable_reg = 0x54,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static struct clk_branch pcm_clk_out = {
+	.halt_reg = 0x5c,
+	.halt_bit = 0,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0x54,
+		.enable_mask = BIT(11),
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_clk_out",
+			.parent_names = (const char *[]){ "pcm_src" },
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap_mux pcm_clk = {
+	.reg = 0x54,
+	.shift = 10,
+	.width = 1,
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "pcm_clk",
+			.parent_names = (const char *[]){
+				"pcm_clk_out",
+				"pcm_codec_clk",
+			},
+			.num_parents = 2,
+			.ops = &clk_regmap_mux_closest_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_rcg slimbus_src = {
+	.ns_reg = 0xcc,
+	.md_reg = 0xd0,
+	.mn = {
+		.mnctr_en_bit = 8,
+		.mnctr_reset_bit = 7,
+		.mnctr_mode_shift = 5,
+		.n_val_shift = 16,
+		.m_val_shift = 16,
+		.width = 8,
+	},
+	.p = {
+		.pre_div_shift = 3,
+		.pre_div_width = 2,
+	},
+	.s = {
+		.src_sel_shift = 0,
+		.parent_map = lcc_pxo_pll4_map,
+	},
+	.freq_tbl = clk_tbl_aif_osr_393,
+	.clkr = {
+		.enable_reg = 0xcc,
+		.enable_mask = BIT(9),
+		.hw.init = &(struct clk_init_data){
+			.name = "slimbus_src",
+			.parent_names = lcc_pxo_pll4,
+			.num_parents = 2,
+			.ops = &clk_rcg_ops,
+			.flags = CLK_SET_RATE_GATE,
+		},
+	},
+};
+
+static const char *lcc_slimbus_parents[] = {
+	"slimbus_src",
+};
+
+static struct clk_branch audio_slimbus_clk = {
+	.halt_reg = 0xd4,
+	.halt_bit = 0,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0xcc,
+		.enable_mask = BIT(10),
+		.hw.init = &(struct clk_init_data){
+			.name = "audio_slimbus_clk",
+			.parent_names = lcc_slimbus_parents,
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_branch sps_slimbus_clk = {
+	.halt_reg = 0xd4,
+	.halt_bit = 1,
+	.halt_check = BRANCH_HALT_ENABLE,
+	.clkr = {
+		.enable_reg = 0xcc,
+		.enable_mask = BIT(12),
+		.hw.init = &(struct clk_init_data){
+			.name = "sps_slimbus_clk",
+			.parent_names = lcc_slimbus_parents,
+			.num_parents = 1,
+			.ops = &clk_branch_ops,
+			.flags = CLK_SET_RATE_PARENT,
+		},
+	},
+};
+
+static struct clk_regmap *lcc_msm8960_clks[] = {
+	[PLL4] = &pll4.clkr,
+	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
+	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
+	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
+	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
+	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
+	[PCM_SRC] = &pcm_src.clkr,
+	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
+	[PCM_CLK] = &pcm_clk.clkr,
+	[SLIMBUS_SRC] = &slimbus_src.clkr,
+	[AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
+	[SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
+	[CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
+	[CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
+	[CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
+	[CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
+	[CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
+	[SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
+	[SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
+	[SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
+	[SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
+	[SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
+	[CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
+	[CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
+	[CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
+	[CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
+	[CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
+	[SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
+	[SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
+	[SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
+	[SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
+	[SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
+};
+
+static const struct regmap_config lcc_msm8960_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= 0xfc,
+	.fast_io	= true,
+};
+
+static const struct qcom_cc_desc lcc_msm8960_desc = {
+	.config = &lcc_msm8960_regmap_config,
+	.clks = lcc_msm8960_clks,
+	.num_clks = ARRAY_SIZE(lcc_msm8960_clks),
+};
+
+static const struct of_device_id lcc_msm8960_match_table[] = {
+	{ .compatible = "qcom,lcc-msm8960" },
+	{ .compatible = "qcom,lcc-apq8064" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lcc_msm8960_match_table);
+
+static int lcc_msm8960_probe(struct platform_device *pdev)
+{
+	u32 val;
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &lcc_msm8960_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	/* Use the correct frequency plan depending on speed of PLL4 */
+	val = regmap_read(regmap, 0x4, &val);
+	if (val == 0x12) {
+		slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
+		mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+		codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+		spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+		codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+		spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+		pcm_src.freq_tbl = clk_tbl_pcm_492;
+	}
+	/* Enable PLL4 source on the LPASS Primary PLL Mux */
+	regmap_write(regmap, 0xc4, 0x1);
+
+	return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap);
+}
+
+static int lcc_msm8960_remove(struct platform_device *pdev)
+{
+	qcom_cc_remove(pdev);
+	return 0;
+}
+
+static struct platform_driver lcc_msm8960_driver = {
+	.probe		= lcc_msm8960_probe,
+	.remove		= lcc_msm8960_remove,
+	.driver		= {
+		.name	= "lcc-msm8960",
+		.owner	= THIS_MODULE,
+		.of_match_table = lcc_msm8960_match_table,
+	},
+};
+module_platform_driver(lcc_msm8960_driver);
+
+MODULE_DESCRIPTION("QCOM LCC MSM8960 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:lcc-msm8960");

+ 35 - 13
drivers/clk/rockchip/clk-rk3288.c

@@ -535,44 +535,44 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
 			RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 8, GFLAGS),
-	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
+	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(17), 0,
 			RK3288_CLKGATE_CON(1), 9, GFLAGS),
-	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, 0,
+	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
 	MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 10, GFLAGS),
-	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", 0,
+	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(18), 0,
 			RK3288_CLKGATE_CON(1), 11, GFLAGS),
-	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, 0,
+	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", 0,
+	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(19), 0,
 			RK3288_CLKGATE_CON(1), 13, GFLAGS),
-	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, 0,
+	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 14, GFLAGS),
-	COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", 0,
+	COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(20), 0,
 			RK3288_CLKGATE_CON(1), 15, GFLAGS),
-	MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, 0,
+	MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(2), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", 0,
+	COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(7), 0,
 			RK3288_CLKGATE_CON(2), 13, GFLAGS),
-	MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0,
+	MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
 
 	COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
@@ -598,7 +598,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	GATE(0, "jtag", "ext_jtag", 0,
 			RK3288_CLKGATE_CON(4), 14, GFLAGS),
 
-	COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
+	COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
 			RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
 			RK3288_CLKGATE_CON(5), 14, GFLAGS),
 	COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
@@ -704,8 +704,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 
 	GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS),
 	GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
-	GATE(0, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
-	GATE(0, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
 	GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
 
 	/* sclk_gpu gates */
@@ -805,6 +805,20 @@ static int rk3288_clk_suspend(void)
 		rk3288_saved_cru_regs[i] =
 				readl_relaxed(rk3288_cru_base + reg_id);
 	}
+
+	/*
+	 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+	 * avoid crashes on resume. The Mask ROM on the system will
+	 * put APLL, CPLL, and GPLL into slow mode at resume time
+	 * anyway (which is why we restore them), but we might not
+	 * even make it to the Mask ROM if this isn't done at suspend
+	 * time.
+	 *
+	 * NOTE: only APLL truly matters here, but we'll do them all.
+	 */
+
+	writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON);
+
 	return 0;
 }
 
@@ -866,6 +880,14 @@ static void __init rk3288_clk_init(struct device_node *np)
 		pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
 			__func__, PTR_ERR(clk));
 
+	/* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
+	clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock pclk_wdt: %ld\n",
+			__func__, PTR_ERR(clk));
+	else
+		rockchip_clk_add_lookup(clk, PCLK_WDT);
+
 	rockchip_clk_register_plls(rk3288_pll_clks,
 				   ARRAY_SIZE(rk3288_pll_clks),
 				   RK3288_GRF_SOC_STATUS1);

+ 22 - 10
drivers/clk/samsung/clk-exynos-audss.c

@@ -82,6 +82,26 @@ static const struct of_device_id exynos_audss_clk_of_match[] = {
 	{},
 };
 
+static void exynos_audss_clk_teardown(void)
+{
+	int i;
+
+	for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) {
+		if (!IS_ERR(clk_table[i]))
+			clk_unregister_mux(clk_table[i]);
+	}
+
+	for (; i < EXYNOS_SRP_CLK; i++) {
+		if (!IS_ERR(clk_table[i]))
+			clk_unregister_divider(clk_table[i]);
+	}
+
+	for (; i < clk_data.clk_num; i++) {
+		if (!IS_ERR(clk_table[i]))
+			clk_unregister_gate(clk_table[i]);
+	}
+}
+
 /* register exynos_audss clocks */
 static int exynos_audss_clk_probe(struct platform_device *pdev)
 {
@@ -219,10 +239,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
 	return 0;
 
 unregister:
-	for (i = 0; i < clk_data.clk_num; i++) {
-		if (!IS_ERR(clk_table[i]))
-			clk_unregister(clk_table[i]);
-	}
+	exynos_audss_clk_teardown();
 
 	if (!IS_ERR(epll))
 		clk_disable_unprepare(epll);
@@ -232,18 +249,13 @@ unregister:
 
 static int exynos_audss_clk_remove(struct platform_device *pdev)
 {
-	int i;
-
 #ifdef CONFIG_PM_SLEEP
 	unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
 #endif
 
 	of_clk_del_provider(pdev->dev.of_node);
 
-	for (i = 0; i < clk_data.clk_num; i++) {
-		if (!IS_ERR(clk_table[i]))
-			clk_unregister(clk_table[i]);
-	}
+	exynos_audss_clk_teardown();
 
 	if (!IS_ERR(epll))
 		clk_disable_unprepare(epll);

+ 47 - 170
drivers/clk/samsung/clk-exynos3250.c

@@ -104,27 +104,6 @@
 #define PWR_CTRL1_USE_CORE1_WFI			(1 << 1)
 #define PWR_CTRL1_USE_CORE0_WFI			(1 << 0)
 
-/* list of PLLs to be registered */
-enum exynos3250_plls {
-	apll, mpll, vpll, upll,
-	nr_plls
-};
-
-/* list of PLLs in DMC block to be registered */
-enum exynos3250_dmc_plls {
-	bpll, epll,
-	nr_dmc_plls
-};
-
-static void __iomem *reg_base;
-static void __iomem *dmc_reg_base;
-
-/*
- * Support for CMU save/restore across system suspends
- */
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos3250_clk_regs;
-
 static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
 	SRC_LEFTBUS,
 	DIV_LEFTBUS,
@@ -195,43 +174,6 @@ static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
 	PWR_CTRL2,
 };
 
-static int exynos3250_clk_suspend(void)
-{
-	samsung_clk_save(reg_base, exynos3250_clk_regs,
-				ARRAY_SIZE(exynos3250_cmu_clk_regs));
-	return 0;
-}
-
-static void exynos3250_clk_resume(void)
-{
-	samsung_clk_restore(reg_base, exynos3250_clk_regs,
-				ARRAY_SIZE(exynos3250_cmu_clk_regs));
-}
-
-static struct syscore_ops exynos3250_clk_syscore_ops = {
-	.suspend = exynos3250_clk_suspend,
-	.resume = exynos3250_clk_resume,
-};
-
-static void exynos3250_clk_sleep_init(void)
-{
-	exynos3250_clk_regs =
-		samsung_clk_alloc_reg_dump(exynos3250_cmu_clk_regs,
-					   ARRAY_SIZE(exynos3250_cmu_clk_regs));
-	if (!exynos3250_clk_regs) {
-		pr_warn("%s: Failed to allocate sleep save data\n", __func__);
-		goto err;
-	}
-
-	register_syscore_ops(&exynos3250_clk_syscore_ops);
-	return;
-err:
-	kfree(exynos3250_clk_regs);
-}
-#else
-static inline void exynos3250_clk_sleep_init(void) { }
-#endif
-
 /* list of all parent clock list */
 PNAME(mout_vpllsrc_p)		= { "fin_pll", };
 
@@ -782,18 +724,18 @@ static struct samsung_pll_rate_table exynos3250_vpll_rates[] = {
 	{ /* sentinel */ }
 };
 
-static struct samsung_pll_clock exynos3250_plls[nr_plls] __initdata = {
-	[apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
-			APLL_LOCK, APLL_CON0, NULL),
-	[mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
-			MPLL_LOCK, MPLL_CON0, NULL),
-	[vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "fin_pll",
-			VPLL_LOCK, VPLL_CON0, NULL),
-	[upll] = PLL(pll_35xx, CLK_FOUT_UPLL, "fout_upll", "fin_pll",
-			UPLL_LOCK, UPLL_CON0, NULL),
+static struct samsung_pll_clock exynos3250_plls[] __initdata = {
+	PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
+		APLL_LOCK, APLL_CON0, exynos3250_pll_rates),
+	PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
+			MPLL_LOCK, MPLL_CON0, exynos3250_pll_rates),
+	PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "fin_pll",
+			VPLL_LOCK, VPLL_CON0, exynos3250_vpll_rates),
+	PLL(pll_35xx, CLK_FOUT_UPLL, "fout_upll", "fin_pll",
+			UPLL_LOCK, UPLL_CON0, exynos3250_pll_rates),
 };
 
-static void __init exynos3_core_down_clock(void)
+static void __init exynos3_core_down_clock(void __iomem *reg_base)
 {
 	unsigned int tmp;
 
@@ -814,38 +756,31 @@ static void __init exynos3_core_down_clock(void)
 	__raw_writel(0x0, reg_base + PWR_CTRL2);
 }
 
+static struct samsung_cmu_info cmu_info __initdata = {
+	.pll_clks		= exynos3250_plls,
+	.nr_pll_clks		= ARRAY_SIZE(exynos3250_plls),
+	.mux_clks		= mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mux_clks),
+	.div_clks		= div_clks,
+	.nr_div_clks		= ARRAY_SIZE(div_clks),
+	.gate_clks		= gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(gate_clks),
+	.fixed_factor_clks	= fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(fixed_factor_clks),
+	.nr_clk_ids		= CLK_NR_CLKS,
+	.clk_regs		= exynos3250_cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(exynos3250_cmu_clk_regs),
+};
+
 static void __init exynos3250_cmu_init(struct device_node *np)
 {
 	struct samsung_clk_provider *ctx;
 
-	reg_base = of_iomap(np, 0);
-	if (!reg_base)
-		panic("%s: failed to map registers\n", __func__);
-
-	ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
+	ctx = samsung_cmu_register_one(np, &cmu_info);
 	if (!ctx)
-		panic("%s: unable to allocate context.\n", __func__);
-
-	samsung_clk_register_fixed_factor(ctx, fixed_factor_clks,
-					  ARRAY_SIZE(fixed_factor_clks));
-
-	exynos3250_plls[apll].rate_table = exynos3250_pll_rates;
-	exynos3250_plls[mpll].rate_table = exynos3250_pll_rates;
-	exynos3250_plls[vpll].rate_table = exynos3250_vpll_rates;
-	exynos3250_plls[upll].rate_table = exynos3250_pll_rates;
-
-	samsung_clk_register_pll(ctx, exynos3250_plls,
-					ARRAY_SIZE(exynos3250_plls), reg_base);
-
-	samsung_clk_register_mux(ctx, mux_clks, ARRAY_SIZE(mux_clks));
-	samsung_clk_register_div(ctx, div_clks, ARRAY_SIZE(div_clks));
-	samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks));
-
-	exynos3_core_down_clock();
+		return;
 
-	exynos3250_clk_sleep_init();
-
-	samsung_clk_of_add_provider(np, ctx);
+	exynos3_core_down_clock(ctx->reg_base);
 }
 CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
 
@@ -872,12 +807,6 @@ CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
 #define EPLL_CON2		0x111c
 #define SRC_EPLL		0x1120
 
-/*
- * Support for CMU save/restore across system suspends
- */
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos3250_dmc_clk_regs;
-
 static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = {
 	BPLL_LOCK,
 	BPLL_CON0,
@@ -899,43 +828,6 @@ static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = {
 	SRC_EPLL,
 };
 
-static int exynos3250_dmc_clk_suspend(void)
-{
-	samsung_clk_save(dmc_reg_base, exynos3250_dmc_clk_regs,
-				ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs));
-	return 0;
-}
-
-static void exynos3250_dmc_clk_resume(void)
-{
-	samsung_clk_restore(dmc_reg_base, exynos3250_dmc_clk_regs,
-				ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs));
-}
-
-static struct syscore_ops exynos3250_dmc_clk_syscore_ops = {
-	.suspend = exynos3250_dmc_clk_suspend,
-	.resume = exynos3250_dmc_clk_resume,
-};
-
-static void exynos3250_dmc_clk_sleep_init(void)
-{
-	exynos3250_dmc_clk_regs =
-		samsung_clk_alloc_reg_dump(exynos3250_cmu_dmc_clk_regs,
-				   ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs));
-	if (!exynos3250_dmc_clk_regs) {
-		pr_warn("%s: Failed to allocate sleep save data\n", __func__);
-		goto err;
-	}
-
-	register_syscore_ops(&exynos3250_dmc_clk_syscore_ops);
-	return;
-err:
-	kfree(exynos3250_dmc_clk_regs);
-}
-#else
-static inline void exynos3250_dmc_clk_sleep_init(void) { }
-#endif
-
 PNAME(mout_epll_p)	= { "fin_pll", "fout_epll", };
 PNAME(mout_bpll_p)	= { "fin_pll", "fout_bpll", };
 PNAME(mout_mpll_mif_p)	= { "fin_pll", "sclk_mpll_mif", };
@@ -977,43 +869,28 @@ static struct samsung_div_clock dmc_div_clks[] __initdata = {
 	DIV(CLK_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
 };
 
-static struct samsung_pll_clock exynos3250_dmc_plls[nr_dmc_plls] __initdata = {
-	[bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll",
-			BPLL_LOCK, BPLL_CON0, NULL),
-	[epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
-			EPLL_LOCK, EPLL_CON0, NULL),
+static struct samsung_pll_clock exynos3250_dmc_plls[] __initdata = {
+	PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll",
+		BPLL_LOCK, BPLL_CON0, exynos3250_pll_rates),
+	PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
+		EPLL_LOCK, EPLL_CON0, exynos3250_epll_rates),
+};
+
+static struct samsung_cmu_info dmc_cmu_info __initdata = {
+	.pll_clks		= exynos3250_dmc_plls,
+	.nr_pll_clks		= ARRAY_SIZE(exynos3250_dmc_plls),
+	.mux_clks		= dmc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(dmc_mux_clks),
+	.div_clks		= dmc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(dmc_div_clks),
+	.nr_clk_ids		= NR_CLKS_DMC,
+	.clk_regs		= exynos3250_cmu_dmc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(exynos3250_cmu_dmc_clk_regs),
 };
 
 static void __init exynos3250_cmu_dmc_init(struct device_node *np)
 {
-	struct samsung_clk_provider *ctx;
-
-	dmc_reg_base = of_iomap(np, 0);
-	if (!dmc_reg_base)
-		panic("%s: failed to map registers\n", __func__);
-
-	ctx = samsung_clk_init(np, dmc_reg_base, NR_CLKS_DMC);
-	if (!ctx)
-		panic("%s: unable to allocate context.\n", __func__);
-
-	exynos3250_dmc_plls[bpll].rate_table = exynos3250_pll_rates;
-	exynos3250_dmc_plls[epll].rate_table = exynos3250_epll_rates;
-
-	pr_err("CLK registering epll bpll: %d, %d, %d, %d\n",
-			exynos3250_dmc_plls[bpll].rate_table[0].rate,
-			exynos3250_dmc_plls[bpll].rate_table[0].mdiv,
-			exynos3250_dmc_plls[bpll].rate_table[0].pdiv,
-			exynos3250_dmc_plls[bpll].rate_table[0].sdiv
-	      );
-	samsung_clk_register_pll(ctx, exynos3250_dmc_plls,
-				ARRAY_SIZE(exynos3250_dmc_plls), dmc_reg_base);
-
-	samsung_clk_register_mux(ctx, dmc_mux_clks, ARRAY_SIZE(dmc_mux_clks));
-	samsung_clk_register_div(ctx, dmc_div_clks, ARRAY_SIZE(dmc_div_clks));
-
-	exynos3250_dmc_clk_sleep_init();
-
-	samsung_clk_of_add_provider(np, ctx);
+	samsung_cmu_register_one(np, &dmc_cmu_info);
 }
 CLK_OF_DECLARE(exynos3250_cmu_dmc, "samsung,exynos3250-cmu-dmc",
 		exynos3250_cmu_dmc_init);

+ 5 - 5
drivers/clk/samsung/clk-exynos4.c

@@ -703,12 +703,12 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
 
 /* list of divider clocks supported in all exynos4 soc's */
 static struct samsung_div_clock exynos4_div_clks[] __initdata = {
-	DIV(0, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
+	DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
 	DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
 	DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
 			CLKOUT_CMU_LEFTBUS, 8, 6),
 
-	DIV(0, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
+	DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
 	DIV(0, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
 	DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
 			CLKOUT_CMU_RIGHTBUS, 8, 6),
@@ -781,10 +781,10 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
 			CLK_SET_RATE_PARENT, 0),
 	DIV(0, "div_clkout_top", "mout_clkout_top", CLKOUT_CMU_TOP, 8, 6),
 
-	DIV(0, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
+	DIV(CLK_DIV_ACP, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
 	DIV(0, "div_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
 	DIV(0, "div_dphy", "mout_dphy", DIV_DMC0, 8, 3),
-	DIV(0, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
+	DIV(CLK_DIV_DMC, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
 	DIV(0, "div_dmcd", "div_dmc", DIV_DMC0, 16, 3),
 	DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
 	DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
@@ -829,7 +829,7 @@ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
 	DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
 						8, 3, CLK_GET_RATE_NOCACHE, 0),
 	DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
-	DIV(0, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
+	DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
 	DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
 };
 

+ 48 - 168
drivers/clk/samsung/clk-exynos4415.c

@@ -113,19 +113,6 @@
 #define DIV_CPU0		0x14500
 #define DIV_CPU1		0x14504
 
-enum exynos4415_plls {
-	apll, epll, g3d_pll, isp_pll, disp_pll,
-	nr_plls,
-};
-
-static struct samsung_clk_provider *exynos4415_ctx;
-
-/*
- * Support for CMU save/restore across system suspends
- */
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos4415_clk_regs;
-
 static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
 	SRC_LEFTBUS,
 	DIV_LEFTBUS,
@@ -219,41 +206,6 @@ static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
 	DIV_CPU1,
 };
 
-static int exynos4415_clk_suspend(void)
-{
-	samsung_clk_save(exynos4415_ctx->reg_base, exynos4415_clk_regs,
-				ARRAY_SIZE(exynos4415_cmu_clk_regs));
-
-	return 0;
-}
-
-static void exynos4415_clk_resume(void)
-{
-	samsung_clk_restore(exynos4415_ctx->reg_base, exynos4415_clk_regs,
-				ARRAY_SIZE(exynos4415_cmu_clk_regs));
-}
-
-static struct syscore_ops exynos4415_clk_syscore_ops = {
-	.suspend = exynos4415_clk_suspend,
-	.resume = exynos4415_clk_resume,
-};
-
-static void exynos4415_clk_sleep_init(void)
-{
-	exynos4415_clk_regs =
-		samsung_clk_alloc_reg_dump(exynos4415_cmu_clk_regs,
-					ARRAY_SIZE(exynos4415_cmu_clk_regs));
-	if (!exynos4415_clk_regs) {
-		pr_warn("%s: Failed to allocate sleep save data\n", __func__);
-		return;
-	}
-
-	register_syscore_ops(&exynos4415_clk_syscore_ops);
-}
-#else
-static inline void exynos4415_clk_sleep_init(void) { }
-#endif
-
 /* list of all parent clock list */
 PNAME(mout_g3d_pllsrc_p)	= { "fin_pll", };
 
@@ -959,56 +911,40 @@ static struct samsung_pll_rate_table exynos4415_epll_rates[] = {
 	{ /* sentinel */ }
 };
 
-static struct samsung_pll_clock exynos4415_plls[nr_plls] __initdata = {
-	[apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
-			APLL_LOCK, APLL_CON0, NULL),
-	[epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
-			EPLL_LOCK, EPLL_CON0, NULL),
-	[g3d_pll] = PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll",
-			"mout_g3d_pllsrc", G3D_PLL_LOCK, G3D_PLL_CON0, NULL),
-	[isp_pll] = PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
-			ISP_PLL_LOCK, ISP_PLL_CON0, NULL),
-	[disp_pll] = PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
-			"fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, NULL),
+static struct samsung_pll_clock exynos4415_plls[] __initdata = {
+	PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
+		APLL_LOCK, APLL_CON0, exynos4415_pll_rates),
+	PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
+		EPLL_LOCK, EPLL_CON0, exynos4415_epll_rates),
+	PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "mout_g3d_pllsrc",
+		G3D_PLL_LOCK, G3D_PLL_CON0, exynos4415_pll_rates),
+	PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
+		ISP_PLL_LOCK, ISP_PLL_CON0, exynos4415_pll_rates),
+	PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
+		"fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, exynos4415_pll_rates),
+};
+
+static struct samsung_cmu_info cmu_info __initdata = {
+	.pll_clks		= exynos4415_plls,
+	.nr_pll_clks		= ARRAY_SIZE(exynos4415_plls),
+	.mux_clks		= exynos4415_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(exynos4415_mux_clks),
+	.div_clks		= exynos4415_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(exynos4415_div_clks),
+	.gate_clks		= exynos4415_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(exynos4415_gate_clks),
+	.fixed_clks		= exynos4415_fixed_rate_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(exynos4415_fixed_rate_clks),
+	.fixed_factor_clks	= exynos4415_fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(exynos4415_fixed_factor_clks),
+	.nr_clk_ids		= CLK_NR_CLKS,
+	.clk_regs		= exynos4415_cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(exynos4415_cmu_clk_regs),
 };
 
 static void __init exynos4415_cmu_init(struct device_node *np)
 {
-	void __iomem *reg_base;
-
-	reg_base = of_iomap(np, 0);
-	if (!reg_base)
-		panic("%s: failed to map registers\n", __func__);
-
-	exynos4415_ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
-	if (!exynos4415_ctx)
-		panic("%s: unable to allocate context.\n", __func__);
-
-	exynos4415_plls[apll].rate_table = exynos4415_pll_rates;
-	exynos4415_plls[epll].rate_table = exynos4415_epll_rates;
-	exynos4415_plls[g3d_pll].rate_table = exynos4415_pll_rates;
-	exynos4415_plls[isp_pll].rate_table = exynos4415_pll_rates;
-	exynos4415_plls[disp_pll].rate_table = exynos4415_pll_rates;
-
-	samsung_clk_register_fixed_factor(exynos4415_ctx,
-				exynos4415_fixed_factor_clks,
-				ARRAY_SIZE(exynos4415_fixed_factor_clks));
-	samsung_clk_register_fixed_rate(exynos4415_ctx,
-				exynos4415_fixed_rate_clks,
-				ARRAY_SIZE(exynos4415_fixed_rate_clks));
-
-	samsung_clk_register_pll(exynos4415_ctx, exynos4415_plls,
-				ARRAY_SIZE(exynos4415_plls), reg_base);
-	samsung_clk_register_mux(exynos4415_ctx, exynos4415_mux_clks,
-				ARRAY_SIZE(exynos4415_mux_clks));
-	samsung_clk_register_div(exynos4415_ctx, exynos4415_div_clks,
-				ARRAY_SIZE(exynos4415_div_clks));
-	samsung_clk_register_gate(exynos4415_ctx, exynos4415_gate_clks,
-				ARRAY_SIZE(exynos4415_gate_clks));
-
-	exynos4415_clk_sleep_init();
-
-	samsung_clk_of_add_provider(np, exynos4415_ctx);
+	samsung_cmu_register_one(np, &cmu_info);
 }
 CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
 
@@ -1027,16 +963,6 @@ CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
 #define SRC_DMC			0x300
 #define DIV_DMC1		0x504
 
-enum exynos4415_dmc_plls {
-	mpll, bpll,
-	nr_dmc_plls,
-};
-
-static struct samsung_clk_provider *exynos4415_dmc_ctx;
-
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos4415_dmc_clk_regs;
-
 static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
 	MPLL_LOCK,
 	MPLL_CON0,
@@ -1050,42 +976,6 @@ static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
 	DIV_DMC1,
 };
 
-static int exynos4415_dmc_clk_suspend(void)
-{
-	samsung_clk_save(exynos4415_dmc_ctx->reg_base,
-				exynos4415_dmc_clk_regs,
-				ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
-	return 0;
-}
-
-static void exynos4415_dmc_clk_resume(void)
-{
-	samsung_clk_restore(exynos4415_dmc_ctx->reg_base,
-				exynos4415_dmc_clk_regs,
-				ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
-}
-
-static struct syscore_ops exynos4415_dmc_clk_syscore_ops = {
-	.suspend = exynos4415_dmc_clk_suspend,
-	.resume = exynos4415_dmc_clk_resume,
-};
-
-static void exynos4415_dmc_clk_sleep_init(void)
-{
-	exynos4415_dmc_clk_regs =
-		samsung_clk_alloc_reg_dump(exynos4415_cmu_dmc_clk_regs,
-				ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs));
-	if (!exynos4415_dmc_clk_regs) {
-		pr_warn("%s: Failed to allocate sleep save data\n", __func__);
-		return;
-	}
-
-	register_syscore_ops(&exynos4415_dmc_clk_syscore_ops);
-}
-#else
-static inline void exynos4415_dmc_clk_sleep_init(void) { }
-#endif /* CONFIG_PM_SLEEP */
-
 PNAME(mout_mpll_p)		= { "fin_pll", "fout_mpll", };
 PNAME(mout_bpll_p)		= { "fin_pll", "fout_bpll", };
 PNAME(mbpll_p)			= { "mout_mpll", "mout_bpll", };
@@ -1107,38 +997,28 @@ static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = {
 	DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
 };
 
-static struct samsung_pll_clock exynos4415_dmc_plls[nr_dmc_plls] __initdata = {
-	[mpll] = PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
-		MPLL_LOCK, MPLL_CON0, NULL),
-	[bpll] = PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
-		BPLL_LOCK, BPLL_CON0, NULL),
+static struct samsung_pll_clock exynos4415_dmc_plls[] __initdata = {
+	PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
+		MPLL_LOCK, MPLL_CON0, exynos4415_pll_rates),
+	PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
+		BPLL_LOCK, BPLL_CON0, exynos4415_pll_rates),
+};
+
+static struct samsung_cmu_info cmu_dmc_info __initdata = {
+	.pll_clks		= exynos4415_dmc_plls,
+	.nr_pll_clks		= ARRAY_SIZE(exynos4415_dmc_plls),
+	.mux_clks		= exynos4415_dmc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(exynos4415_dmc_mux_clks),
+	.div_clks		= exynos4415_dmc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(exynos4415_dmc_div_clks),
+	.nr_clk_ids		= NR_CLKS_DMC,
+	.clk_regs		= exynos4415_cmu_dmc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs),
 };
 
 static void __init exynos4415_cmu_dmc_init(struct device_node *np)
 {
-	void __iomem *reg_base;
-
-	reg_base = of_iomap(np, 0);
-	if (!reg_base)
-		panic("%s: failed to map registers\n", __func__);
-
-	exynos4415_dmc_ctx = samsung_clk_init(np, reg_base, NR_CLKS_DMC);
-	if (!exynos4415_dmc_ctx)
-		panic("%s: unable to allocate context.\n", __func__);
-
-	exynos4415_dmc_plls[mpll].rate_table = exynos4415_pll_rates;
-	exynos4415_dmc_plls[bpll].rate_table = exynos4415_pll_rates;
-
-	samsung_clk_register_pll(exynos4415_dmc_ctx, exynos4415_dmc_plls,
-				ARRAY_SIZE(exynos4415_dmc_plls), reg_base);
-	samsung_clk_register_mux(exynos4415_dmc_ctx, exynos4415_dmc_mux_clks,
-				ARRAY_SIZE(exynos4415_dmc_mux_clks));
-	samsung_clk_register_div(exynos4415_dmc_ctx, exynos4415_dmc_div_clks,
-				ARRAY_SIZE(exynos4415_dmc_div_clks));
-
-	exynos4415_dmc_clk_sleep_init();
-
-	samsung_clk_of_add_provider(np, exynos4415_dmc_ctx);
+	samsung_cmu_register_one(np, &cmu_dmc_info);
 }
 CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
 		exynos4415_cmu_dmc_init);

+ 406 - 2
drivers/clk/samsung/clk-exynos7.c

@@ -34,6 +34,7 @@
 #define DIV_TOPC0		0x0600
 #define DIV_TOPC1		0x0604
 #define DIV_TOPC3		0x060C
+#define ENABLE_ACLK_TOPC1	0x0804
 
 static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
 	FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0),
@@ -45,6 +46,7 @@ static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
 };
 
 /* List of parent clocks for Muxes in CMU_TOPC */
+PNAME(mout_aud_pll_ctrl_p)	= { "fin_pll", "fout_aud_pll" };
 PNAME(mout_bus0_pll_ctrl_p)	= { "fin_pll", "fout_bus0_pll" };
 PNAME(mout_bus1_pll_ctrl_p)	= { "fin_pll", "fout_bus1_pll" };
 PNAME(mout_cc_pll_ctrl_p)	= { "fin_pll", "fout_cc_pll" };
@@ -104,9 +106,11 @@ static struct samsung_mux_clock topc_mux_clks[] __initdata = {
 
 	MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p,
 		MUX_SEL_TOPC1, 16, 1),
+	MUX(0, "mout_aud_pll_ctrl", mout_aud_pll_ctrl_p, MUX_SEL_TOPC1, 0, 1),
 
 	MUX(0, "mout_aclk_ccore_133", mout_topc_group2,	MUX_SEL_TOPC2, 4, 2),
 
+	MUX(0, "mout_aclk_mscl_532", mout_topc_group2, MUX_SEL_TOPC3, 20, 2),
 	MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2),
 };
 
@@ -114,6 +118,8 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
 	DIV(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133",
 		DIV_TOPC0, 4, 4),
 
+	DIV(DOUT_ACLK_MSCL_532, "dout_aclk_mscl_532", "mout_aclk_mscl_532",
+		DIV_TOPC1, 20, 4),
 	DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
 		DIV_TOPC1, 24, 4),
 
@@ -125,6 +131,18 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
 		DIV_TOPC3, 12, 3),
 	DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
 		DIV_TOPC3, 16, 3),
+	DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_aud_pll_ctrl",
+		DIV_TOPC3, 28, 3),
+};
+
+static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
+	PLL_36XX_RATE(491520000, 20, 1, 0, 31457),
+	{},
+};
+
+static struct samsung_gate_clock topc_gate_clks[] __initdata = {
+	GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532",
+		ENABLE_ACLK_TOPC1, 20, 0, 0),
 };
 
 static struct samsung_pll_clock topc_pll_clks[] __initdata = {
@@ -136,8 +154,8 @@ static struct samsung_pll_clock topc_pll_clks[] __initdata = {
 		BUS1_DPLL_CON0, NULL),
 	PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK,
 		MFC_PLL_CON0, NULL),
-	PLL(pll_1460x, 0, "fout_aud_pll", "fin_pll", AUD_PLL_LOCK,
-		AUD_PLL_CON0, NULL),
+	PLL(pll_1460x, FOUT_AUD_PLL, "fout_aud_pll", "fin_pll", AUD_PLL_LOCK,
+		AUD_PLL_CON0, pll1460x_24mhz_tbl),
 };
 
 static struct samsung_cmu_info topc_cmu_info __initdata = {
@@ -147,6 +165,8 @@ static struct samsung_cmu_info topc_cmu_info __initdata = {
 	.nr_mux_clks		= ARRAY_SIZE(topc_mux_clks),
 	.div_clks		= topc_div_clks,
 	.nr_div_clks		= ARRAY_SIZE(topc_div_clks),
+	.gate_clks		= topc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(topc_gate_clks),
 	.fixed_factor_clks	= topc_fixed_factor_clks,
 	.nr_fixed_factor_clks	= ARRAY_SIZE(topc_fixed_factor_clks),
 	.nr_clk_ids		= TOPC_NR_CLK,
@@ -166,9 +186,18 @@ CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc",
 #define MUX_SEL_TOP00			0x0200
 #define MUX_SEL_TOP01			0x0204
 #define MUX_SEL_TOP03			0x020C
+#define MUX_SEL_TOP0_PERIC0		0x0230
+#define MUX_SEL_TOP0_PERIC1		0x0234
+#define MUX_SEL_TOP0_PERIC2		0x0238
 #define MUX_SEL_TOP0_PERIC3		0x023C
 #define DIV_TOP03			0x060C
+#define DIV_TOP0_PERIC0			0x0630
+#define DIV_TOP0_PERIC1			0x0634
+#define DIV_TOP0_PERIC2			0x0638
 #define DIV_TOP0_PERIC3			0x063C
+#define ENABLE_SCLK_TOP0_PERIC0		0x0A30
+#define ENABLE_SCLK_TOP0_PERIC1		0x0A34
+#define ENABLE_SCLK_TOP0_PERIC2		0x0A38
 #define ENABLE_SCLK_TOP0_PERIC3		0x0A3C
 
 /* List of parent clocks for Muxes in CMU_TOP0 */
@@ -176,6 +205,7 @@ PNAME(mout_bus0_pll_p)	= { "fin_pll", "dout_sclk_bus0_pll" };
 PNAME(mout_bus1_pll_p)	= { "fin_pll", "dout_sclk_bus1_pll" };
 PNAME(mout_cc_pll_p)	= { "fin_pll", "dout_sclk_cc_pll" };
 PNAME(mout_mfc_pll_p)	= { "fin_pll", "dout_sclk_mfc_pll" };
+PNAME(mout_aud_pll_p)	= { "fin_pll", "dout_sclk_aud_pll" };
 
 PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll",
 	"ffac_top0_bus0_pll_div2"};
@@ -189,18 +219,34 @@ PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll",
 PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll",
 	"mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
 	"mout_top0_half_mfc_pll"};
+PNAME(mout_top0_group3) = {"ioclk_audiocdclk0",
+	"ioclk_audiocdclk1", "ioclk_spdif_extclk",
+	"mout_top0_aud_pll", "mout_top0_half_bus0_pll",
+	"mout_top0_half_bus1_pll"};
+PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll",
+	"mout_top0_half_bus0_pll", "mout_top0_half_bus1_pll"};
 
 static unsigned long top0_clk_regs[] __initdata = {
 	MUX_SEL_TOP00,
 	MUX_SEL_TOP01,
 	MUX_SEL_TOP03,
+	MUX_SEL_TOP0_PERIC0,
+	MUX_SEL_TOP0_PERIC1,
+	MUX_SEL_TOP0_PERIC2,
 	MUX_SEL_TOP0_PERIC3,
 	DIV_TOP03,
+	DIV_TOP0_PERIC0,
+	DIV_TOP0_PERIC1,
+	DIV_TOP0_PERIC2,
 	DIV_TOP0_PERIC3,
+	ENABLE_SCLK_TOP0_PERIC0,
+	ENABLE_SCLK_TOP0_PERIC1,
+	ENABLE_SCLK_TOP0_PERIC2,
 	ENABLE_SCLK_TOP0_PERIC3,
 };
 
 static struct samsung_mux_clock top0_mux_clks[] __initdata = {
+	MUX(0, "mout_top0_aud_pll", mout_aud_pll_p, MUX_SEL_TOP00, 0, 1),
 	MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1),
 	MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1),
 	MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1),
@@ -218,10 +264,20 @@ static struct samsung_mux_clock top0_mux_clks[] __initdata = {
 	MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2),
 	MUX(0, "mout_aclk_peric0_66", mout_top0_group1, MUX_SEL_TOP03, 20, 2),
 
+	MUX(0, "mout_sclk_spdif", mout_top0_group3, MUX_SEL_TOP0_PERIC0, 4, 3),
+	MUX(0, "mout_sclk_pcm1", mout_top0_group4, MUX_SEL_TOP0_PERIC0, 8, 2),
+	MUX(0, "mout_sclk_i2s1", mout_top0_group4, MUX_SEL_TOP0_PERIC0, 20, 2),
+
+	MUX(0, "mout_sclk_spi1", mout_top0_group1, MUX_SEL_TOP0_PERIC1, 8, 2),
+	MUX(0, "mout_sclk_spi0", mout_top0_group1, MUX_SEL_TOP0_PERIC1, 20, 2),
+
+	MUX(0, "mout_sclk_spi3", mout_top0_group1, MUX_SEL_TOP0_PERIC2, 8, 2),
+	MUX(0, "mout_sclk_spi2", mout_top0_group1, MUX_SEL_TOP0_PERIC2, 20, 2),
 	MUX(0, "mout_sclk_uart3", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 4, 2),
 	MUX(0, "mout_sclk_uart2", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 8, 2),
 	MUX(0, "mout_sclk_uart1", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 12, 2),
 	MUX(0, "mout_sclk_uart0", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 16, 2),
+	MUX(0, "mout_sclk_spi4", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 20, 2),
 };
 
 static struct samsung_div_clock top0_div_clks[] __initdata = {
@@ -230,13 +286,40 @@ static struct samsung_div_clock top0_div_clks[] __initdata = {
 	DIV(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66",
 		DIV_TOP03, 20, 6),
 
+	DIV(0, "dout_sclk_spdif", "mout_sclk_spdif", DIV_TOP0_PERIC0, 4, 4),
+	DIV(0, "dout_sclk_pcm1", "mout_sclk_pcm1", DIV_TOP0_PERIC0, 8, 12),
+	DIV(0, "dout_sclk_i2s1", "mout_sclk_i2s1", DIV_TOP0_PERIC0, 20, 10),
+
+	DIV(0, "dout_sclk_spi1", "mout_sclk_spi1", DIV_TOP0_PERIC1, 8, 12),
+	DIV(0, "dout_sclk_spi0", "mout_sclk_spi0", DIV_TOP0_PERIC1, 20, 12),
+
+	DIV(0, "dout_sclk_spi3", "mout_sclk_spi3", DIV_TOP0_PERIC2, 8, 12),
+	DIV(0, "dout_sclk_spi2", "mout_sclk_spi2", DIV_TOP0_PERIC2, 20, 12),
+
 	DIV(0, "dout_sclk_uart3", "mout_sclk_uart3", DIV_TOP0_PERIC3, 4, 4),
 	DIV(0, "dout_sclk_uart2", "mout_sclk_uart2", DIV_TOP0_PERIC3, 8, 4),
 	DIV(0, "dout_sclk_uart1", "mout_sclk_uart1", DIV_TOP0_PERIC3, 12, 4),
 	DIV(0, "dout_sclk_uart0", "mout_sclk_uart0", DIV_TOP0_PERIC3, 16, 4),
+	DIV(0, "dout_sclk_spi4", "mout_sclk_spi4", DIV_TOP0_PERIC3, 20, 12),
 };
 
 static struct samsung_gate_clock top0_gate_clks[] __initdata = {
+	GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif",
+		ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
+	GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1",
+		ENABLE_SCLK_TOP0_PERIC0, 8, CLK_SET_RATE_PARENT, 0),
+	GATE(CLK_SCLK_I2S1, "sclk_i2s1", "dout_sclk_i2s1",
+		ENABLE_SCLK_TOP0_PERIC0, 20, CLK_SET_RATE_PARENT, 0),
+
+	GATE(CLK_SCLK_SPI1, "sclk_spi1", "dout_sclk_spi1",
+		ENABLE_SCLK_TOP0_PERIC1, 8, CLK_SET_RATE_PARENT, 0),
+	GATE(CLK_SCLK_SPI0, "sclk_spi0", "dout_sclk_spi0",
+		ENABLE_SCLK_TOP0_PERIC1, 20, CLK_SET_RATE_PARENT, 0),
+
+	GATE(CLK_SCLK_SPI3, "sclk_spi3", "dout_sclk_spi3",
+		ENABLE_SCLK_TOP0_PERIC2, 8, CLK_SET_RATE_PARENT, 0),
+	GATE(CLK_SCLK_SPI2, "sclk_spi2", "dout_sclk_spi2",
+		ENABLE_SCLK_TOP0_PERIC2, 20, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_sclk_uart3",
 		ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0),
 	GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_sclk_uart2",
@@ -245,6 +328,8 @@ static struct samsung_gate_clock top0_gate_clks[] __initdata = {
 		ENABLE_SCLK_TOP0_PERIC3, 12, 0, 0),
 	GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0",
 		ENABLE_SCLK_TOP0_PERIC3, 16, 0, 0),
+	GATE(CLK_SCLK_SPI4, "sclk_spi4", "dout_sclk_spi4",
+		ENABLE_SCLK_TOP0_PERIC3, 20, CLK_SET_RATE_PARENT, 0),
 };
 
 static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
@@ -343,6 +428,8 @@ static struct samsung_mux_clock top1_mux_clks[] __initdata = {
 	MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2),
 
 	MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2),
+	MUX(0, "mout_sclk_usbdrd300", mout_top1_group1,
+		MUX_SEL_TOP1_FSYS0, 28, 2),
 
 	MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2),
 	MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2),
@@ -356,6 +443,8 @@ static struct samsung_div_clock top1_div_clks[] __initdata = {
 
 	DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
 		DIV_TOP1_FSYS0, 24, 4),
+	DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300",
+		DIV_TOP1_FSYS0, 28, 4),
 
 	DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
 		DIV_TOP1_FSYS1, 24, 4),
@@ -366,6 +455,8 @@ static struct samsung_div_clock top1_div_clks[] __initdata = {
 static struct samsung_gate_clock top1_gate_clks[] __initdata = {
 	GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
 		ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0),
+	GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300",
+		ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0),
 
 	GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
 		ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0),
@@ -514,6 +605,7 @@ static void __init exynos7_clk_peric0_init(struct device_node *np)
 /* Register Offset definitions for CMU_PERIC1 (0x14C80000) */
 #define MUX_SEL_PERIC10			0x0200
 #define MUX_SEL_PERIC11			0x0204
+#define MUX_SEL_PERIC12			0x0208
 #define ENABLE_PCLK_PERIC1		0x0900
 #define ENABLE_SCLK_PERIC10		0x0A00
 
@@ -525,10 +617,16 @@ PNAME(mout_aclk_peric1_66_p)	= { "fin_pll", "dout_aclk_peric1_66" };
 PNAME(mout_sclk_uart1_p)	= { "fin_pll", "sclk_uart1" };
 PNAME(mout_sclk_uart2_p)	= { "fin_pll", "sclk_uart2" };
 PNAME(mout_sclk_uart3_p)	= { "fin_pll", "sclk_uart3" };
+PNAME(mout_sclk_spi0_p)		= { "fin_pll", "sclk_spi0" };
+PNAME(mout_sclk_spi1_p)		= { "fin_pll", "sclk_spi1" };
+PNAME(mout_sclk_spi2_p)		= { "fin_pll", "sclk_spi2" };
+PNAME(mout_sclk_spi3_p)		= { "fin_pll", "sclk_spi3" };
+PNAME(mout_sclk_spi4_p)		= { "fin_pll", "sclk_spi4" };
 
 static unsigned long peric1_clk_regs[] __initdata = {
 	MUX_SEL_PERIC10,
 	MUX_SEL_PERIC11,
+	MUX_SEL_PERIC12,
 	ENABLE_PCLK_PERIC1,
 	ENABLE_SCLK_PERIC10,
 };
@@ -537,6 +635,16 @@ static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
 	MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p,
 		MUX_SEL_PERIC10, 0, 1),
 
+	MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_p,
+		MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0),
+	MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_p,
+		MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0),
+	MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_p,
+		MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0),
+	MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_p,
+		MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0),
+	MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_p,
+		MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0),
 	MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p,
 		MUX_SEL_PERIC11, 20, 1),
 	MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p,
@@ -562,6 +670,22 @@ static struct samsung_gate_clock peric1_gate_clks[] __initdata = {
 		ENABLE_PCLK_PERIC1, 10, 0, 0),
 	GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user",
 		ENABLE_PCLK_PERIC1, 11, 0, 0),
+	GATE(PCLK_SPI0, "pclk_spi0", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 12, 0, 0),
+	GATE(PCLK_SPI1, "pclk_spi1", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 13, 0, 0),
+	GATE(PCLK_SPI2, "pclk_spi2", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 14, 0, 0),
+	GATE(PCLK_SPI3, "pclk_spi3", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 15, 0, 0),
+	GATE(PCLK_SPI4, "pclk_spi4", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 16, 0, 0),
+	GATE(PCLK_I2S1, "pclk_i2s1", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 17, CLK_SET_RATE_PARENT, 0),
+	GATE(PCLK_PCM1, "pclk_pcm1", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 18, 0, 0),
+	GATE(PCLK_SPDIF, "pclk_spdif", "mout_aclk_peric1_66_user",
+		ENABLE_PCLK_PERIC1, 19, 0, 0),
 
 	GATE(SCLK_UART1, "sclk_uart1_user", "mout_sclk_uart1_user",
 		ENABLE_SCLK_PERIC10, 9, 0, 0),
@@ -569,6 +693,22 @@ static struct samsung_gate_clock peric1_gate_clks[] __initdata = {
 		ENABLE_SCLK_PERIC10, 10, 0, 0),
 	GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user",
 		ENABLE_SCLK_PERIC10, 11, 0, 0),
+	GATE(SCLK_SPI0, "sclk_spi0_user", "mout_sclk_spi0_user",
+		ENABLE_SCLK_PERIC10, 12, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_SPI1, "sclk_spi1_user", "mout_sclk_spi1_user",
+		ENABLE_SCLK_PERIC10, 13, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_SPI2, "sclk_spi2_user", "mout_sclk_spi2_user",
+		ENABLE_SCLK_PERIC10, 14, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_SPI3, "sclk_spi3_user", "mout_sclk_spi3_user",
+		ENABLE_SCLK_PERIC10, 15, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_SPI4, "sclk_spi4_user", "mout_sclk_spi4_user",
+		ENABLE_SCLK_PERIC10, 16, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_I2S1, "sclk_i2s1_user", "sclk_i2s1",
+		ENABLE_SCLK_PERIC10, 17, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_PCM1, "sclk_pcm1_user", "sclk_pcm1",
+		ENABLE_SCLK_PERIC10, 18, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_SPDIF, "sclk_spdif_user", "sclk_spdif",
+		ENABLE_SCLK_PERIC10, 19, CLK_SET_RATE_PARENT, 0),
 };
 
 static struct samsung_cmu_info peric1_cmu_info __initdata = {
@@ -647,7 +787,12 @@ CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris",
 /* Register Offset definitions for CMU_FSYS0 (0x10E90000) */
 #define MUX_SEL_FSYS00			0x0200
 #define MUX_SEL_FSYS01			0x0204
+#define MUX_SEL_FSYS02			0x0208
+#define ENABLE_ACLK_FSYS00		0x0800
 #define ENABLE_ACLK_FSYS01		0x0804
+#define ENABLE_SCLK_FSYS01		0x0A04
+#define ENABLE_SCLK_FSYS02		0x0A08
+#define ENABLE_SCLK_FSYS04		0x0A10
 
 /*
  * List of parent clocks for Muxes in CMU_FSYS0
@@ -655,10 +800,29 @@ CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris",
 PNAME(mout_aclk_fsys0_200_p)	= { "fin_pll", "dout_aclk_fsys0_200" };
 PNAME(mout_sclk_mmc2_p)		= { "fin_pll", "sclk_mmc2" };
 
+PNAME(mout_sclk_usbdrd300_p)	= { "fin_pll", "sclk_usbdrd300" };
+PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_p)	= { "fin_pll",
+				"phyclk_usbdrd300_udrd30_phyclock" };
+PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_p)	= { "fin_pll",
+				"phyclk_usbdrd300_udrd30_pipe_pclk" };
+
+/* fixed rate clocks used in the FSYS0 block */
+struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
+	FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL,
+		CLK_IS_ROOT, 60000000),
+	FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL,
+		CLK_IS_ROOT, 125000000),
+};
+
 static unsigned long fsys0_clk_regs[] __initdata = {
 	MUX_SEL_FSYS00,
 	MUX_SEL_FSYS01,
+	MUX_SEL_FSYS02,
+	ENABLE_ACLK_FSYS00,
 	ENABLE_ACLK_FSYS01,
+	ENABLE_SCLK_FSYS01,
+	ENABLE_SCLK_FSYS02,
+	ENABLE_SCLK_FSYS04,
 };
 
 static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
@@ -666,11 +830,49 @@ static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
 		MUX_SEL_FSYS00, 24, 1),
 
 	MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1),
+	MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_p,
+		MUX_SEL_FSYS01, 28, 1),
+
+	MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user",
+		mout_phyclk_usbdrd300_udrd30_pipe_pclk_p,
+		MUX_SEL_FSYS02, 24, 1),
+	MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user",
+		mout_phyclk_usbdrd300_udrd30_phyclk_p,
+		MUX_SEL_FSYS02, 28, 1),
 };
 
 static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
+	GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
+		"mout_aclk_fsys0_200_user",
+		ENABLE_ACLK_FSYS00, 19, 0, 0),
+	GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user",
+			ENABLE_ACLK_FSYS00, 3, 0, 0),
+	GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user",
+			ENABLE_ACLK_FSYS00, 4, 0, 0),
+
+	GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user",
+		ENABLE_ACLK_FSYS01, 29, 0, 0),
 	GATE(ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys0_200_user",
 		ENABLE_ACLK_FSYS01, 31, 0, 0),
+
+	GATE(SCLK_USBDRD300_SUSPENDCLK, "sclk_usbdrd300_suspendclk",
+		"mout_sclk_usbdrd300_user",
+		ENABLE_SCLK_FSYS01, 4, 0, 0),
+	GATE(SCLK_USBDRD300_REFCLK, "sclk_usbdrd300_refclk", "fin_pll",
+		ENABLE_SCLK_FSYS01, 8, 0, 0),
+
+	GATE(PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER,
+		"phyclk_usbdrd300_udrd30_pipe_pclk_user",
+		"mout_phyclk_usbdrd300_udrd30_pipe_pclk_user",
+		ENABLE_SCLK_FSYS02, 24, 0, 0),
+	GATE(PHYCLK_USBDRD300_UDRD30_PHYCLK_USER,
+		"phyclk_usbdrd300_udrd30_phyclk_user",
+		"mout_phyclk_usbdrd300_udrd30_phyclk_user",
+		ENABLE_SCLK_FSYS02, 28, 0, 0),
+
+	GATE(OSCCLK_PHY_CLKOUT_USB30_PHY, "oscclk_phy_clkout_usb30_phy",
+		"fin_pll",
+		ENABLE_SCLK_FSYS04, 28, 0, 0),
 };
 
 static struct samsung_cmu_info fsys0_cmu_info __initdata = {
@@ -741,3 +943,205 @@ static void __init exynos7_clk_fsys1_init(struct device_node *np)
 
 CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1",
 	exynos7_clk_fsys1_init);
+
+#define MUX_SEL_MSCL			0x0200
+#define DIV_MSCL			0x0600
+#define ENABLE_ACLK_MSCL		0x0800
+#define ENABLE_PCLK_MSCL		0x0900
+
+/* List of parent clocks for Muxes in CMU_MSCL */
+PNAME(mout_aclk_mscl_532_user_p)	= { "fin_pll", "aclk_mscl_532" };
+
+static unsigned long mscl_clk_regs[] __initdata = {
+	MUX_SEL_MSCL,
+	DIV_MSCL,
+	ENABLE_ACLK_MSCL,
+	ENABLE_PCLK_MSCL,
+};
+
+static struct samsung_mux_clock mscl_mux_clks[] __initdata = {
+	MUX(USERMUX_ACLK_MSCL_532, "usermux_aclk_mscl_532",
+		mout_aclk_mscl_532_user_p, MUX_SEL_MSCL, 0, 1),
+};
+static struct samsung_div_clock mscl_div_clks[] __initdata = {
+	DIV(DOUT_PCLK_MSCL, "dout_pclk_mscl", "usermux_aclk_mscl_532",
+			DIV_MSCL, 0, 3),
+};
+static struct samsung_gate_clock mscl_gate_clks[] __initdata = {
+
+	GATE(ACLK_MSCL_0, "aclk_mscl_0", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 31, 0, 0),
+	GATE(ACLK_MSCL_1, "aclk_mscl_1", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 30, 0, 0),
+	GATE(ACLK_JPEG, "aclk_jpeg", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 29, 0, 0),
+	GATE(ACLK_G2D, "aclk_g2d", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 28, 0, 0),
+	GATE(ACLK_LH_ASYNC_SI_MSCL_0, "aclk_lh_async_si_mscl_0",
+			"usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 27, 0, 0),
+	GATE(ACLK_LH_ASYNC_SI_MSCL_1, "aclk_lh_async_si_mscl_1",
+			"usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 26, 0, 0),
+	GATE(ACLK_XIU_MSCLX_0, "aclk_xiu_msclx_0", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 25, 0, 0),
+	GATE(ACLK_XIU_MSCLX_1, "aclk_xiu_msclx_1", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 24, 0, 0),
+	GATE(ACLK_AXI2ACEL_BRIDGE, "aclk_axi2acel_bridge",
+			"usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 23, 0, 0),
+	GATE(ACLK_QE_MSCL_0, "aclk_qe_mscl_0", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 22, 0, 0),
+	GATE(ACLK_QE_MSCL_1, "aclk_qe_mscl_1", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 21, 0, 0),
+	GATE(ACLK_QE_JPEG, "aclk_qe_jpeg", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 20, 0, 0),
+	GATE(ACLK_QE_G2D, "aclk_qe_g2d", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 19, 0, 0),
+	GATE(ACLK_PPMU_MSCL_0, "aclk_ppmu_mscl_0", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 18, 0, 0),
+	GATE(ACLK_PPMU_MSCL_1, "aclk_ppmu_mscl_1", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 17, 0, 0),
+	GATE(ACLK_MSCLNP_133, "aclk_msclnp_133", "usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 16, 0, 0),
+	GATE(ACLK_AHB2APB_MSCL0P, "aclk_ahb2apb_mscl0p",
+			"usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 15, 0, 0),
+	GATE(ACLK_AHB2APB_MSCL1P, "aclk_ahb2apb_mscl1p",
+			"usermux_aclk_mscl_532",
+			ENABLE_ACLK_MSCL, 14, 0, 0),
+
+	GATE(PCLK_MSCL_0, "pclk_mscl_0", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 31, 0, 0),
+	GATE(PCLK_MSCL_1, "pclk_mscl_1", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 30, 0, 0),
+	GATE(PCLK_JPEG, "pclk_jpeg", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 29, 0, 0),
+	GATE(PCLK_G2D, "pclk_g2d", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 28, 0, 0),
+	GATE(PCLK_QE_MSCL_0, "pclk_qe_mscl_0", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 27, 0, 0),
+	GATE(PCLK_QE_MSCL_1, "pclk_qe_mscl_1", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 26, 0, 0),
+	GATE(PCLK_QE_JPEG, "pclk_qe_jpeg", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 25, 0, 0),
+	GATE(PCLK_QE_G2D, "pclk_qe_g2d", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 24, 0, 0),
+	GATE(PCLK_PPMU_MSCL_0, "pclk_ppmu_mscl_0", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 23, 0, 0),
+	GATE(PCLK_PPMU_MSCL_1, "pclk_ppmu_mscl_1", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 22, 0, 0),
+	GATE(PCLK_AXI2ACEL_BRIDGE, "pclk_axi2acel_bridge", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 21, 0, 0),
+	GATE(PCLK_PMU_MSCL, "pclk_pmu_mscl", "dout_pclk_mscl",
+			ENABLE_PCLK_MSCL, 20, 0, 0),
+};
+
+static struct samsung_cmu_info mscl_cmu_info __initdata = {
+	.mux_clks		= mscl_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mscl_mux_clks),
+	.div_clks		= mscl_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mscl_div_clks),
+	.gate_clks		= mscl_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mscl_gate_clks),
+	.nr_clk_ids		= MSCL_NR_CLK,
+	.clk_regs		= mscl_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mscl_clk_regs),
+};
+
+static void __init exynos7_clk_mscl_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &mscl_cmu_info);
+}
+
+CLK_OF_DECLARE(exynos7_clk_mscl, "samsung,exynos7-clock-mscl",
+		exynos7_clk_mscl_init);
+
+/* Register Offset definitions for CMU_AUD (0x114C0000) */
+#define	MUX_SEL_AUD			0x0200
+#define	DIV_AUD0			0x0600
+#define	DIV_AUD1			0x0604
+#define	ENABLE_ACLK_AUD			0x0800
+#define	ENABLE_PCLK_AUD			0x0900
+#define	ENABLE_SCLK_AUD			0x0A00
+
+/*
+ * List of parent clocks for Muxes in CMU_AUD
+ */
+PNAME(mout_aud_pll_user_p) = { "fin_pll", "fout_aud_pll" };
+PNAME(mout_aud_group_p) = { "dout_aud_cdclk", "ioclk_audiocdclk0" };
+
+static unsigned long aud_clk_regs[] __initdata = {
+	MUX_SEL_AUD,
+	DIV_AUD0,
+	DIV_AUD1,
+	ENABLE_ACLK_AUD,
+	ENABLE_PCLK_AUD,
+	ENABLE_SCLK_AUD,
+};
+
+static struct samsung_mux_clock aud_mux_clks[] __initdata = {
+	MUX(0, "mout_sclk_i2s", mout_aud_group_p, MUX_SEL_AUD, 12, 1),
+	MUX(0, "mout_sclk_pcm", mout_aud_group_p, MUX_SEL_AUD, 16, 1),
+	MUX(0, "mout_aud_pll_user", mout_aud_pll_user_p, MUX_SEL_AUD, 20, 1),
+};
+
+static struct samsung_div_clock aud_div_clks[] __initdata = {
+	DIV(0, "dout_aud_ca5", "mout_aud_pll_user", DIV_AUD0, 0, 4),
+	DIV(0, "dout_aclk_aud", "dout_aud_ca5", DIV_AUD0, 4, 4),
+	DIV(0, "dout_aud_pclk_dbg", "dout_aud_ca5", DIV_AUD0, 8, 4),
+
+	DIV(0, "dout_sclk_i2s", "mout_sclk_i2s", DIV_AUD1, 0, 4),
+	DIV(0, "dout_sclk_pcm", "mout_sclk_pcm", DIV_AUD1, 4, 8),
+	DIV(0, "dout_sclk_uart", "dout_aud_cdclk", DIV_AUD1, 12, 4),
+	DIV(0, "dout_sclk_slimbus", "dout_aud_cdclk", DIV_AUD1, 16, 5),
+	DIV(0, "dout_aud_cdclk", "mout_aud_pll_user", DIV_AUD1, 24, 4),
+};
+
+static struct samsung_gate_clock aud_gate_clks[] __initdata = {
+	GATE(SCLK_PCM, "sclk_pcm", "dout_sclk_pcm",
+			ENABLE_SCLK_AUD, 27, CLK_SET_RATE_PARENT, 0),
+	GATE(SCLK_I2S, "sclk_i2s", "dout_sclk_i2s",
+			ENABLE_SCLK_AUD, 28, CLK_SET_RATE_PARENT, 0),
+	GATE(0, "sclk_uart", "dout_sclk_uart", ENABLE_SCLK_AUD, 29, 0, 0),
+	GATE(0, "sclk_slimbus", "dout_sclk_slimbus",
+			ENABLE_SCLK_AUD, 30, 0, 0),
+
+	GATE(0, "pclk_dbg_aud", "dout_aud_pclk_dbg", ENABLE_PCLK_AUD, 19, 0, 0),
+	GATE(0, "pclk_gpio_aud", "dout_aclk_aud", ENABLE_PCLK_AUD, 20, 0, 0),
+	GATE(0, "pclk_wdt1", "dout_aclk_aud", ENABLE_PCLK_AUD, 22, 0, 0),
+	GATE(0, "pclk_wdt0", "dout_aclk_aud", ENABLE_PCLK_AUD, 23, 0, 0),
+	GATE(0, "pclk_slimbus", "dout_aclk_aud", ENABLE_PCLK_AUD, 24, 0, 0),
+	GATE(0, "pclk_uart", "dout_aclk_aud", ENABLE_PCLK_AUD, 25, 0, 0),
+	GATE(PCLK_PCM, "pclk_pcm", "dout_aclk_aud",
+			ENABLE_PCLK_AUD, 26, CLK_SET_RATE_PARENT, 0),
+	GATE(PCLK_I2S, "pclk_i2s", "dout_aclk_aud",
+			ENABLE_PCLK_AUD, 27, CLK_SET_RATE_PARENT, 0),
+	GATE(0, "pclk_timer", "dout_aclk_aud", ENABLE_PCLK_AUD, 28, 0, 0),
+	GATE(0, "pclk_smmu_aud", "dout_aclk_aud", ENABLE_PCLK_AUD, 31, 0, 0),
+
+	GATE(0, "aclk_smmu_aud", "dout_aclk_aud", ENABLE_ACLK_AUD, 27, 0, 0),
+	GATE(0, "aclk_acel_lh_async_si_top", "dout_aclk_aud",
+			 ENABLE_ACLK_AUD, 28, 0, 0),
+	GATE(ACLK_ADMA, "aclk_dmac", "dout_aclk_aud", ENABLE_ACLK_AUD, 31, 0, 0),
+};
+
+static struct samsung_cmu_info aud_cmu_info __initdata = {
+	.mux_clks		= aud_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(aud_mux_clks),
+	.div_clks		= aud_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(aud_div_clks),
+	.gate_clks		= aud_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(aud_gate_clks),
+	.nr_clk_ids		= AUD_NR_CLK,
+	.clk_regs		= aud_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(aud_clk_regs),
+};
+
+static void __init exynos7_clk_aud_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &aud_cmu_info);
+}
+
+CLK_OF_DECLARE(exynos7_clk_aud, "samsung,exynos7-clock-aud",
+		exynos7_clk_aud_init);

+ 10 - 3
drivers/clk/samsung/clk.c

@@ -374,19 +374,24 @@ static void samsung_clk_sleep_init(void __iomem *reg_base,
  * Common function which registers plls, muxes, dividers and gates
  * for each CMU. It also add CMU register list to register cache.
  */
-void __init samsung_cmu_register_one(struct device_node *np,
+struct samsung_clk_provider * __init samsung_cmu_register_one(
+			struct device_node *np,
 			struct samsung_cmu_info *cmu)
 {
 	void __iomem *reg_base;
 	struct samsung_clk_provider *ctx;
 
 	reg_base = of_iomap(np, 0);
-	if (!reg_base)
+	if (!reg_base) {
 		panic("%s: failed to map registers\n", __func__);
+		return NULL;
+	}
 
 	ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
-	if (!ctx)
+	if (!ctx) {
 		panic("%s: unable to alllocate ctx\n", __func__);
+		return ctx;
+	}
 
 	if (cmu->pll_clks)
 		samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
@@ -410,4 +415,6 @@ void __init samsung_cmu_register_one(struct device_node *np,
 			cmu->nr_clk_regs);
 
 	samsung_clk_of_add_provider(np, ctx);
+
+	return ctx;
 }

+ 2 - 1
drivers/clk/samsung/clk.h

@@ -392,7 +392,8 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 			struct samsung_pll_clock *pll_list,
 			unsigned int nr_clk, void __iomem *base);
 
-extern void __init samsung_cmu_register_one(struct device_node *,
+extern struct samsung_clk_provider __init *samsung_cmu_register_one(
+			struct device_node *,
 			struct samsung_cmu_info *);
 
 extern unsigned long _get_rate(const char *clk_name);

+ 2 - 0
drivers/clk/shmobile/Makefile

@@ -1,9 +1,11 @@
 obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)		+= clk-rz.o
+obj-$(CONFIG_ARCH_R8A73A4)		+= clk-r8a73a4.o
 obj-$(CONFIG_ARCH_R8A7740)		+= clk-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7779)		+= clk-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7793)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7794)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SH73A0)		+= clk-sh73a0.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o

+ 14 - 4
drivers/clk/shmobile/clk-div6.c

@@ -54,12 +54,19 @@ static int cpg_div6_clock_enable(struct clk_hw *hw)
 static void cpg_div6_clock_disable(struct clk_hw *hw)
 {
 	struct div6_clock *clock = to_div6_clock(hw);
+	u32 val;
 
-	/* DIV6 clocks require the divisor field to be non-zero when stopping
-	 * the clock.
+	val = clk_readl(clock->reg);
+	val |= CPG_DIV6_CKSTP;
+	/*
+	 * DIV6 clocks require the divisor field to be non-zero when stopping
+	 * the clock. However, some clocks (e.g. ZB on sh73a0) fail to be
+	 * re-enabled later if the divisor field is changed when stopping the
+	 * clock
 	 */
-	clk_writel(clk_readl(clock->reg) | CPG_DIV6_CKSTP | CPG_DIV6_DIV_MASK,
-		   clock->reg);
+	if (!(val & CPG_DIV6_DIV_MASK))
+		val |= CPG_DIV6_DIV_MASK;
+	clk_writel(val, clock->reg);
 }
 
 static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
@@ -83,6 +90,9 @@ static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
 {
 	unsigned int div;
 
+	if (!rate)
+		rate = 1;
+
 	div = DIV_ROUND_CLOSEST(parent_rate, rate);
 	return clamp_t(unsigned int, div, 1, 64);
 }

+ 241 - 0
drivers/clk/shmobile/clk-r8a73a4.c

@@ -0,0 +1,241 @@
+/*
+ * r8a73a4 Core CPG Clocks
+ *
+ * Copyright (C) 2014  Ulrich Hecht
+ *
+ * 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; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct r8a73a4_cpg {
+	struct clk_onecell_data data;
+	spinlock_t lock;
+	void __iomem *reg;
+};
+
+#define CPG_CKSCR	0xc0
+#define CPG_FRQCRA	0x00
+#define CPG_FRQCRB	0x04
+#define CPG_FRQCRC	0xe0
+#define CPG_PLL0CR	0xd8
+#define CPG_PLL1CR	0x28
+#define CPG_PLL2CR	0x2c
+#define CPG_PLL2HCR	0xe4
+#define CPG_PLL2SCR	0xf4
+
+#define CLK_ENABLE_ON_INIT BIT(0)
+
+struct div4_clk {
+	const char *name;
+	unsigned int reg;
+	unsigned int shift;
+};
+
+static struct div4_clk div4_clks[] = {
+	{ "i",	CPG_FRQCRA, 20 },
+	{ "m3", CPG_FRQCRA, 12 },
+	{ "b",	CPG_FRQCRA,  8 },
+	{ "m1", CPG_FRQCRA,  4 },
+	{ "m2", CPG_FRQCRA,  0 },
+	{ "zx", CPG_FRQCRB, 12 },
+	{ "zs", CPG_FRQCRB,  8 },
+	{ "hp", CPG_FRQCRB,  4 },
+	{ NULL, 0, 0 },
+};
+
+static const struct clk_div_table div4_div_table[] = {
+	{ 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 },
+	{ 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 },
+	{ 12, 10 }, { 0, 0 }
+};
+
+static struct clk * __init
+r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg,
+			     const char *name)
+{
+	const struct clk_div_table *table = NULL;
+	const char *parent_name;
+	unsigned int shift, reg;
+	unsigned int mult = 1;
+	unsigned int div = 1;
+
+
+	if (!strcmp(name, "main")) {
+		u32 ckscr = clk_readl(cpg->reg + CPG_CKSCR);
+
+		switch ((ckscr >> 28) & 3) {
+		case 0:	/* extal1 */
+			parent_name = of_clk_get_parent_name(np, 0);
+			break;
+		case 1:	/* extal1 / 2 */
+			parent_name = of_clk_get_parent_name(np, 0);
+			div = 2;
+			break;
+		case 2: /* extal2 */
+			parent_name = of_clk_get_parent_name(np, 1);
+			break;
+		case 3: /* extal2 / 2 */
+			parent_name = of_clk_get_parent_name(np, 1);
+			div = 2;
+			break;
+		}
+	} else if (!strcmp(name, "pll0")) {
+		/* PLL0/1 are configurable multiplier clocks. Register them as
+		 * fixed factor clocks for now as there's no generic multiplier
+		 * clock implementation and we currently have no need to change
+		 * the multiplier value.
+		 */
+		u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+
+		parent_name = "main";
+		mult = ((value >> 24) & 0x7f) + 1;
+		if (value & BIT(20))
+			div = 2;
+	} else if (!strcmp(name, "pll1")) {
+		u32 value = clk_readl(cpg->reg + CPG_PLL1CR);
+
+		parent_name = "main";
+		/* XXX: enable bit? */
+		mult = ((value >> 24) & 0x7f) + 1;
+		if (value & BIT(7))
+			div = 2;
+	} else if (!strncmp(name, "pll2", 4)) {
+		u32 value, cr;
+
+		switch (name[4]) {
+		case 0:
+			cr = CPG_PLL2CR;
+			break;
+		case 's':
+			cr = CPG_PLL2SCR;
+			break;
+		case 'h':
+			cr = CPG_PLL2HCR;
+			break;
+		default:
+			return ERR_PTR(-EINVAL);
+		}
+		value = clk_readl(cpg->reg + cr);
+		switch ((value >> 5) & 7) {
+		case 0:
+			parent_name = "main";
+			div = 2;
+			break;
+		case 1:
+			parent_name = "extal2";
+			div = 2;
+			break;
+		case 3:
+			parent_name = "extal2";
+			div = 4;
+			break;
+		case 4:
+			parent_name = "main";
+			break;
+		case 5:
+			parent_name = "extal2";
+			break;
+		default:
+			pr_warn("%s: unexpected parent of %s\n", __func__,
+				name);
+			return ERR_PTR(-EINVAL);
+		}
+		/* XXX: enable bit? */
+		mult = ((value >> 24) & 0x7f) + 1;
+	} else if (!strcmp(name, "z") || !strcmp(name, "z2")) {
+		u32 shift = 8;
+
+		parent_name = "pll0";
+		if (name[1] == '2') {
+			div = 2;
+			shift = 0;
+		}
+		div *= 32;
+		mult = 0x20 - ((clk_readl(cpg->reg + CPG_FRQCRC) >> shift)
+		       & 0x1f);
+	} else {
+		struct div4_clk *c;
+
+		for (c = div4_clks; c->name; c++) {
+			if (!strcmp(name, c->name))
+				break;
+		}
+		if (!c->name)
+			return ERR_PTR(-EINVAL);
+
+		parent_name = "pll1";
+		table = div4_div_table;
+		reg = c->reg;
+		shift = c->shift;
+	}
+
+	if (!table) {
+		return clk_register_fixed_factor(NULL, name, parent_name, 0,
+						 mult, div);
+	} else {
+		return clk_register_divider_table(NULL, name, parent_name, 0,
+						  cpg->reg + reg, shift, 4, 0,
+						  table, &cpg->lock);
+	}
+}
+
+static void __init r8a73a4_cpg_clocks_init(struct device_node *np)
+{
+	struct r8a73a4_cpg *cpg;
+	struct clk **clks;
+	unsigned int i;
+	int num_clks;
+
+	num_clks = of_property_count_strings(np, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks\n", __func__);
+		return;
+	}
+
+	cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+	clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL);
+	if (cpg == NULL || clks == NULL) {
+		/* We're leaking memory on purpose, there's no point in cleaning
+		 * up as the system won't boot anyway.
+		 */
+		return;
+	}
+
+	spin_lock_init(&cpg->lock);
+
+	cpg->data.clks = clks;
+	cpg->data.clk_num = num_clks;
+
+	cpg->reg = of_iomap(np, 0);
+	if (WARN_ON(cpg->reg == NULL))
+		return;
+
+	for (i = 0; i < num_clks; ++i) {
+		const char *name;
+		struct clk *clk;
+
+		of_property_read_string_index(np, "clock-output-names", i,
+					      &name);
+
+		clk = r8a73a4_cpg_register_clock(np, cpg, name);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clk));
+		else
+			cpg->data.clks[i] = clk;
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(r8a73a4_cpg_clks, "renesas,r8a73a4-cpg-clocks",
+	       r8a73a4_cpg_clocks_init);

+ 88 - 0
drivers/clk/shmobile/clk-rcar-gen2.c

@@ -33,6 +33,8 @@ struct rcar_gen2_cpg {
 #define CPG_FRQCRC			0x000000e0
 #define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
 #define CPG_FRQCRC_ZFC_SHIFT		8
+#define CPG_ADSPCKCR			0x0000025c
+#define CPG_RCANCKCR			0x00000270
 
 /* -----------------------------------------------------------------------------
  * Z Clock
@@ -161,6 +163,88 @@ static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
 	return clk;
 }
 
+static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg,
+						 struct device_node *np)
+{
+	const char *parent_name = of_clk_get_parent_name(np, 1);
+	struct clk_fixed_factor *fixed;
+	struct clk_gate *gate;
+	struct clk *clk;
+
+	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return ERR_PTR(-ENOMEM);
+
+	fixed->mult = 1;
+	fixed->div = 6;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(fixed);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = cpg->reg + CPG_RCANCKCR;
+	gate->bit_idx = 8;
+	gate->flags = CLK_GATE_SET_TO_DISABLE;
+	gate->lock = &cpg->lock;
+
+	clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL,
+				     &fixed->hw, &clk_fixed_factor_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(gate);
+		kfree(fixed);
+	}
+
+	return clk;
+}
+
+/* ADSP divisors */
+static const struct clk_div_table cpg_adsp_div_table[] = {
+	{  1,  3 }, {  2,  4 }, {  3,  6 }, {  4,  8 },
+	{  5, 12 }, {  6, 16 }, {  7, 18 }, {  8, 24 },
+	{ 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg)
+{
+	const char *parent_name = "pll1";
+	struct clk_divider *div;
+	struct clk_gate *gate;
+	struct clk *clk;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->reg = cpg->reg + CPG_ADSPCKCR;
+	div->width = 4;
+	div->table = cpg_adsp_div_table;
+	div->lock = &cpg->lock;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(div);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = cpg->reg + CPG_ADSPCKCR;
+	gate->bit_idx = 8;
+	gate->flags = CLK_GATE_SET_TO_DISABLE;
+	gate->lock = &cpg->lock;
+
+	clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL,
+				     &div->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(gate);
+		kfree(div);
+	}
+
+	return clk;
+}
+
 /* -----------------------------------------------------------------------------
  * CPG Clock Data
  */
@@ -263,6 +347,10 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
 		shift = 0;
 	} else if (!strcmp(name, "z")) {
 		return cpg_z_clk_register(cpg);
+	} else if (!strcmp(name, "rcan")) {
+		return cpg_rcan_clk_register(cpg, np);
+	} else if (!strcmp(name, "adsp")) {
+		return cpg_adsp_clk_register(cpg);
 	} else {
 		return ERR_PTR(-EINVAL);
 	}

+ 25 - 14
drivers/clk/st/clk-flexgen.c

@@ -37,8 +37,8 @@ static int flexgen_enable(struct clk_hw *hw)
 	struct clk_hw *pgate_hw = &flexgen->pgate.hw;
 	struct clk_hw *fgate_hw = &flexgen->fgate.hw;
 
-	pgate_hw->clk = hw->clk;
-	fgate_hw->clk = hw->clk;
+	__clk_hw_set_clk(pgate_hw, hw);
+	__clk_hw_set_clk(fgate_hw, hw);
 
 	clk_gate_ops.enable(pgate_hw);
 
@@ -54,7 +54,7 @@ static void flexgen_disable(struct clk_hw *hw)
 	struct clk_hw *fgate_hw = &flexgen->fgate.hw;
 
 	/* disable only the final gate */
-	fgate_hw->clk = hw->clk;
+	__clk_hw_set_clk(fgate_hw, hw);
 
 	clk_gate_ops.disable(fgate_hw);
 
@@ -66,7 +66,7 @@ static int flexgen_is_enabled(struct clk_hw *hw)
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct clk_hw *fgate_hw = &flexgen->fgate.hw;
 
-	fgate_hw->clk = hw->clk;
+	__clk_hw_set_clk(fgate_hw, hw);
 
 	if (!clk_gate_ops.is_enabled(fgate_hw))
 		return 0;
@@ -79,7 +79,7 @@ static u8 flexgen_get_parent(struct clk_hw *hw)
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct clk_hw *mux_hw = &flexgen->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return clk_mux_ops.get_parent(mux_hw);
 }
@@ -89,7 +89,7 @@ static int flexgen_set_parent(struct clk_hw *hw, u8 index)
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct clk_hw *mux_hw = &flexgen->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return clk_mux_ops.set_parent(mux_hw, index);
 }
@@ -124,8 +124,8 @@ unsigned long flexgen_recalc_rate(struct clk_hw *hw,
 	struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
 	unsigned long mid_rate;
 
-	pdiv_hw->clk = hw->clk;
-	fdiv_hw->clk = hw->clk;
+	__clk_hw_set_clk(pdiv_hw, hw);
+	__clk_hw_set_clk(fdiv_hw, hw);
 
 	mid_rate = clk_divider_ops.recalc_rate(pdiv_hw, parent_rate);
 
@@ -138,16 +138,27 @@ static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
 	struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
-	unsigned long primary_div = 0;
+	unsigned long div = 0;
 	int ret = 0;
 
-	pdiv_hw->clk = hw->clk;
-	fdiv_hw->clk = hw->clk;
+	__clk_hw_set_clk(pdiv_hw, hw);
+	__clk_hw_set_clk(fdiv_hw, hw);
 
-	primary_div = clk_best_div(parent_rate, rate);
+	div = clk_best_div(parent_rate, rate);
 
-	clk_divider_ops.set_rate(fdiv_hw, parent_rate, parent_rate);
-	ret = clk_divider_ops.set_rate(pdiv_hw, rate, rate * primary_div);
+	/*
+	* pdiv is mainly targeted for low freq results, while fdiv
+	* should be used for div <= 64. The other way round can
+	* lead to 'duty cycle' issues.
+	*/
+
+	if (div <= 64) {
+		clk_divider_ops.set_rate(pdiv_hw, parent_rate, parent_rate);
+		ret = clk_divider_ops.set_rate(fdiv_hw, rate, rate * div);
+	} else {
+		clk_divider_ops.set_rate(fdiv_hw, parent_rate, parent_rate);
+		ret = clk_divider_ops.set_rate(pdiv_hw, rate, rate * div);
+	}
 
 	return ret;
 }

+ 7 - 7
drivers/clk/st/clkgen-mux.c

@@ -94,7 +94,7 @@ static int clkgena_divmux_enable(struct clk_hw *hw)
 	unsigned long timeout;
 	int ret = 0;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	ret = clk_mux_ops.set_parent(mux_hw, genamux->muxsel);
 	if (ret)
@@ -116,7 +116,7 @@ static void clkgena_divmux_disable(struct clk_hw *hw)
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *mux_hw = &genamux->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	clk_mux_ops.set_parent(mux_hw, CKGAX_CLKOPSRC_SWITCH_OFF);
 }
@@ -126,7 +126,7 @@ static int clkgena_divmux_is_enabled(struct clk_hw *hw)
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *mux_hw = &genamux->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return (s8)clk_mux_ops.get_parent(mux_hw) > 0;
 }
@@ -136,7 +136,7 @@ u8 clkgena_divmux_get_parent(struct clk_hw *hw)
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *mux_hw = &genamux->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	genamux->muxsel = clk_mux_ops.get_parent(mux_hw);
 	if ((s8)genamux->muxsel < 0) {
@@ -174,7 +174,7 @@ unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw,
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return clk_divider_ops.recalc_rate(div_hw, parent_rate);
 }
@@ -185,7 +185,7 @@ static int clkgena_divmux_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return clk_divider_ops.set_rate(div_hw, rate, parent_rate);
 }
@@ -196,7 +196,7 @@ static long clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long rate,
 	struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
 	struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return clk_divider_ops.round_rate(div_hw, rate, prate);
 }

+ 1 - 0
drivers/clk/sunxi/Makefile

@@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun9i-core.o
+obj-y += clk-sun9i-mmc.o
 
 obj-$(CONFIG_MFD_SUN6I_PRCM) += \
 	clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \

+ 6 - 6
drivers/clk/sunxi/clk-factors.c

@@ -80,6 +80,8 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
 }
 
 static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long min_rate,
+				       unsigned long max_rate,
 				       unsigned long *best_parent_rate,
 				       struct clk_hw **best_parent_p)
 {
@@ -156,9 +158,10 @@ static const struct clk_ops clk_factors_ops = {
 	.set_rate = clk_factors_set_rate,
 };
 
-struct clk * __init sunxi_factors_register(struct device_node *node,
-					   const struct factors_data *data,
-					   spinlock_t *lock)
+struct clk *sunxi_factors_register(struct device_node *node,
+				   const struct factors_data *data,
+				   spinlock_t *lock,
+				   void __iomem *reg)
 {
 	struct clk *clk;
 	struct clk_factors *factors;
@@ -168,11 +171,8 @@ struct clk * __init sunxi_factors_register(struct device_node *node,
 	struct clk_hw *mux_hw = NULL;
 	const char *clk_name = node->name;
 	const char *parents[FACTORS_MAX_PARENTS];
-	void __iomem *reg;
 	int i = 0;
 
-	reg = of_iomap(node, 0);
-
 	/* if we have a mux, we will have >1 parents */
 	while (i < FACTORS_MAX_PARENTS &&
 	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)

+ 4 - 3
drivers/clk/sunxi/clk-factors.h

@@ -36,8 +36,9 @@ struct clk_factors {
 	spinlock_t *lock;
 };
 
-struct clk * __init sunxi_factors_register(struct device_node *node,
-					   const struct factors_data *data,
-					   spinlock_t *lock);
+struct clk *sunxi_factors_register(struct device_node *node,
+				   const struct factors_data *data,
+				   spinlock_t *lock,
+				   void __iomem *reg);
 
 #endif

+ 166 - 58
drivers/clk/sunxi/clk-mod0.c

@@ -17,6 +17,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 
 #include "clk-factors.h"
 
@@ -67,7 +68,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = {
 	.pwidth = 2,
 };
 
-static const struct factors_data sun4i_a10_mod0_data __initconst = {
+static const struct factors_data sun4i_a10_mod0_data = {
 	.enable = 31,
 	.mux = 24,
 	.muxmask = BIT(1) | BIT(0),
@@ -79,15 +80,95 @@ static DEFINE_SPINLOCK(sun4i_a10_mod0_lock);
 
 static void __init sun4i_a10_mod0_setup(struct device_node *node)
 {
-	sunxi_factors_register(node, &sun4i_a10_mod0_data, &sun4i_a10_mod0_lock);
+	void __iomem *reg;
+
+	reg = of_iomap(node, 0);
+	if (!reg) {
+		/*
+		 * This happens with mod0 clk nodes instantiated through
+		 * mfd, as those do not have their resources assigned at
+		 * CLK_OF_DECLARE time yet, so do not print an error.
+		 */
+		return;
+	}
+
+	sunxi_factors_register(node, &sun4i_a10_mod0_data,
+			       &sun4i_a10_mod0_lock, reg);
 }
 CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);
 
+static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	void __iomem *reg;
+
+	if (!np)
+		return -ENODEV;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	reg = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	sunxi_factors_register(np, &sun4i_a10_mod0_data,
+			       &sun4i_a10_mod0_lock, reg);
+	return 0;
+}
+
+static const struct of_device_id sun4i_a10_mod0_clk_dt_ids[] = {
+	{ .compatible = "allwinner,sun4i-a10-mod0-clk" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver sun4i_a10_mod0_clk_driver = {
+	.driver = {
+		.name = "sun4i-a10-mod0-clk",
+		.of_match_table = sun4i_a10_mod0_clk_dt_ids,
+	},
+	.probe = sun4i_a10_mod0_clk_probe,
+};
+module_platform_driver(sun4i_a10_mod0_clk_driver);
+
+static const struct factors_data sun9i_a80_mod0_data __initconst = {
+	.enable = 31,
+	.mux = 24,
+	.muxmask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
+	.table = &sun4i_a10_mod0_config,
+	.getter = sun4i_a10_get_mod0_factors,
+};
+
+static void __init sun9i_a80_mod0_setup(struct device_node *node)
+{
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("Could not get registers for mod0-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_mod0_data,
+			       &sun4i_a10_mod0_lock, reg);
+}
+CLK_OF_DECLARE(sun9i_a80_mod0, "allwinner,sun9i-a80-mod0-clk", sun9i_a80_mod0_setup);
+
 static DEFINE_SPINLOCK(sun5i_a13_mbus_lock);
 
 static void __init sun5i_a13_mbus_setup(struct device_node *node)
 {
-	struct clk *mbus = sunxi_factors_register(node, &sun4i_a10_mod0_data, &sun5i_a13_mbus_lock);
+	struct clk *mbus;
+	void __iomem *reg;
+
+	reg = of_iomap(node, 0);
+	if (!reg) {
+		pr_err("Could not get registers for a13-mbus-clk\n");
+		return;
+	}
+
+	mbus = sunxi_factors_register(node, &sun4i_a10_mod0_data,
+				      &sun5i_a13_mbus_lock, reg);
 
 	/* The MBUS clocks needs to be always enabled */
 	__clk_get(mbus);
@@ -95,14 +176,10 @@ static void __init sun5i_a13_mbus_setup(struct device_node *node)
 }
 CLK_OF_DECLARE(sun5i_a13_mbus, "allwinner,sun5i-a13-mbus-clk", sun5i_a13_mbus_setup);
 
-struct mmc_phase_data {
-	u8	offset;
-};
-
 struct mmc_phase {
 	struct clk_hw		hw;
+	u8			offset;
 	void __iomem		*reg;
-	struct mmc_phase_data	*data;
 	spinlock_t		*lock;
 };
 
@@ -118,7 +195,7 @@ static int mmc_get_phase(struct clk_hw *hw)
 	u8 delay;
 
 	value = readl(phase->reg);
-	delay = (value >> phase->data->offset) & 0x3;
+	delay = (value >> phase->offset) & 0x3;
 
 	if (!delay)
 		return 180;
@@ -206,8 +283,8 @@ static int mmc_set_phase(struct clk_hw *hw, int degrees)
 
 	spin_lock_irqsave(phase->lock, flags);
 	value = readl(phase->reg);
-	value &= ~GENMASK(phase->data->offset + 3, phase->data->offset);
-	value |= delay << phase->data->offset;
+	value &= ~GENMASK(phase->offset + 3, phase->offset);
+	value |= delay << phase->offset;
 	writel(value, phase->reg);
 	spin_unlock_irqrestore(phase->lock, flags);
 
@@ -219,66 +296,97 @@ static const struct clk_ops mmc_clk_ops = {
 	.set_phase	= mmc_set_phase,
 };
 
-static void __init sun4i_a10_mmc_phase_setup(struct device_node *node,
-					     struct mmc_phase_data *data)
+/*
+ * sunxi_mmc_setup - Common setup function for mmc module clocks
+ *
+ * The only difference between module clocks on different platforms is the
+ * width of the mux register bits and the valid values, which are passed in
+ * through struct factors_data. The phase clocks parts are identical.
+ */
+static void __init sunxi_mmc_setup(struct device_node *node,
+				   const struct factors_data *data,
+				   spinlock_t *lock)
 {
-	const char *parent_names[1] = { of_clk_get_parent_name(node, 0) };
-	struct clk_init_data init = {
-		.num_parents	= 1,
-		.parent_names	= parent_names,
-		.ops		= &mmc_clk_ops,
-	};
-
-	struct mmc_phase *phase;
-	struct clk *clk;
-
-	phase = kmalloc(sizeof(*phase), GFP_KERNEL);
-	if (!phase)
+	struct clk_onecell_data *clk_data;
+	const char *parent;
+	void __iomem *reg;
+	int i;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("Couldn't map the %s clock registers\n", node->name);
 		return;
+	}
 
-	phase->hw.init = &init;
-
-	phase->reg = of_iomap(node, 0);
-	if (!phase->reg)
-		goto err_free;
-
-	phase->data = data;
-	phase->lock = &sun4i_a10_mod0_lock;
-
-	if (of_property_read_string(node, "clock-output-names", &init.name))
-		init.name = node->name;
+	clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL);
+	if (!clk_data)
+		return;
 
-	clk = clk_register(NULL, &phase->hw);
-	if (IS_ERR(clk))
-		goto err_unmap;
+	clk_data->clks = kcalloc(3, sizeof(*clk_data->clks), GFP_KERNEL);
+	if (!clk_data->clks)
+		goto err_free_data;
+
+	clk_data->clk_num = 3;
+	clk_data->clks[0] = sunxi_factors_register(node, data, lock, reg);
+	if (!clk_data->clks[0])
+		goto err_free_clks;
+
+	parent = __clk_get_name(clk_data->clks[0]);
+
+	for (i = 1; i < 3; i++) {
+		struct clk_init_data init = {
+			.num_parents	= 1,
+			.parent_names	= &parent,
+			.ops		= &mmc_clk_ops,
+		};
+		struct mmc_phase *phase;
+
+		phase = kmalloc(sizeof(*phase), GFP_KERNEL);
+		if (!phase)
+			continue;
+
+		phase->hw.init = &init;
+		phase->reg = reg;
+		phase->lock = lock;
+
+		if (i == 1)
+			phase->offset = 8;
+		else
+			phase->offset = 20;
+
+		if (of_property_read_string_index(node, "clock-output-names",
+						  i, &init.name))
+			init.name = node->name;
+
+		clk_data->clks[i] = clk_register(NULL, &phase->hw);
+		if (IS_ERR(clk_data->clks[i])) {
+			kfree(phase);
+			continue;
+		}
+	}
 
-	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 
 	return;
 
-err_unmap:
-	iounmap(phase->reg);
-err_free:
-	kfree(phase);
+err_free_clks:
+	kfree(clk_data->clks);
+err_free_data:
+	kfree(clk_data);
 }
 
+static DEFINE_SPINLOCK(sun4i_a10_mmc_lock);
 
-static struct mmc_phase_data mmc_output_clk = {
-	.offset	= 8,
-};
-
-static struct mmc_phase_data mmc_sample_clk = {
-	.offset	= 20,
-};
-
-static void __init sun4i_a10_mmc_output_setup(struct device_node *node)
+static void __init sun4i_a10_mmc_setup(struct device_node *node)
 {
-	sun4i_a10_mmc_phase_setup(node, &mmc_output_clk);
+	sunxi_mmc_setup(node, &sun4i_a10_mod0_data, &sun4i_a10_mmc_lock);
 }
-CLK_OF_DECLARE(sun4i_a10_mmc_output, "allwinner,sun4i-a10-mmc-output-clk", sun4i_a10_mmc_output_setup);
+CLK_OF_DECLARE(sun4i_a10_mmc, "allwinner,sun4i-a10-mmc-clk", sun4i_a10_mmc_setup);
+
+static DEFINE_SPINLOCK(sun9i_a80_mmc_lock);
 
-static void __init sun4i_a10_mmc_sample_setup(struct device_node *node)
+static void __init sun9i_a80_mmc_setup(struct device_node *node)
 {
-	sun4i_a10_mmc_phase_setup(node, &mmc_sample_clk);
+	sunxi_mmc_setup(node, &sun9i_a80_mod0_data, &sun9i_a80_mmc_lock);
 }
-CLK_OF_DECLARE(sun4i_a10_mmc_sample, "allwinner,sun4i-a10-mmc-sample-clk", sun4i_a10_mmc_sample_setup);
+CLK_OF_DECLARE(sun9i_a80_mmc, "allwinner,sun9i-a80-mmc-clk", sun9i_a80_mmc_setup);

+ 2 - 0
drivers/clk/sunxi/clk-sun6i-ar100.c

@@ -45,6 +45,8 @@ static unsigned long ar100_recalc_rate(struct clk_hw *hw,
 }
 
 static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long min_rate,
+				 unsigned long max_rate,
 				 unsigned long *best_parent_rate,
 				 struct clk_hw **best_parent_clk)
 {

+ 11 - 2
drivers/clk/sunxi/clk-sun8i-mbus.c

@@ -69,8 +69,17 @@ static DEFINE_SPINLOCK(sun8i_a23_mbus_lock);
 
 static void __init sun8i_a23_mbus_setup(struct device_node *node)
 {
-	struct clk *mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data,
-						  &sun8i_a23_mbus_lock);
+	struct clk *mbus;
+	void __iomem *reg;
+
+	reg = of_iomap(node, 0);
+	if (!reg) {
+		pr_err("Could not get registers for a23-mbus-clk\n");
+		return;
+	}
+
+	mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data,
+				      &sun8i_a23_mbus_lock, reg);
 
 	/* The MBUS clocks needs to be always enabled */
 	__clk_get(mbus);

+ 85 - 34
drivers/clk/sunxi/clk-sun9i-core.c

@@ -24,50 +24,51 @@
 
 
 /**
- * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1
+ * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL4
  * PLL4 rate is calculated as follows
  * rate = (parent_rate * n >> p) / (m + 1);
- * parent_rate is always 24Mhz
+ * parent_rate is always 24MHz
  *
  * p and m are named div1 and div2 in Allwinner's SDK
  */
 
 static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
-				       u8 *n, u8 *k, u8 *m, u8 *p)
+				       u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret)
 {
-	int div;
+	int n;
+	int m = 1;
+	int p = 1;
 
-	/* Normalize value to a 6M multiple */
-	div = DIV_ROUND_UP(*freq, 6000000);
+	/* Normalize value to a 6 MHz multiple (24 MHz / 4) */
+	n = DIV_ROUND_UP(*freq, 6000000);
 
-	/* divs above 256 cannot be odd */
-	if (div > 256)
-		div = round_up(div, 2);
+	/* If n is too large switch to steps of 12 MHz */
+	if (n > 255) {
+		m = 0;
+		n = (n + 1) / 2;
+	}
+
+	/* If n is still too large switch to steps of 24 MHz */
+	if (n > 255) {
+		p = 0;
+		n = (n + 1) / 2;
+	}
 
-	/* divs above 512 must be a multiple of 4 */
-	if (div > 512)
-		div = round_up(div, 4);
+	/* n must be between 12 and 255 */
+	if (n > 255)
+		n = 255;
+	else if (n < 12)
+		n = 12;
 
-	*freq = 6000000 * div;
+	*freq = ((24000000 * n) >> p) / (m + 1);
 
 	/* we were called to round the frequency, we can now return */
-	if (n == NULL)
+	if (n_ret == NULL)
 		return;
 
-	/* p will be 1 for divs under 512 */
-	if (div < 512)
-		*p = 1;
-	else
-		*p = 0;
-
-	/* m will be 1 if div is odd */
-	if (div & 1)
-		*m = 1;
-	else
-		*m = 0;
-
-	/* calculate a suitable n based on m and p */
-	*n = div / (*p + 1) / (*m + 1);
+	*n_ret = n;
+	*m_ret = m;
+	*p_ret = p;
 }
 
 static struct clk_factors_config sun9i_a80_pll4_config = {
@@ -89,7 +90,17 @@ static DEFINE_SPINLOCK(sun9i_a80_pll4_lock);
 
 static void __init sun9i_a80_pll4_setup(struct device_node *node)
 {
-	sunxi_factors_register(node, &sun9i_a80_pll4_data, &sun9i_a80_pll4_lock);
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for a80-pll4-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_pll4_data,
+			       &sun9i_a80_pll4_lock, reg);
 }
 CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_setup);
 
@@ -139,8 +150,18 @@ static DEFINE_SPINLOCK(sun9i_a80_gt_lock);
 
 static void __init sun9i_a80_gt_setup(struct device_node *node)
 {
-	struct clk *gt = sunxi_factors_register(node, &sun9i_a80_gt_data,
-						&sun9i_a80_gt_lock);
+	void __iomem *reg;
+	struct clk *gt;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for a80-gt-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	gt = sunxi_factors_register(node, &sun9i_a80_gt_data,
+				    &sun9i_a80_gt_lock, reg);
 
 	/* The GT bus clock needs to be always enabled */
 	__clk_get(gt);
@@ -194,7 +215,17 @@ static DEFINE_SPINLOCK(sun9i_a80_ahb_lock);
 
 static void __init sun9i_a80_ahb_setup(struct device_node *node)
 {
-	sunxi_factors_register(node, &sun9i_a80_ahb_data, &sun9i_a80_ahb_lock);
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for a80-ahb-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_ahb_data,
+			       &sun9i_a80_ahb_lock, reg);
 }
 CLK_OF_DECLARE(sun9i_a80_ahb, "allwinner,sun9i-a80-ahb-clk", sun9i_a80_ahb_setup);
 
@@ -210,7 +241,17 @@ static DEFINE_SPINLOCK(sun9i_a80_apb0_lock);
 
 static void __init sun9i_a80_apb0_setup(struct device_node *node)
 {
-	sunxi_factors_register(node, &sun9i_a80_apb0_data, &sun9i_a80_apb0_lock);
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for a80-apb0-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_apb0_data,
+			       &sun9i_a80_apb0_lock, reg);
 }
 CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_setup);
 
@@ -266,6 +307,16 @@ static DEFINE_SPINLOCK(sun9i_a80_apb1_lock);
 
 static void __init sun9i_a80_apb1_setup(struct device_node *node)
 {
-	sunxi_factors_register(node, &sun9i_a80_apb1_data, &sun9i_a80_apb1_lock);
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (!reg) {
+		pr_err("Could not get registers for a80-apb1-clk: %s\n",
+		       node->name);
+		return;
+	}
+
+	sunxi_factors_register(node, &sun9i_a80_apb1_data,
+			       &sun9i_a80_apb1_lock, reg);
 }
 CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-clk", sun9i_a80_apb1_setup);

+ 219 - 0
drivers/clk/sunxi/clk-sun9i-mmc.c

@@ -0,0 +1,219 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai	<wens@csie.org>
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+#define SUN9I_MMC_WIDTH		4
+
+#define SUN9I_MMC_GATE_BIT	16
+#define SUN9I_MMC_RESET_BIT	18
+
+struct sun9i_mmc_clk_data {
+	spinlock_t			lock;
+	void __iomem			*membase;
+	struct clk			*clk;
+	struct reset_control		*reset;
+	struct clk_onecell_data		clk_data;
+	struct reset_controller_dev	rcdev;
+};
+
+static int sun9i_mmc_reset_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct sun9i_mmc_clk_data *data = container_of(rcdev,
+						       struct sun9i_mmc_clk_data,
+						       rcdev);
+	unsigned long flags;
+	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
+	u32 val;
+
+	clk_prepare_enable(data->clk);
+	spin_lock_irqsave(&data->lock, flags);
+
+	val = readl(reg);
+	writel(val & ~BIT(SUN9I_MMC_RESET_BIT), reg);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct sun9i_mmc_clk_data *data = container_of(rcdev,
+						       struct sun9i_mmc_clk_data,
+						       rcdev);
+	unsigned long flags;
+	void __iomem *reg = data->membase + SUN9I_MMC_WIDTH * id;
+	u32 val;
+
+	clk_prepare_enable(data->clk);
+	spin_lock_irqsave(&data->lock, flags);
+
+	val = readl(reg);
+	writel(val | BIT(SUN9I_MMC_RESET_BIT), reg);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+static struct reset_control_ops sun9i_mmc_reset_ops = {
+	.assert		= sun9i_mmc_reset_assert,
+	.deassert	= sun9i_mmc_reset_deassert,
+};
+
+static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sun9i_mmc_clk_data *data;
+	struct clk_onecell_data *clk_data;
+	const char *clk_name = np->name;
+	const char *clk_parent;
+	struct resource *r;
+	int count, i, ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&data->lock);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* one clock/reset pair per word */
+	count = DIV_ROUND_UP((r->end - r->start + 1), SUN9I_MMC_WIDTH);
+	data->membase = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(data->membase))
+		return PTR_ERR(data->membase);
+
+	clk_data = &data->clk_data;
+	clk_data->clk_num = count;
+	clk_data->clks = devm_kcalloc(&pdev->dev, count, sizeof(struct clk *),
+				      GFP_KERNEL);
+	if (!clk_data->clks)
+		return -ENOMEM;
+
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		dev_err(&pdev->dev, "Could not get clock\n");
+		return PTR_ERR(data->clk);
+	}
+
+	data->reset = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(data->reset)) {
+		dev_err(&pdev->dev, "Could not get reset control\n");
+		return PTR_ERR(data->reset);
+	}
+
+	ret = reset_control_deassert(data->reset);
+	if (ret) {
+		dev_err(&pdev->dev, "Reset deassert err %d\n", ret);
+		return ret;
+	}
+
+	clk_parent = __clk_get_name(data->clk);
+	for (i = 0; i < count; i++) {
+		of_property_read_string_index(np, "clock-output-names",
+					      i, &clk_name);
+
+		clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
+						      clk_parent, 0,
+						      data->membase + SUN9I_MMC_WIDTH * i,
+						      SUN9I_MMC_GATE_BIT, 0,
+						      &data->lock);
+
+		if (IS_ERR(clk_data->clks[i])) {
+			ret = PTR_ERR(clk_data->clks[i]);
+			goto err_clk_register;
+		}
+	}
+
+	ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+	if (ret)
+		goto err_clk_provider;
+
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = count;
+	data->rcdev.ops = &sun9i_mmc_reset_ops;
+	data->rcdev.of_node = pdev->dev.of_node;
+
+	ret = reset_controller_register(&data->rcdev);
+	if (ret)
+		goto err_rc_reg;
+
+	platform_set_drvdata(pdev, data);
+
+	return 0;
+
+err_rc_reg:
+	of_clk_del_provider(np);
+
+err_clk_provider:
+	for (i = 0; i < count; i++)
+		clk_unregister(clk_data->clks[i]);
+
+err_clk_register:
+	reset_control_assert(data->reset);
+
+	return ret;
+}
+
+static int sun9i_a80_mmc_config_clk_remove(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sun9i_mmc_clk_data *data = platform_get_drvdata(pdev);
+	struct clk_onecell_data *clk_data = &data->clk_data;
+	int i;
+
+	reset_controller_unregister(&data->rcdev);
+	of_clk_del_provider(np);
+	for (i = 0; i < clk_data->clk_num; i++)
+		clk_unregister(clk_data->clks[i]);
+
+	reset_control_assert(data->reset);
+
+	return 0;
+}
+
+static const struct of_device_id sun9i_a80_mmc_config_clk_dt_ids[] = {
+	{ .compatible = "allwinner,sun9i-a80-mmc-config-clk" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver sun9i_a80_mmc_config_clk_driver = {
+	.driver = {
+		.name = "sun9i-a80-mmc-config-clk",
+		.of_match_table = sun9i_a80_mmc_config_clk_dt_ids,
+	},
+	.probe = sun9i_a80_mmc_config_clk_probe,
+	.remove = sun9i_a80_mmc_config_clk_remove,
+};
+module_platform_driver(sun9i_a80_mmc_config_clk_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_DESCRIPTION("Allwinner A80 MMC clock/reset Driver");
+MODULE_LICENSE("GPL v2");

+ 222 - 40
drivers/clk/sunxi/clk-sunxi.c

@@ -20,11 +20,221 @@
 #include <linux/of_address.h>
 #include <linux/reset-controller.h>
 #include <linux/spinlock.h>
+#include <linux/log2.h>
 
 #include "clk-factors.h"
 
 static DEFINE_SPINLOCK(clk_lock);
 
+/**
+ * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk
+ */
+
+#define SUN6I_AHB1_MAX_PARENTS		4
+#define SUN6I_AHB1_MUX_PARENT_PLL6	3
+#define SUN6I_AHB1_MUX_SHIFT		12
+/* un-shifted mask is what mux_clk expects */
+#define SUN6I_AHB1_MUX_MASK		0x3
+#define SUN6I_AHB1_MUX_GET_PARENT(reg)	((reg >> SUN6I_AHB1_MUX_SHIFT) & \
+					 SUN6I_AHB1_MUX_MASK)
+
+#define SUN6I_AHB1_DIV_SHIFT		4
+#define SUN6I_AHB1_DIV_MASK		(0x3 << SUN6I_AHB1_DIV_SHIFT)
+#define SUN6I_AHB1_DIV_GET(reg)		((reg & SUN6I_AHB1_DIV_MASK) >> \
+						SUN6I_AHB1_DIV_SHIFT)
+#define SUN6I_AHB1_DIV_SET(reg, div)	((reg & ~SUN6I_AHB1_DIV_MASK) | \
+						(div << SUN6I_AHB1_DIV_SHIFT))
+#define SUN6I_AHB1_PLL6_DIV_SHIFT	6
+#define SUN6I_AHB1_PLL6_DIV_MASK	(0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT)
+#define SUN6I_AHB1_PLL6_DIV_GET(reg)	((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \
+						SUN6I_AHB1_PLL6_DIV_SHIFT)
+#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \
+						(div << SUN6I_AHB1_PLL6_DIV_SHIFT))
+
+struct sun6i_ahb1_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+
+#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw)
+
+static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
+	unsigned long rate;
+	u32 reg;
+
+	/* Fetch the register value */
+	reg = readl(ahb1->reg);
+
+	/* apply pre-divider first if parent is pll6 */
+	if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6)
+		parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1;
+
+	/* clk divider */
+	rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg);
+
+	return rate;
+}
+
+static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp,
+				 u8 parent, unsigned long parent_rate)
+{
+	u8 div, calcp, calcm = 1;
+
+	/*
+	 * clock can only divide, so we will never be able to achieve
+	 * frequencies higher than the parent frequency
+	 */
+	if (parent_rate && rate > parent_rate)
+		rate = parent_rate;
+
+	div = DIV_ROUND_UP(parent_rate, rate);
+
+	/* calculate pre-divider if parent is pll6 */
+	if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) {
+		if (div < 4)
+			calcp = 0;
+		else if (div / 2 < 4)
+			calcp = 1;
+		else if (div / 4 < 4)
+			calcp = 2;
+		else
+			calcp = 3;
+
+		calcm = DIV_ROUND_UP(div, 1 << calcp);
+	} else {
+		calcp = __roundup_pow_of_two(div);
+		calcp = calcp > 3 ? 3 : calcp;
+	}
+
+	/* we were asked to pass back divider values */
+	if (divp) {
+		*divp = calcp;
+		*pre_divp = calcm - 1;
+	}
+
+	return (parent_rate / calcm) >> calcp;
+}
+
+static long sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+					  unsigned long min_rate,
+					  unsigned long max_rate,
+					  unsigned long *best_parent_rate,
+					  struct clk_hw **best_parent_clk)
+{
+	struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+	int i, num_parents;
+	unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
+
+	/* find the parent that can help provide the fastest rate <= rate */
+	num_parents = __clk_get_num_parents(clk);
+	for (i = 0; i < num_parents; i++) {
+		parent = clk_get_parent_by_index(clk, i);
+		if (!parent)
+			continue;
+		if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
+			parent_rate = __clk_round_rate(parent, rate);
+		else
+			parent_rate = __clk_get_rate(parent);
+
+		child_rate = sun6i_ahb1_clk_round(rate, NULL, NULL, i,
+						  parent_rate);
+
+		if (child_rate <= rate && child_rate > best_child_rate) {
+			best_parent = parent;
+			best = parent_rate;
+			best_child_rate = child_rate;
+		}
+	}
+
+	if (best_parent)
+		*best_parent_clk = __clk_get_hw(best_parent);
+	*best_parent_rate = best;
+
+	return best_child_rate;
+}
+
+static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
+	unsigned long flags;
+	u8 div, pre_div, parent;
+	u32 reg;
+
+	spin_lock_irqsave(&clk_lock, flags);
+
+	reg = readl(ahb1->reg);
+
+	/* need to know which parent is used to apply pre-divider */
+	parent = SUN6I_AHB1_MUX_GET_PARENT(reg);
+	sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate);
+
+	reg = SUN6I_AHB1_DIV_SET(reg, div);
+	reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div);
+	writel(reg, ahb1->reg);
+
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops sun6i_ahb1_clk_ops = {
+	.determine_rate	= sun6i_ahb1_clk_determine_rate,
+	.recalc_rate	= sun6i_ahb1_clk_recalc_rate,
+	.set_rate	= sun6i_ahb1_clk_set_rate,
+};
+
+static void __init sun6i_ahb1_clk_setup(struct device_node *node)
+{
+	struct clk *clk;
+	struct sun6i_ahb1_clk *ahb1;
+	struct clk_mux *mux;
+	const char *clk_name = node->name;
+	const char *parents[SUN6I_AHB1_MAX_PARENTS];
+	void __iomem *reg;
+	int i = 0;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+
+	/* we have a mux, we will have >1 parents */
+	while (i < SUN6I_AHB1_MAX_PARENTS &&
+	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+		i++;
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL);
+	if (!ahb1)
+		return;
+
+	mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+	if (!mux) {
+		kfree(ahb1);
+		return;
+	}
+
+	/* set up clock properties */
+	mux->reg = reg;
+	mux->shift = SUN6I_AHB1_MUX_SHIFT;
+	mux->mask = SUN6I_AHB1_MUX_MASK;
+	mux->lock = &clk_lock;
+	ahb1->reg = reg;
+
+	clk = clk_register_composite(NULL, clk_name, parents, i,
+				     &mux->hw, &clk_mux_ops,
+				     &ahb1->hw, &sun6i_ahb1_clk_ops,
+				     NULL, NULL, 0);
+
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+		clk_register_clkdev(clk, clk_name, NULL);
+	}
+}
+CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup);
+
 /* Maximum number of parents our clocks have */
 #define SUNXI_MAX_PARENTS	5
 
@@ -354,43 +564,6 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
 	*p = calcp;
 }
 
-/**
- * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
- */
-
-void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output)
-{
-	#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
-	#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
-
-	struct clk_hw *hw = __clk_get_hw(clk);
-	struct clk_composite *composite = to_clk_composite(hw);
-	struct clk_hw *rate_hw = composite->rate_hw;
-	struct clk_factors *factors = to_clk_factors(rate_hw);
-	unsigned long flags = 0;
-	u32 reg;
-
-	if (factors->lock)
-		spin_lock_irqsave(factors->lock, flags);
-
-	reg = readl(factors->reg);
-
-	/* set sample clock phase control */
-	reg &= ~(0x7 << 20);
-	reg |= ((sample & 0x7) << 20);
-
-	/* set output clock phase control */
-	reg &= ~(0x7 << 8);
-	reg |= ((output & 0x7) << 8);
-
-	writel(reg, factors->reg);
-
-	if (factors->lock)
-		spin_unlock_irqrestore(factors->lock, flags);
-}
-EXPORT_SYMBOL(clk_sunxi_mmc_phase_control);
-
-
 /**
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
@@ -413,6 +586,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
 	.kwidth = 2,
 	.mshift = 0,
 	.mwidth = 2,
+	.n_start = 1,
 };
 
 static struct clk_factors_config sun8i_a23_pll1_config = {
@@ -520,7 +694,16 @@ static const struct factors_data sun7i_a20_out_data __initconst = {
 static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
 						   const struct factors_data *data)
 {
-	return sunxi_factors_register(node, data, &clk_lock);
+	void __iomem *reg;
+
+	reg = of_iomap(node, 0);
+	if (!reg) {
+		pr_err("Could not get registers for factors-clk: %s\n",
+		       node->name);
+		return NULL;
+	}
+
+	return sunxi_factors_register(node, data, &clk_lock, reg);
 }
 
 
@@ -561,7 +744,7 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
 	clk = clk_register_mux(NULL, clk_name, parents, i,
-			       CLK_SET_RATE_NO_REPARENT, reg,
+			       CLK_SET_RATE_PARENT, reg,
 			       data->shift, SUNXI_MUX_GATE_WIDTH,
 			       0, &clk_lock);
 
@@ -1217,7 +1400,6 @@ CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks);
 
 static const char *sun6i_critical_clocks[] __initdata = {
 	"cpu",
-	"ahb1_sdram",
 };
 
 static void __init sun6i_init_clocks(struct device_node *node)

+ 1 - 0
drivers/clk/tegra/Makefile

@@ -15,3 +15,4 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clk-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += clk-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= clk-tegra114.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124.o
+obj-$(CONFIG_ARCH_TEGRA_132_SOC)	+= clk-tegra124.o

+ 0 - 2
drivers/clk/tegra/clk-id.h

@@ -64,10 +64,8 @@ enum clk_id {
 	tegra_clk_disp2,
 	tegra_clk_dp2,
 	tegra_clk_dpaux,
-	tegra_clk_dsia,
 	tegra_clk_dsialp,
 	tegra_clk_dsia_mux,
-	tegra_clk_dsib,
 	tegra_clk_dsiblp,
 	tegra_clk_dsib_mux,
 	tegra_clk_dtv,

+ 7 - 7
drivers/clk/tegra/clk-periph.c

@@ -28,7 +28,7 @@ static u8 clk_periph_get_parent(struct clk_hw *hw)
 	const struct clk_ops *mux_ops = periph->mux_ops;
 	struct clk_hw *mux_hw = &periph->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return mux_ops->get_parent(mux_hw);
 }
@@ -39,7 +39,7 @@ static int clk_periph_set_parent(struct clk_hw *hw, u8 index)
 	const struct clk_ops *mux_ops = periph->mux_ops;
 	struct clk_hw *mux_hw = &periph->mux.hw;
 
-	mux_hw->clk = hw->clk;
+	__clk_hw_set_clk(mux_hw, hw);
 
 	return mux_ops->set_parent(mux_hw, index);
 }
@@ -51,7 +51,7 @@ static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
 	const struct clk_ops *div_ops = periph->div_ops;
 	struct clk_hw *div_hw = &periph->divider.hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return div_ops->recalc_rate(div_hw, parent_rate);
 }
@@ -63,7 +63,7 @@ static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *div_ops = periph->div_ops;
 	struct clk_hw *div_hw = &periph->divider.hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return div_ops->round_rate(div_hw, rate, prate);
 }
@@ -75,7 +75,7 @@ static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *div_ops = periph->div_ops;
 	struct clk_hw *div_hw = &periph->divider.hw;
 
-	div_hw->clk = hw->clk;
+	__clk_hw_set_clk(div_hw, hw);
 
 	return div_ops->set_rate(div_hw, rate, parent_rate);
 }
@@ -86,7 +86,7 @@ static int clk_periph_is_enabled(struct clk_hw *hw)
 	const struct clk_ops *gate_ops = periph->gate_ops;
 	struct clk_hw *gate_hw = &periph->gate.hw;
 
-	gate_hw->clk = hw->clk;
+	__clk_hw_set_clk(gate_hw, hw);
 
 	return gate_ops->is_enabled(gate_hw);
 }
@@ -97,7 +97,7 @@ static int clk_periph_enable(struct clk_hw *hw)
 	const struct clk_ops *gate_ops = periph->gate_ops;
 	struct clk_hw *gate_hw = &periph->gate.hw;
 
-	gate_hw->clk = hw->clk;
+	__clk_hw_set_clk(gate_hw, hw);
 
 	return gate_ops->enable(gate_hw);
 }

+ 11 - 7
drivers/clk/tegra/clk-pll.c

@@ -816,7 +816,9 @@ const struct clk_ops tegra_clk_plle_ops = {
 	.enable = clk_plle_enable,
 };
 
-#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC)
+#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
+	defined(CONFIG_ARCH_TEGRA_124_SOC) || \
+	defined(CONFIG_ARCH_TEGRA_132_SOC)
 
 static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
 			   unsigned long parent_rate)
@@ -1505,7 +1507,9 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
 	return clk;
 }
 
-#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC)
+#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
+	defined(CONFIG_ARCH_TEGRA_124_SOC) || \
+	defined(CONFIG_ARCH_TEGRA_132_SOC)
 static const struct clk_ops tegra_clk_pllxc_ops = {
 	.is_enabled = clk_pll_is_enabled,
 	.enable = clk_pll_iddq_enable,
@@ -1565,7 +1569,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
 	parent = __clk_lookup(parent_name);
 	if (!parent) {
 		WARN(1, "parent clk %s of %s must be registered first\n",
-			name, parent_name);
+			parent_name, name);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1665,7 +1669,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
 	parent = __clk_lookup(parent_name);
 	if (!parent) {
 		WARN(1, "parent clk %s of %s must be registered first\n",
-			name, parent_name);
+			parent_name, name);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1706,7 +1710,7 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
 	parent = __clk_lookup(parent_name);
 	if (!parent) {
 		WARN(1, "parent clk %s of %s must be registered first\n",
-			name, parent_name);
+			parent_name, name);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1802,7 +1806,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
 }
 #endif
 
-#ifdef CONFIG_ARCH_TEGRA_124_SOC
+#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
 static const struct clk_ops tegra_clk_pllss_ops = {
 	.is_enabled = clk_pll_is_enabled,
 	.enable = clk_pll_iddq_enable,
@@ -1830,7 +1834,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
 	parent = __clk_lookup(parent_name);
 	if (!parent) {
 		WARN(1, "parent clk %s of %s must be registered first\n",
-			name, parent_name);
+			parent_name, name);
 		return ERR_PTR(-EINVAL);
 	}
 

+ 8 - 10
drivers/clk/tegra/clk-tegra-periph.c

@@ -434,10 +434,10 @@ static struct tegra_periph_init_data periph_clks[] = {
 	MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda),
 	MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x),
 	MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, tegra_clk_vfir),
-	MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1),
-	MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2),
-	MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3),
-	MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4),
+	MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1),
+	MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2),
+	MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3),
+	MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4),
 	MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la),
 	MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace),
 	MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr),
@@ -470,10 +470,10 @@ static struct tegra_periph_init_data periph_clks[] = {
 	MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1),
 	MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1),
 	MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 165, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2),
-	MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1_8),
-	MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2_8),
-	MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3_8),
-	MUX8("sdmmc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4_8),
+	MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_8),
+	MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2_8),
+	MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_8),
+	MUX8("sdmmc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4_8),
 	MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8),
 	MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8),
 	MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8),
@@ -537,8 +537,6 @@ static struct tegra_periph_init_data gate_clks[] = {
 	GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0),
 	GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0),
 	GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0),
-	GATE("dsia", "dsia_mux", 48, 0, tegra_clk_dsia, 0),
-	GATE("dsib", "dsib_mux", 82, 0, tegra_clk_dsib, 0),
 	GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED),
 	GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0),
 	GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0),

+ 8 - 2
drivers/clk/tegra/clk-tegra114.c

@@ -715,7 +715,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_sbc2_8] = { .dt_id = TEGRA114_CLK_SBC2, .present = true },
 	[tegra_clk_sbc3_8] = { .dt_id = TEGRA114_CLK_SBC3, .present = true },
 	[tegra_clk_i2c5] = { .dt_id = TEGRA114_CLK_I2C5, .present = true },
-	[tegra_clk_dsia] = { .dt_id = TEGRA114_CLK_DSIA, .present = true },
 	[tegra_clk_mipi] = { .dt_id = TEGRA114_CLK_MIPI, .present = true },
 	[tegra_clk_hdmi] = { .dt_id = TEGRA114_CLK_HDMI, .present = true },
 	[tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true },
@@ -739,7 +738,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_dtv] = { .dt_id = TEGRA114_CLK_DTV, .present = true },
 	[tegra_clk_ndspeed] = { .dt_id = TEGRA114_CLK_NDSPEED, .present = true },
 	[tegra_clk_i2cslow] = { .dt_id = TEGRA114_CLK_I2CSLOW, .present = true },
-	[tegra_clk_dsib] = { .dt_id = TEGRA114_CLK_DSIB, .present = true },
 	[tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true },
 	[tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true },
 	[tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true },
@@ -1224,6 +1222,14 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
 			       clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);
 	clks[TEGRA114_CLK_DSIB_MUX] = clk;
 
+	clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base,
+					     0, 48, periph_clk_enb_refcnt);
+	clks[TEGRA114_CLK_DSIA] = clk;
+
+	clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base,
+					     0, 82, periph_clk_enb_refcnt);
+	clks[TEGRA114_CLK_DSIB] = clk;
+
 	/* emc mux */
 	clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
 			       ARRAY_SIZE(mux_pllmcp_clkm),

+ 139 - 29
drivers/clk/tegra/clk-tegra124.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2012-2014 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -28,6 +28,14 @@
 #include "clk.h"
 #include "clk-id.h"
 
+/*
+ * TEGRA124_CAR_BANK_COUNT: the number of peripheral clock register
+ * banks present in the Tegra124/132 CAR IP block.  The banks are
+ * identified by single letters, e.g.: L, H, U, V, W, X.  See
+ * periph_regs[] in drivers/clk/tegra/clk.c
+ */
+#define TEGRA124_CAR_BANK_COUNT			6
+
 #define CLK_SOURCE_CSITE 0x1d4
 #define CLK_SOURCE_EMC 0x19c
 
@@ -128,7 +136,6 @@ static unsigned long osc_freq;
 static unsigned long pll_ref_freq;
 
 static DEFINE_SPINLOCK(pll_d_lock);
-static DEFINE_SPINLOCK(pll_d2_lock);
 static DEFINE_SPINLOCK(pll_e_lock);
 static DEFINE_SPINLOCK(pll_re_lock);
 static DEFINE_SPINLOCK(pll_u_lock);
@@ -145,11 +152,6 @@ static unsigned long tegra124_input_freq[] = {
 	[12] = 260000000,
 };
 
-static const char *mux_plld_out0_plld2_out0[] = {
-	"pll_d_out0", "pll_d2_out0",
-};
-#define mux_plld_out0_plld2_out0_idx NULL
-
 static const char *mux_pllmcp_clkm[] = {
 	"pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3",
 };
@@ -783,7 +785,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_sbc2] = { .dt_id = TEGRA124_CLK_SBC2, .present = true },
 	[tegra_clk_sbc3] = { .dt_id = TEGRA124_CLK_SBC3, .present = true },
 	[tegra_clk_i2c5] = { .dt_id = TEGRA124_CLK_I2C5, .present = true },
-	[tegra_clk_dsia] = { .dt_id = TEGRA124_CLK_DSIA, .present = true },
 	[tegra_clk_mipi] = { .dt_id = TEGRA124_CLK_MIPI, .present = true },
 	[tegra_clk_hdmi] = { .dt_id = TEGRA124_CLK_HDMI, .present = true },
 	[tegra_clk_csi] = { .dt_id = TEGRA124_CLK_CSI, .present = true },
@@ -809,7 +810,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true },
 	[tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true },
 	[tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true },
-	[tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true },
 	[tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true },
 	[tegra_clk_xusb_host] = { .dt_id = TEGRA124_CLK_XUSB_HOST, .present = true },
 	[tegra_clk_msenc] = { .dt_id = TEGRA124_CLK_MSENC, .present = true },
@@ -949,8 +949,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true },
 	[tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true },
 	[tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true },
-	[tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true },
-	[tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true },
 };
 
 static struct tegra_devclk devclks[] __initdata = {
@@ -1112,17 +1110,17 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
 					1, 2);
 	clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;
 
-	/* dsia mux */
-	clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
-			       ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
-			       clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock);
-	clks[TEGRA124_CLK_DSIA_MUX] = clk;
+	clk = clk_register_gate(NULL, "plld_dsi", "plld_out0", 0,
+				clk_base + PLLD_MISC, 30, 0, &pll_d_lock);
+	clks[TEGRA124_CLK_PLLD_DSI] = clk;
+
+	clk = tegra_clk_register_periph_gate("dsia", "plld_dsi", 0, clk_base,
+					     0, 48, periph_clk_enb_refcnt);
+	clks[TEGRA124_CLK_DSIA] = clk;
 
-	/* dsib mux */
-	clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0,
-			       ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
-			       clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);
-	clks[TEGRA124_CLK_DSIB_MUX] = clk;
+	clk = tegra_clk_register_periph_gate("dsib", "plld_dsi", 0, clk_base,
+					     0, 82, periph_clk_enb_refcnt);
+	clks[TEGRA124_CLK_DSIB] = clk;
 
 	/* emc mux */
 	clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
@@ -1351,7 +1349,7 @@ static const struct of_device_id pmc_match[] __initconst = {
 	{},
 };
 
-static struct tegra_clk_init_table init_table[] __initdata = {
+static struct tegra_clk_init_table common_init_table[] __initdata = {
 	{TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0},
 	{TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0},
 	{TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0},
@@ -1368,6 +1366,8 @@ static struct tegra_clk_init_table init_table[] __initdata = {
 	{TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0},
 	{TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0},
 	{TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1},
+	{TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0},
+	{TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0},
 	{TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1},
 	{TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1},
 	{TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1},
@@ -1385,27 +1385,73 @@ static struct tegra_clk_init_table init_table[] __initdata = {
 	{TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0},
 	{TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0},
 	{TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1},
-	{TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
 	{TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1},
 	{TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1},
 	{TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0},
+	/* This MUST be the last entry. */
+	{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
+};
+
+static struct tegra_clk_init_table tegra124_init_table[] __initdata = {
 	{TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},
+	{TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
+	/* This MUST be the last entry. */
+	{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
+};
+
+/* Tegra132 requires the SOC_THERM clock to remain active */
+static struct tegra_clk_init_table tegra132_init_table[] __initdata = {
+	{TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1},
 	/* This MUST be the last entry. */
 	{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
 };
 
+/**
+ * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
+ *
+ * Program an initial clock rate and enable or disable clocks needed
+ * by the rest of the kernel, for Tegra124 SoCs.  It is intended to be
+ * called by assigning a pointer to it to tegra_clk_apply_init_table -
+ * this will be called as an arch_initcall.  No return value.
+ */
 static void __init tegra124_clock_apply_init_table(void)
 {
-	tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX);
+	tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);
+	tegra_init_from_table(tegra124_init_table, clks, TEGRA124_CLK_CLK_MAX);
 }
 
-static void __init tegra124_clock_init(struct device_node *np)
+/**
+ * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs
+ *
+ * Program an initial clock rate and enable or disable clocks needed
+ * by the rest of the kernel, for Tegra132 SoCs.  It is intended to be
+ * called by assigning a pointer to it to tegra_clk_apply_init_table -
+ * this will be called as an arch_initcall.  No return value.
+ */
+static void __init tegra132_clock_apply_init_table(void)
+{
+	tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);
+	tegra_init_from_table(tegra132_init_table, clks, TEGRA124_CLK_CLK_MAX);
+}
+
+/**
+ * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132
+ * @np: struct device_node * of the DT node for the SoC CAR IP block
+ *
+ * Register most of the clocks controlled by the CAR IP block, along
+ * with a few clocks controlled by the PMC IP block.  Everything in
+ * this function should be common to Tegra124 and Tegra132.  XXX The
+ * PMC clock initialization should probably be moved to PMC-specific
+ * driver code.  No return value.
+ */
+static void __init tegra124_132_clock_init_pre(struct device_node *np)
 {
 	struct device_node *node;
+	u32 plld_base;
 
 	clk_base = of_iomap(np, 0);
 	if (!clk_base) {
-		pr_err("ioremap tegra124 CAR failed\n");
+		pr_err("ioremap tegra124/tegra132 CAR failed\n");
 		return;
 	}
 
@@ -1423,7 +1469,8 @@ static void __init tegra124_clock_init(struct device_node *np)
 		return;
 	}
 
-	clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6);
+	clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX,
+			      TEGRA124_CAR_BANK_COUNT);
 	if (!clks)
 		return;
 
@@ -1437,13 +1484,76 @@ static void __init tegra124_clock_init(struct device_node *np)
 	tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params);
 	tegra_pmc_clk_init(pmc_base, tegra124_clks);
 
+	/* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
+	plld_base = clk_readl(clk_base + PLLD_BASE);
+	plld_base &= ~BIT(25);
+	clk_writel(plld_base, clk_base + PLLD_BASE);
+}
+
+/**
+ * tegra124_132_clock_init_post - clock initialization postamble for T124/T132
+ * @np: struct device_node * of the DT node for the SoC CAR IP block
+ *
+ * Register most of the along with a few clocks controlled by the PMC
+ * IP block.  Everything in this function should be common to Tegra124
+ * and Tegra132.  This function must be called after
+ * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will
+ * not be set.  No return value.
+ */
+static void __init tegra124_132_clock_init_post(struct device_node *np)
+{
 	tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,
-					&pll_x_params);
+				  &pll_x_params);
 	tegra_add_of_provider(np);
 	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
 
+	tegra_cpu_car_ops = &tegra124_cpu_car_ops;
+}
+
+/**
+ * tegra124_clock_init - Tegra124-specific clock initialization
+ * @np: struct device_node * of the DT node for the SoC CAR IP block
+ *
+ * Register most SoC clocks for the Tegra124 system-on-chip.  Most of
+ * this code is shared between the Tegra124 and Tegra132 SoCs,
+ * although some of the initial clock settings and CPU clocks differ.
+ * Intended to be called by the OF init code when a DT node with the
+ * "nvidia,tegra124-car" string is encountered, and declared with
+ * CLK_OF_DECLARE.  No return value.
+ */
+static void __init tegra124_clock_init(struct device_node *np)
+{
+	tegra124_132_clock_init_pre(np);
 	tegra_clk_apply_init_table = tegra124_clock_apply_init_table;
+	tegra124_132_clock_init_post(np);
+}
 
-	tegra_cpu_car_ops = &tegra124_cpu_car_ops;
+/**
+ * tegra132_clock_init - Tegra132-specific clock initialization
+ * @np: struct device_node * of the DT node for the SoC CAR IP block
+ *
+ * Register most SoC clocks for the Tegra132 system-on-chip.  Most of
+ * this code is shared between the Tegra124 and Tegra132 SoCs,
+ * although some of the initial clock settings and CPU clocks differ.
+ * Intended to be called by the OF init code when a DT node with the
+ * "nvidia,tegra132-car" string is encountered, and declared with
+ * CLK_OF_DECLARE.  No return value.
+ */
+static void __init tegra132_clock_init(struct device_node *np)
+{
+	tegra124_132_clock_init_pre(np);
+
+	/*
+	 * On Tegra132, these clocks are controlled by the
+	 * CLUSTER_clocks IP block, located in the CPU complex
+	 */
+	tegra124_clks[tegra_clk_cclk_g].present = false;
+	tegra124_clks[tegra_clk_cclk_lp].present = false;
+	tegra124_clks[tegra_clk_pll_x].present = false;
+	tegra124_clks[tegra_clk_pll_x_out0].present = false;
+
+	tegra_clk_apply_init_table = tegra132_clock_apply_init_table;
+	tegra124_132_clock_init_post(np);
 }
 CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init);
+CLK_OF_DECLARE(tegra132, "nvidia,tegra132-car", tegra132_clock_init);

+ 5 - 2
drivers/clk/tegra/clk.c

@@ -302,10 +302,13 @@ struct clk ** __init tegra_lookup_dt_id(int clk_id,
 
 tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
 
-void __init tegra_clocks_apply_init_table(void)
+static int __init tegra_clocks_apply_init_table(void)
 {
 	if (!tegra_clk_apply_init_table)
-		return;
+		return 0;
 
 	tegra_clk_apply_init_table();
+
+	return 0;
 }
+arch_initcall(tegra_clocks_apply_init_table);

+ 6 - 2
drivers/clk/ti/Makefile

@@ -1,13 +1,17 @@
-ifneq ($(CONFIG_OF),)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o
+obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= $(clk-common) interface.o clk-3xxx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= $(clk-common) interface.o \
+					   clk-3xxx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clk-common) clk-44xx.o
 obj-$(CONFIG_SOC_OMAP5)			+= $(clk-common) clk-54xx.o
 obj-$(CONFIG_SOC_DRA7XX)		+= $(clk-common) clk-7xx.o \
 					   clk-dra7-atl.o
 obj-$(CONFIG_SOC_AM43XX)		+= $(clk-common) clk-43xx.o
+
+ifdef CONFIG_ATAGS
+obj-$(CONFIG_ARCH_OMAP3)                += clk-3xxx-legacy.o
 endif

+ 4653 - 0
drivers/clk/ti/clk-3xxx-legacy.c

@@ -0,0 +1,4653 @@
+/*
+ * OMAP3 Legacy clock data
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc
+ *     Tero Kristo (t-kristo@ti.com)
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
+
+static struct ti_clk_fixed virt_12m_ck_data = {
+	.frequency = 12000000,
+};
+
+static struct ti_clk virt_12m_ck = {
+	.name = "virt_12m_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_12m_ck_data,
+};
+
+static struct ti_clk_fixed virt_13m_ck_data = {
+	.frequency = 13000000,
+};
+
+static struct ti_clk virt_13m_ck = {
+	.name = "virt_13m_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_13m_ck_data,
+};
+
+static struct ti_clk_fixed virt_19200000_ck_data = {
+	.frequency = 19200000,
+};
+
+static struct ti_clk virt_19200000_ck = {
+	.name = "virt_19200000_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_19200000_ck_data,
+};
+
+static struct ti_clk_fixed virt_26000000_ck_data = {
+	.frequency = 26000000,
+};
+
+static struct ti_clk virt_26000000_ck = {
+	.name = "virt_26000000_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_26000000_ck_data,
+};
+
+static struct ti_clk_fixed virt_38_4m_ck_data = {
+	.frequency = 38400000,
+};
+
+static struct ti_clk virt_38_4m_ck = {
+	.name = "virt_38_4m_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_38_4m_ck_data,
+};
+
+static struct ti_clk_fixed virt_16_8m_ck_data = {
+	.frequency = 16800000,
+};
+
+static struct ti_clk virt_16_8m_ck = {
+	.name = "virt_16_8m_ck",
+	.type = TI_CLK_FIXED,
+	.data = &virt_16_8m_ck_data,
+};
+
+static const char *osc_sys_ck_parents[] = {
+	"virt_12m_ck",
+	"virt_13m_ck",
+	"virt_19200000_ck",
+	"virt_26000000_ck",
+	"virt_38_4m_ck",
+	"virt_16_8m_ck",
+};
+
+static struct ti_clk_mux osc_sys_ck_data = {
+	.num_parents = ARRAY_SIZE(osc_sys_ck_parents),
+	.reg = 0xd40,
+	.module = TI_CLKM_PRM,
+	.parents = osc_sys_ck_parents,
+};
+
+static struct ti_clk osc_sys_ck = {
+	.name = "osc_sys_ck",
+	.type = TI_CLK_MUX,
+	.data = &osc_sys_ck_data,
+};
+
+static struct ti_clk_divider sys_ck_data = {
+	.parent = "osc_sys_ck",
+	.bit_shift = 6,
+	.max_div = 3,
+	.reg = 0x1270,
+	.module = TI_CLKM_PRM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk sys_ck = {
+	.name = "sys_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &sys_ck_data,
+};
+
+static const char *dpll3_ck_parents[] = {
+	"sys_ck",
+	"sys_ck",
+};
+
+static struct ti_clk_dpll dpll3_ck_data = {
+	.num_parents = ARRAY_SIZE(dpll3_ck_parents),
+	.control_reg = 0xd00,
+	.idlest_reg = 0xd20,
+	.mult_div1_reg = 0xd40,
+	.autoidle_reg = 0xd30,
+	.module = TI_CLKM_CM,
+	.parents = dpll3_ck_parents,
+	.flags = CLKF_CORE,
+	.freqsel_mask = 0xf0,
+	.div1_mask = 0x7f00,
+	.idlest_mask = 0x1,
+	.auto_recal_bit = 0x3,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x5,
+	.max_multiplier = 0x7ff,
+	.enable_mask = 0x7,
+	.mult_mask = 0x7ff0000,
+	.recal_st_bit = 0x5,
+	.autoidle_mask = 0x7,
+};
+
+static struct ti_clk dpll3_ck = {
+	.name = "dpll3_ck",
+	.clkdm_name = "dpll3_clkdm",
+	.type = TI_CLK_DPLL,
+	.data = &dpll3_ck_data,
+};
+
+static struct ti_clk_divider dpll3_m2_ck_data = {
+	.parent = "dpll3_ck",
+	.bit_shift = 27,
+	.max_div = 31,
+	.reg = 0xd40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll3_m2_ck = {
+	.name = "dpll3_m2_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll3_m2_ck_data,
+};
+
+static struct ti_clk_fixed_factor core_ck_data = {
+	.parent = "dpll3_m2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_ck = {
+	.name = "core_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_ck_data,
+};
+
+static struct ti_clk_divider l3_ick_data = {
+	.parent = "core_ck",
+	.max_div = 3,
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk l3_ick = {
+	.name = "l3_ick",
+	.type = TI_CLK_DIVIDER,
+	.data = &l3_ick_data,
+};
+
+static struct ti_clk_fixed_factor security_l3_ick_data = {
+	.parent = "l3_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk security_l3_ick = {
+	.name = "security_l3_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &security_l3_ick_data,
+};
+
+static struct ti_clk_fixed_factor wkup_l4_ick_data = {
+	.parent = "sys_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk wkup_l4_ick = {
+	.name = "wkup_l4_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &wkup_l4_ick_data,
+};
+
+static struct ti_clk_gate usim_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 9,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk usim_ick = {
+	.name = "usim_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usim_ick_data,
+};
+
+static struct ti_clk_gate dss2_alwon_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 1,
+	.reg = 0xe00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk dss2_alwon_fck = {
+	.name = "dss2_alwon_fck",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss2_alwon_fck_data,
+};
+
+static struct ti_clk_divider l4_ick_data = {
+	.parent = "l3_ick",
+	.bit_shift = 2,
+	.max_div = 3,
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk l4_ick = {
+	.name = "l4_ick",
+	.type = TI_CLK_DIVIDER,
+	.data = &l4_ick_data,
+};
+
+static struct ti_clk_fixed_factor core_l4_ick_data = {
+	.parent = "l4_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_l4_ick = {
+	.name = "core_l4_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_l4_ick_data,
+};
+
+static struct ti_clk_gate mmchs2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 25,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mmchs2_ick = {
+	.name = "mmchs2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs2_ick_data,
+};
+
+static const char *dpll4_ck_parents[] = {
+	"sys_ck",
+	"sys_ck",
+};
+
+static struct ti_clk_dpll dpll4_ck_data = {
+	.num_parents = ARRAY_SIZE(dpll4_ck_parents),
+	.control_reg = 0xd00,
+	.idlest_reg = 0xd20,
+	.mult_div1_reg = 0xd44,
+	.autoidle_reg = 0xd30,
+	.module = TI_CLKM_CM,
+	.parents = dpll4_ck_parents,
+	.flags = CLKF_PER,
+	.freqsel_mask = 0xf00000,
+	.modes = 0x82,
+	.div1_mask = 0x7f,
+	.idlest_mask = 0x2,
+	.auto_recal_bit = 0x13,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x6,
+	.max_multiplier = 0x7ff,
+	.enable_mask = 0x70000,
+	.mult_mask = 0x7ff00,
+	.recal_st_bit = 0x6,
+	.autoidle_mask = 0x38,
+};
+
+static struct ti_clk dpll4_ck = {
+	.name = "dpll4_ck",
+	.clkdm_name = "dpll4_clkdm",
+	.type = TI_CLK_DPLL,
+	.data = &dpll4_ck_data,
+};
+
+static struct ti_clk_divider dpll4_m2_ck_data = {
+	.parent = "dpll4_ck",
+	.max_div = 63,
+	.reg = 0xd48,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll4_m2_ck = {
+	.name = "dpll4_m2_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll4_m2_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll4_m2x2_mul_ck_data = {
+	.parent = "dpll4_m2_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll4_m2x2_mul_ck = {
+	.name = "dpll4_m2x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_m2x2_mul_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m2x2_ck_data = {
+	.parent = "dpll4_m2x2_mul_ck",
+	.bit_shift = 0x1b,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m2x2_ck = {
+	.name = "dpll4_m2x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m2x2_ck_data,
+};
+
+static struct ti_clk_fixed_factor omap_96m_alwon_fck_data = {
+	.parent = "dpll4_m2x2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk omap_96m_alwon_fck = {
+	.name = "omap_96m_alwon_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_96m_alwon_fck_data,
+};
+
+static struct ti_clk_fixed_factor cm_96m_fck_data = {
+	.parent = "omap_96m_alwon_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk cm_96m_fck = {
+	.name = "cm_96m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &cm_96m_fck_data,
+};
+
+static const char *omap_96m_fck_parents[] = {
+	"cm_96m_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux omap_96m_fck_data = {
+	.bit_shift = 6,
+	.num_parents = ARRAY_SIZE(omap_96m_fck_parents),
+	.reg = 0xd40,
+	.module = TI_CLKM_CM,
+	.parents = omap_96m_fck_parents,
+};
+
+static struct ti_clk omap_96m_fck = {
+	.name = "omap_96m_fck",
+	.type = TI_CLK_MUX,
+	.data = &omap_96m_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_96m_fck_data = {
+	.parent = "omap_96m_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_96m_fck = {
+	.name = "core_96m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_96m_fck_data,
+};
+
+static struct ti_clk_gate mspro_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 23,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mspro_fck = {
+	.name = "mspro_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mspro_fck_data,
+};
+
+static struct ti_clk_gate dss_ick_3430es2_data = {
+	.parent = "l4_ick",
+	.bit_shift = 0,
+	.reg = 0xe10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_DSS | CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk dss_ick_3430es2 = {
+	.name = "dss_ick",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss_ick_3430es2_data,
+};
+
+static struct ti_clk_gate uart4_ick_am35xx_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 23,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk uart4_ick_am35xx = {
+	.name = "uart4_ick_am35xx",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart4_ick_am35xx_data,
+};
+
+static struct ti_clk_fixed_factor security_l4_ick2_data = {
+	.parent = "l4_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk security_l4_ick2 = {
+	.name = "security_l4_ick2",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &security_l4_ick2_data,
+};
+
+static struct ti_clk_gate aes1_ick_data = {
+	.parent = "security_l4_ick2",
+	.bit_shift = 3,
+	.reg = 0xa14,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk aes1_ick = {
+	.name = "aes1_ick",
+	.type = TI_CLK_GATE,
+	.data = &aes1_ick_data,
+};
+
+static const char *dpll5_ck_parents[] = {
+	"sys_ck",
+	"sys_ck",
+};
+
+static struct ti_clk_dpll dpll5_ck_data = {
+	.num_parents = ARRAY_SIZE(dpll5_ck_parents),
+	.control_reg = 0xd04,
+	.idlest_reg = 0xd24,
+	.mult_div1_reg = 0xd4c,
+	.autoidle_reg = 0xd34,
+	.module = TI_CLKM_CM,
+	.parents = dpll5_ck_parents,
+	.freqsel_mask = 0xf0,
+	.modes = 0x82,
+	.div1_mask = 0x7f,
+	.idlest_mask = 0x1,
+	.auto_recal_bit = 0x3,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x19,
+	.max_multiplier = 0x7ff,
+	.enable_mask = 0x7,
+	.mult_mask = 0x7ff00,
+	.recal_st_bit = 0x19,
+	.autoidle_mask = 0x7,
+};
+
+static struct ti_clk dpll5_ck = {
+	.name = "dpll5_ck",
+	.clkdm_name = "dpll5_clkdm",
+	.type = TI_CLK_DPLL,
+	.data = &dpll5_ck_data,
+};
+
+static struct ti_clk_divider dpll5_m2_ck_data = {
+	.parent = "dpll5_ck",
+	.max_div = 31,
+	.reg = 0xd50,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll5_m2_ck = {
+	.name = "dpll5_m2_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll5_m2_ck_data,
+};
+
+static struct ti_clk_gate usbhost_120m_fck_data = {
+	.parent = "dpll5_m2_ck",
+	.bit_shift = 1,
+	.reg = 0x1400,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk usbhost_120m_fck = {
+	.name = "usbhost_120m_fck",
+	.clkdm_name = "usbhost_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usbhost_120m_fck_data,
+};
+
+static struct ti_clk_fixed_factor cm_96m_d2_fck_data = {
+	.parent = "cm_96m_fck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk cm_96m_d2_fck = {
+	.name = "cm_96m_d2_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &cm_96m_d2_fck_data,
+};
+
+static struct ti_clk_fixed sys_altclk_data = {
+	.frequency = 0x0,
+};
+
+static struct ti_clk sys_altclk = {
+	.name = "sys_altclk",
+	.type = TI_CLK_FIXED,
+	.data = &sys_altclk_data,
+};
+
+static const char *omap_48m_fck_parents[] = {
+	"cm_96m_d2_fck",
+	"sys_altclk",
+};
+
+static struct ti_clk_mux omap_48m_fck_data = {
+	.bit_shift = 3,
+	.num_parents = ARRAY_SIZE(omap_48m_fck_parents),
+	.reg = 0xd40,
+	.module = TI_CLKM_CM,
+	.parents = omap_48m_fck_parents,
+};
+
+static struct ti_clk omap_48m_fck = {
+	.name = "omap_48m_fck",
+	.type = TI_CLK_MUX,
+	.data = &omap_48m_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_48m_fck_data = {
+	.parent = "omap_48m_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_48m_fck = {
+	.name = "core_48m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_48m_fck_data,
+};
+
+static struct ti_clk_fixed mcbsp_clks_data = {
+	.frequency = 0x0,
+};
+
+static struct ti_clk mcbsp_clks = {
+	.name = "mcbsp_clks",
+	.type = TI_CLK_FIXED,
+	.data = &mcbsp_clks_data,
+};
+
+static struct ti_clk_gate mcbsp2_gate_fck_data = {
+	.parent = "mcbsp_clks",
+	.bit_shift = 0,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_fixed_factor per_96m_fck_data = {
+	.parent = "omap_96m_alwon_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk per_96m_fck = {
+	.name = "per_96m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &per_96m_fck_data,
+};
+
+static const char *mcbsp2_mux_fck_parents[] = {
+	"per_96m_fck",
+	"mcbsp_clks",
+};
+
+static struct ti_clk_mux mcbsp2_mux_fck_data = {
+	.bit_shift = 6,
+	.num_parents = ARRAY_SIZE(mcbsp2_mux_fck_parents),
+	.reg = 0x274,
+	.module = TI_CLKM_SCRM,
+	.parents = mcbsp2_mux_fck_parents,
+};
+
+static struct ti_clk_composite mcbsp2_fck_data = {
+	.mux = &mcbsp2_mux_fck_data,
+	.gate = &mcbsp2_gate_fck_data,
+};
+
+static struct ti_clk mcbsp2_fck = {
+	.name = "mcbsp2_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &mcbsp2_fck_data,
+};
+
+static struct ti_clk_fixed_factor dpll3_m2x2_ck_data = {
+	.parent = "dpll3_m2_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll3_m2x2_ck = {
+	.name = "dpll3_m2x2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll3_m2x2_ck_data,
+};
+
+static struct ti_clk_fixed_factor corex2_fck_data = {
+	.parent = "dpll3_m2x2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk corex2_fck = {
+	.name = "corex2_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &corex2_fck_data,
+};
+
+static struct ti_clk_gate ssi_ssr_gate_fck_3430es1_data = {
+	.parent = "corex2_fck",
+	.bit_shift = 0,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_NO_WAIT,
+};
+
+static int ssi_ssr_div_fck_3430es1_divs[] = {
+	0,
+	1,
+	2,
+	3,
+	4,
+	0,
+	6,
+	0,
+	8,
+};
+
+static struct ti_clk_divider ssi_ssr_div_fck_3430es1_data = {
+	.num_dividers = ARRAY_SIZE(ssi_ssr_div_fck_3430es1_divs),
+	.parent = "corex2_fck",
+	.bit_shift = 8,
+	.dividers = ssi_ssr_div_fck_3430es1_divs,
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_composite ssi_ssr_fck_3430es1_data = {
+	.gate = &ssi_ssr_gate_fck_3430es1_data,
+	.divider = &ssi_ssr_div_fck_3430es1_data,
+};
+
+static struct ti_clk ssi_ssr_fck_3430es1 = {
+	.name = "ssi_ssr_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &ssi_ssr_fck_3430es1_data,
+};
+
+static struct ti_clk_fixed_factor ssi_sst_fck_3430es1_data = {
+	.parent = "ssi_ssr_fck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk ssi_sst_fck_3430es1 = {
+	.name = "ssi_sst_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &ssi_sst_fck_3430es1_data,
+};
+
+static struct ti_clk_fixed omap_32k_fck_data = {
+	.frequency = 32768,
+};
+
+static struct ti_clk omap_32k_fck = {
+	.name = "omap_32k_fck",
+	.type = TI_CLK_FIXED,
+	.data = &omap_32k_fck_data,
+};
+
+static struct ti_clk_fixed_factor per_32k_alwon_fck_data = {
+	.parent = "omap_32k_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk per_32k_alwon_fck = {
+	.name = "per_32k_alwon_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &per_32k_alwon_fck_data,
+};
+
+static struct ti_clk_gate gpio5_dbck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 16,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio5_dbck = {
+	.name = "gpio5_dbck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio5_dbck_data,
+};
+
+static struct ti_clk_gate gpt1_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 0,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt1_ick = {
+	.name = "gpt1_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt1_ick_data,
+};
+
+static struct ti_clk_gate mcspi3_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 20,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mcspi3_fck = {
+	.name = "mcspi3_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi3_fck_data,
+};
+
+static struct ti_clk_gate gpt2_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 3,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static const char *gpt2_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt2_mux_fck_data = {
+	.num_parents = ARRAY_SIZE(gpt2_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt2_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt2_fck_data = {
+	.mux = &gpt2_mux_fck_data,
+	.gate = &gpt2_gate_fck_data,
+};
+
+static struct ti_clk gpt2_fck = {
+	.name = "gpt2_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt2_fck_data,
+};
+
+static struct ti_clk_gate gpt10_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 11,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt10_ick = {
+	.name = "gpt10_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt10_ick_data,
+};
+
+static struct ti_clk_gate uart2_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 14,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk uart2_fck = {
+	.name = "uart2_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart2_fck_data,
+};
+
+static struct ti_clk_fixed_factor sr_l4_ick_data = {
+	.parent = "l4_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk sr_l4_ick = {
+	.name = "sr_l4_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &sr_l4_ick_data,
+};
+
+static struct ti_clk_fixed_factor omap_96m_d8_fck_data = {
+	.parent = "omap_96m_fck",
+	.div = 8,
+	.mult = 1,
+};
+
+static struct ti_clk omap_96m_d8_fck = {
+	.name = "omap_96m_d8_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_96m_d8_fck_data,
+};
+
+static struct ti_clk_divider dpll4_m5_ck_data = {
+	.parent = "dpll4_ck",
+	.max_div = 63,
+	.reg = 0xf40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll4_m5_ck = {
+	.name = "dpll4_m5_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll4_m5_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll4_m5x2_mul_ck_data = {
+	.parent = "dpll4_m5_ck",
+	.div = 1,
+	.mult = 2,
+	.flags = CLKF_SET_RATE_PARENT,
+};
+
+static struct ti_clk dpll4_m5x2_mul_ck = {
+	.name = "dpll4_m5x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_m5x2_mul_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m5x2_ck_data = {
+	.parent = "dpll4_m5x2_mul_ck",
+	.bit_shift = 0x1e,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m5x2_ck = {
+	.name = "dpll4_m5x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m5x2_ck_data,
+};
+
+static struct ti_clk_gate cam_mclk_data = {
+	.parent = "dpll4_m5x2_ck",
+	.bit_shift = 0,
+	.reg = 0xf00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_RATE_PARENT,
+};
+
+static struct ti_clk cam_mclk = {
+	.name = "cam_mclk",
+	.type = TI_CLK_GATE,
+	.data = &cam_mclk_data,
+};
+
+static struct ti_clk_gate mcbsp3_gate_fck_data = {
+	.parent = "mcbsp_clks",
+	.bit_shift = 1,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static const char *mcbsp3_mux_fck_parents[] = {
+	"per_96m_fck",
+	"mcbsp_clks",
+};
+
+static struct ti_clk_mux mcbsp3_mux_fck_data = {
+	.num_parents = ARRAY_SIZE(mcbsp3_mux_fck_parents),
+	.reg = 0x2d8,
+	.module = TI_CLKM_SCRM,
+	.parents = mcbsp3_mux_fck_parents,
+};
+
+static struct ti_clk_composite mcbsp3_fck_data = {
+	.mux = &mcbsp3_mux_fck_data,
+	.gate = &mcbsp3_gate_fck_data,
+};
+
+static struct ti_clk mcbsp3_fck = {
+	.name = "mcbsp3_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &mcbsp3_fck_data,
+};
+
+static struct ti_clk_gate csi2_96m_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 1,
+	.reg = 0xf00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk csi2_96m_fck = {
+	.name = "csi2_96m_fck",
+	.clkdm_name = "cam_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &csi2_96m_fck_data,
+};
+
+static struct ti_clk_gate gpt9_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 10,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static const char *gpt9_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt9_mux_fck_data = {
+	.bit_shift = 7,
+	.num_parents = ARRAY_SIZE(gpt9_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt9_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt9_fck_data = {
+	.mux = &gpt9_mux_fck_data,
+	.gate = &gpt9_gate_fck_data,
+};
+
+static struct ti_clk gpt9_fck = {
+	.name = "gpt9_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt9_fck_data,
+};
+
+static struct ti_clk_divider dpll3_m3_ck_data = {
+	.parent = "dpll3_ck",
+	.bit_shift = 16,
+	.max_div = 31,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll3_m3_ck = {
+	.name = "dpll3_m3_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll3_m3_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll3_m3x2_mul_ck_data = {
+	.parent = "dpll3_m3_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll3_m3x2_mul_ck = {
+	.name = "dpll3_m3x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll3_m3x2_mul_ck_data,
+};
+
+static struct ti_clk_gate sr2_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 7,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk sr2_fck = {
+	.name = "sr2_fck",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sr2_fck_data,
+};
+
+static struct ti_clk_fixed pclk_ck_data = {
+	.frequency = 27000000,
+};
+
+static struct ti_clk pclk_ck = {
+	.name = "pclk_ck",
+	.type = TI_CLK_FIXED,
+	.data = &pclk_ck_data,
+};
+
+static struct ti_clk_gate wdt2_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 5,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk wdt2_ick = {
+	.name = "wdt2_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &wdt2_ick_data,
+};
+
+static struct ti_clk_fixed_factor core_l3_ick_data = {
+	.parent = "l3_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_l3_ick = {
+	.name = "core_l3_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_l3_ick_data,
+};
+
+static struct ti_clk_gate mcspi4_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 21,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mcspi4_fck = {
+	.name = "mcspi4_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi4_fck_data,
+};
+
+static struct ti_clk_fixed_factor per_48m_fck_data = {
+	.parent = "omap_48m_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk per_48m_fck = {
+	.name = "per_48m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &per_48m_fck_data,
+};
+
+static struct ti_clk_gate uart4_fck_data = {
+	.parent = "per_48m_fck",
+	.bit_shift = 18,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk uart4_fck = {
+	.name = "uart4_fck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart4_fck_data,
+};
+
+static struct ti_clk_fixed_factor omap_96m_d10_fck_data = {
+	.parent = "omap_96m_fck",
+	.div = 10,
+	.mult = 1,
+};
+
+static struct ti_clk omap_96m_d10_fck = {
+	.name = "omap_96m_d10_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_96m_d10_fck_data,
+};
+
+static struct ti_clk_gate usim_gate_fck_data = {
+	.parent = "omap_96m_fck",
+	.bit_shift = 9,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_fixed_factor per_l4_ick_data = {
+	.parent = "l4_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk per_l4_ick = {
+	.name = "per_l4_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &per_l4_ick_data,
+};
+
+static struct ti_clk_gate gpt5_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 6,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt5_ick = {
+	.name = "gpt5_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt5_ick_data,
+};
+
+static struct ti_clk_gate mcspi2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 19,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcspi2_ick = {
+	.name = "mcspi2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi2_ick_data,
+};
+
+static struct ti_clk_fixed_factor ssi_l4_ick_data = {
+	.parent = "l4_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk ssi_l4_ick = {
+	.name = "ssi_l4_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &ssi_l4_ick_data,
+};
+
+static struct ti_clk_gate ssi_ick_3430es1_data = {
+	.parent = "ssi_l4_ick",
+	.bit_shift = 0,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_NO_WAIT | CLKF_INTERFACE,
+};
+
+static struct ti_clk ssi_ick_3430es1 = {
+	.name = "ssi_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &ssi_ick_3430es1_data,
+};
+
+static struct ti_clk_gate i2c2_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 16,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk i2c2_fck = {
+	.name = "i2c2_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c2_fck_data,
+};
+
+static struct ti_clk_divider dpll1_fck_data = {
+	.parent = "core_ck",
+	.bit_shift = 19,
+	.max_div = 7,
+	.reg = 0x940,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll1_fck = {
+	.name = "dpll1_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll1_fck_data,
+};
+
+static const char *dpll1_ck_parents[] = {
+	"sys_ck",
+	"dpll1_fck",
+};
+
+static struct ti_clk_dpll dpll1_ck_data = {
+	.num_parents = ARRAY_SIZE(dpll1_ck_parents),
+	.control_reg = 0x904,
+	.idlest_reg = 0x924,
+	.mult_div1_reg = 0x940,
+	.autoidle_reg = 0x934,
+	.module = TI_CLKM_CM,
+	.parents = dpll1_ck_parents,
+	.freqsel_mask = 0xf0,
+	.modes = 0xa0,
+	.div1_mask = 0x7f,
+	.idlest_mask = 0x1,
+	.auto_recal_bit = 0x3,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x7,
+	.max_multiplier = 0x7ff,
+	.enable_mask = 0x7,
+	.mult_mask = 0x7ff00,
+	.recal_st_bit = 0x7,
+	.autoidle_mask = 0x7,
+};
+
+static struct ti_clk dpll1_ck = {
+	.name = "dpll1_ck",
+	.clkdm_name = "dpll1_clkdm",
+	.type = TI_CLK_DPLL,
+	.data = &dpll1_ck_data,
+};
+
+static struct ti_clk_fixed secure_32k_fck_data = {
+	.frequency = 32768,
+};
+
+static struct ti_clk secure_32k_fck = {
+	.name = "secure_32k_fck",
+	.type = TI_CLK_FIXED,
+	.data = &secure_32k_fck_data,
+};
+
+static struct ti_clk_gate gpio5_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 16,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio5_ick = {
+	.name = "gpio5_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio5_ick_data,
+};
+
+static struct ti_clk_divider dpll4_m4_ck_data = {
+	.parent = "dpll4_ck",
+	.max_div = 32,
+	.reg = 0xe40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll4_m4_ck = {
+	.name = "dpll4_m4_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll4_m4_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll4_m4x2_mul_ck_data = {
+	.parent = "dpll4_m4_ck",
+	.div = 1,
+	.mult = 2,
+	.flags = CLKF_SET_RATE_PARENT,
+};
+
+static struct ti_clk dpll4_m4x2_mul_ck = {
+	.name = "dpll4_m4x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_m4x2_mul_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m4x2_ck_data = {
+	.parent = "dpll4_m4x2_mul_ck",
+	.bit_shift = 0x1d,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_RATE_PARENT | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m4x2_ck = {
+	.name = "dpll4_m4x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m4x2_ck_data,
+};
+
+static struct ti_clk_gate dss1_alwon_fck_3430es2_data = {
+	.parent = "dpll4_m4x2_ck",
+	.bit_shift = 0,
+	.reg = 0xe00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_DSS | CLKF_SET_RATE_PARENT,
+};
+
+static struct ti_clk dss1_alwon_fck_3430es2 = {
+	.name = "dss1_alwon_fck",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss1_alwon_fck_3430es2_data,
+};
+
+static struct ti_clk_gate uart3_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 11,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk uart3_ick = {
+	.name = "uart3_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart3_ick_data,
+};
+
+static struct ti_clk_divider dpll4_m3_ck_data = {
+	.parent = "dpll4_ck",
+	.bit_shift = 8,
+	.max_div = 32,
+	.reg = 0xe40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll4_m3_ck = {
+	.name = "dpll4_m3_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll4_m3_ck_data,
+};
+
+static struct ti_clk_gate mcbsp3_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 1,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcbsp3_ick = {
+	.name = "mcbsp3_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcbsp3_ick_data,
+};
+
+static struct ti_clk_gate gpio3_dbck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 14,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio3_dbck = {
+	.name = "gpio3_dbck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio3_dbck_data,
+};
+
+static struct ti_clk_gate fac_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 8,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk fac_ick = {
+	.name = "fac_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &fac_ick_data,
+};
+
+static struct ti_clk_gate clkout2_src_gate_ck_data = {
+	.parent = "core_ck",
+	.bit_shift = 7,
+	.reg = 0xd70,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_NO_WAIT,
+};
+
+static struct ti_clk_fixed_factor dpll4_m3x2_mul_ck_data = {
+	.parent = "dpll4_m3_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll4_m3x2_mul_ck = {
+	.name = "dpll4_m3x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_m3x2_mul_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m3x2_ck_data = {
+	.parent = "dpll4_m3x2_mul_ck",
+	.bit_shift = 0x1c,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m3x2_ck = {
+	.name = "dpll4_m3x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m3x2_ck_data,
+};
+
+static const char *omap_54m_fck_parents[] = {
+	"dpll4_m3x2_ck",
+	"sys_altclk",
+};
+
+static struct ti_clk_mux omap_54m_fck_data = {
+	.bit_shift = 5,
+	.num_parents = ARRAY_SIZE(omap_54m_fck_parents),
+	.reg = 0xd40,
+	.module = TI_CLKM_CM,
+	.parents = omap_54m_fck_parents,
+};
+
+static struct ti_clk omap_54m_fck = {
+	.name = "omap_54m_fck",
+	.type = TI_CLK_MUX,
+	.data = &omap_54m_fck_data,
+};
+
+static const char *clkout2_src_mux_ck_parents[] = {
+	"core_ck",
+	"sys_ck",
+	"cm_96m_fck",
+	"omap_54m_fck",
+};
+
+static struct ti_clk_mux clkout2_src_mux_ck_data = {
+	.num_parents = ARRAY_SIZE(clkout2_src_mux_ck_parents),
+	.reg = 0xd70,
+	.module = TI_CLKM_CM,
+	.parents = clkout2_src_mux_ck_parents,
+};
+
+static struct ti_clk_composite clkout2_src_ck_data = {
+	.mux = &clkout2_src_mux_ck_data,
+	.gate = &clkout2_src_gate_ck_data,
+};
+
+static struct ti_clk clkout2_src_ck = {
+	.name = "clkout2_src_ck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &clkout2_src_ck_data,
+};
+
+static struct ti_clk_gate i2c1_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 15,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk i2c1_fck = {
+	.name = "i2c1_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c1_fck_data,
+};
+
+static struct ti_clk_gate wdt3_fck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 12,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk wdt3_fck = {
+	.name = "wdt3_fck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &wdt3_fck_data,
+};
+
+static struct ti_clk_gate gpt7_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 8,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static const char *gpt7_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt7_mux_fck_data = {
+	.bit_shift = 5,
+	.num_parents = ARRAY_SIZE(gpt7_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt7_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt7_fck_data = {
+	.mux = &gpt7_mux_fck_data,
+	.gate = &gpt7_gate_fck_data,
+};
+
+static struct ti_clk gpt7_fck = {
+	.name = "gpt7_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt7_fck_data,
+};
+
+static struct ti_clk_gate usb_l4_gate_ick_data = {
+	.parent = "l4_ick",
+	.bit_shift = 5,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INTERFACE,
+};
+
+static struct ti_clk_divider usb_l4_div_ick_data = {
+	.parent = "l4_ick",
+	.bit_shift = 4,
+	.max_div = 1,
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk_composite usb_l4_ick_data = {
+	.gate = &usb_l4_gate_ick_data,
+	.divider = &usb_l4_div_ick_data,
+};
+
+static struct ti_clk usb_l4_ick = {
+	.name = "usb_l4_ick",
+	.type = TI_CLK_COMPOSITE,
+	.data = &usb_l4_ick_data,
+};
+
+static struct ti_clk_gate uart4_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 18,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk uart4_ick = {
+	.name = "uart4_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart4_ick_data,
+};
+
+static struct ti_clk_fixed dummy_ck_data = {
+	.frequency = 0,
+};
+
+static struct ti_clk dummy_ck = {
+	.name = "dummy_ck",
+	.type = TI_CLK_FIXED,
+	.data = &dummy_ck_data,
+};
+
+static const char *gpt3_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt3_mux_fck_data = {
+	.bit_shift = 1,
+	.num_parents = ARRAY_SIZE(gpt3_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt3_mux_fck_parents,
+};
+
+static struct ti_clk_gate gpt9_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 10,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt9_ick = {
+	.name = "gpt9_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt9_ick_data,
+};
+
+static struct ti_clk_gate gpt10_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 11,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_gate dss_ick_3430es1_data = {
+	.parent = "l4_ick",
+	.bit_shift = 0,
+	.reg = 0xe10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_NO_WAIT | CLKF_INTERFACE,
+};
+
+static struct ti_clk dss_ick_3430es1 = {
+	.name = "dss_ick",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss_ick_3430es1_data,
+};
+
+static struct ti_clk_gate gpt11_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 12,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt11_ick = {
+	.name = "gpt11_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt11_ick_data,
+};
+
+static struct ti_clk_divider dpll2_fck_data = {
+	.parent = "core_ck",
+	.bit_shift = 19,
+	.max_div = 7,
+	.reg = 0x40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll2_fck = {
+	.name = "dpll2_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll2_fck_data,
+};
+
+static struct ti_clk_gate uart1_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 13,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk uart1_fck = {
+	.name = "uart1_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart1_fck_data,
+};
+
+static struct ti_clk_gate hsotgusb_ick_3430es1_data = {
+	.parent = "core_l3_ick",
+	.bit_shift = 4,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_NO_WAIT | CLKF_INTERFACE,
+};
+
+static struct ti_clk hsotgusb_ick_3430es1 = {
+	.name = "hsotgusb_ick_3430es1",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hsotgusb_ick_3430es1_data,
+};
+
+static struct ti_clk_gate gpio2_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 13,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio2_ick = {
+	.name = "gpio2_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio2_ick_data,
+};
+
+static struct ti_clk_gate mmchs1_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 24,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mmchs1_ick = {
+	.name = "mmchs1_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs1_ick_data,
+};
+
+static struct ti_clk_gate modem_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 31,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk modem_fck = {
+	.name = "modem_fck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &modem_fck_data,
+};
+
+static struct ti_clk_gate mcbsp4_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 2,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcbsp4_ick = {
+	.name = "mcbsp4_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcbsp4_ick_data,
+};
+
+static struct ti_clk_gate gpio1_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 3,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio1_ick = {
+	.name = "gpio1_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio1_ick_data,
+};
+
+static const char *gpt6_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt6_mux_fck_data = {
+	.bit_shift = 4,
+	.num_parents = ARRAY_SIZE(gpt6_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt6_mux_fck_parents,
+};
+
+static struct ti_clk_fixed_factor dpll1_x2_ck_data = {
+	.parent = "dpll1_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll1_x2_ck = {
+	.name = "dpll1_x2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll1_x2_ck_data,
+};
+
+static struct ti_clk_divider dpll1_x2m2_ck_data = {
+	.parent = "dpll1_x2_ck",
+	.max_div = 31,
+	.reg = 0x944,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll1_x2m2_ck = {
+	.name = "dpll1_x2m2_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll1_x2m2_ck_data,
+};
+
+static struct ti_clk_fixed_factor mpu_ck_data = {
+	.parent = "dpll1_x2m2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk mpu_ck = {
+	.name = "mpu_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &mpu_ck_data,
+};
+
+static struct ti_clk_divider arm_fck_data = {
+	.parent = "mpu_ck",
+	.max_div = 2,
+	.reg = 0x924,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk arm_fck = {
+	.name = "arm_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &arm_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_d3_ck_data = {
+	.parent = "core_ck",
+	.div = 3,
+	.mult = 1,
+};
+
+static struct ti_clk core_d3_ck = {
+	.name = "core_d3_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_d3_ck_data,
+};
+
+static struct ti_clk_gate gpt11_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 12,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+};
+
+static const char *gpt11_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt11_mux_fck_data = {
+	.bit_shift = 7,
+	.num_parents = ARRAY_SIZE(gpt11_mux_fck_parents),
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+	.parents = gpt11_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt11_fck_data = {
+	.mux = &gpt11_mux_fck_data,
+	.gate = &gpt11_gate_fck_data,
+};
+
+static struct ti_clk gpt11_fck = {
+	.name = "gpt11_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt11_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_d6_ck_data = {
+	.parent = "core_ck",
+	.div = 6,
+	.mult = 1,
+};
+
+static struct ti_clk core_d6_ck = {
+	.name = "core_d6_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_d6_ck_data,
+};
+
+static struct ti_clk_gate uart4_fck_am35xx_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 23,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk uart4_fck_am35xx = {
+	.name = "uart4_fck_am35xx",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart4_fck_am35xx_data,
+};
+
+static struct ti_clk_gate dpll3_m3x2_ck_data = {
+	.parent = "dpll3_m3x2_mul_ck",
+	.bit_shift = 0xc,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll3_m3x2_ck = {
+	.name = "dpll3_m3x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll3_m3x2_ck_data,
+};
+
+static struct ti_clk_fixed_factor emu_core_alwon_ck_data = {
+	.parent = "dpll3_m3x2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk emu_core_alwon_ck = {
+	.name = "emu_core_alwon_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &emu_core_alwon_ck_data,
+};
+
+static struct ti_clk_divider dpll4_m6_ck_data = {
+	.parent = "dpll4_ck",
+	.bit_shift = 24,
+	.max_div = 63,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll4_m6_ck = {
+	.name = "dpll4_m6_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll4_m6_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll4_m6x2_mul_ck_data = {
+	.parent = "dpll4_m6_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll4_m6x2_mul_ck = {
+	.name = "dpll4_m6x2_mul_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_m6x2_mul_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m6x2_ck_data = {
+	.parent = "dpll4_m6x2_mul_ck",
+	.bit_shift = 0x1f,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m6x2_ck = {
+	.name = "dpll4_m6x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m6x2_ck_data,
+};
+
+static struct ti_clk_fixed_factor emu_per_alwon_ck_data = {
+	.parent = "dpll4_m6x2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk emu_per_alwon_ck = {
+	.name = "emu_per_alwon_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &emu_per_alwon_ck_data,
+};
+
+static struct ti_clk_fixed_factor emu_mpu_alwon_ck_data = {
+	.parent = "mpu_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk emu_mpu_alwon_ck = {
+	.name = "emu_mpu_alwon_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &emu_mpu_alwon_ck_data,
+};
+
+static const char *emu_src_mux_ck_parents[] = {
+	"sys_ck",
+	"emu_core_alwon_ck",
+	"emu_per_alwon_ck",
+	"emu_mpu_alwon_ck",
+};
+
+static struct ti_clk_mux emu_src_mux_ck_data = {
+	.num_parents = ARRAY_SIZE(emu_src_mux_ck_parents),
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.parents = emu_src_mux_ck_parents,
+};
+
+static struct ti_clk emu_src_mux_ck = {
+	.name = "emu_src_mux_ck",
+	.type = TI_CLK_MUX,
+	.data = &emu_src_mux_ck_data,
+};
+
+static struct ti_clk_gate emu_src_ck_data = {
+	.parent = "emu_src_mux_ck",
+	.flags = CLKF_CLKDM,
+};
+
+static struct ti_clk emu_src_ck = {
+	.name = "emu_src_ck",
+	.clkdm_name = "emu_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &emu_src_ck_data,
+};
+
+static struct ti_clk_divider atclk_fck_data = {
+	.parent = "emu_src_ck",
+	.bit_shift = 4,
+	.max_div = 3,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk atclk_fck = {
+	.name = "atclk_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &atclk_fck_data,
+};
+
+static struct ti_clk_gate ipss_ick_data = {
+	.parent = "core_l3_ick",
+	.bit_shift = 4,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_AM35XX | CLKF_INTERFACE,
+};
+
+static struct ti_clk ipss_ick = {
+	.name = "ipss_ick",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &ipss_ick_data,
+};
+
+static struct ti_clk_gate emac_ick_data = {
+	.parent = "ipss_ick",
+	.bit_shift = 1,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+	.flags = CLKF_AM35XX,
+};
+
+static struct ti_clk emac_ick = {
+	.name = "emac_ick",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &emac_ick_data,
+};
+
+static struct ti_clk_gate vpfe_ick_data = {
+	.parent = "ipss_ick",
+	.bit_shift = 2,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+	.flags = CLKF_AM35XX,
+};
+
+static struct ti_clk vpfe_ick = {
+	.name = "vpfe_ick",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &vpfe_ick_data,
+};
+
+static const char *dpll2_ck_parents[] = {
+	"sys_ck",
+	"dpll2_fck",
+};
+
+static struct ti_clk_dpll dpll2_ck_data = {
+	.num_parents = ARRAY_SIZE(dpll2_ck_parents),
+	.control_reg = 0x4,
+	.idlest_reg = 0x24,
+	.mult_div1_reg = 0x40,
+	.autoidle_reg = 0x34,
+	.module = TI_CLKM_CM,
+	.parents = dpll2_ck_parents,
+	.freqsel_mask = 0xf0,
+	.modes = 0xa2,
+	.div1_mask = 0x7f,
+	.idlest_mask = 0x1,
+	.auto_recal_bit = 0x3,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x8,
+	.max_multiplier = 0x7ff,
+	.enable_mask = 0x7,
+	.mult_mask = 0x7ff00,
+	.recal_st_bit = 0x8,
+	.autoidle_mask = 0x7,
+};
+
+static struct ti_clk dpll2_ck = {
+	.name = "dpll2_ck",
+	.clkdm_name = "dpll2_clkdm",
+	.type = TI_CLK_DPLL,
+	.data = &dpll2_ck_data,
+};
+
+static struct ti_clk_divider dpll2_m2_ck_data = {
+	.parent = "dpll2_ck",
+	.max_div = 31,
+	.reg = 0x44,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk dpll2_m2_ck = {
+	.name = "dpll2_m2_ck",
+	.type = TI_CLK_DIVIDER,
+	.data = &dpll2_m2_ck_data,
+};
+
+static const char *mcbsp4_mux_fck_parents[] = {
+	"per_96m_fck",
+	"mcbsp_clks",
+};
+
+static struct ti_clk_mux mcbsp4_mux_fck_data = {
+	.bit_shift = 2,
+	.num_parents = ARRAY_SIZE(mcbsp4_mux_fck_parents),
+	.reg = 0x2d8,
+	.module = TI_CLKM_SCRM,
+	.parents = mcbsp4_mux_fck_parents,
+};
+
+static const char *mcbsp1_mux_fck_parents[] = {
+	"core_96m_fck",
+	"mcbsp_clks",
+};
+
+static struct ti_clk_mux mcbsp1_mux_fck_data = {
+	.bit_shift = 2,
+	.num_parents = ARRAY_SIZE(mcbsp1_mux_fck_parents),
+	.reg = 0x274,
+	.module = TI_CLKM_SCRM,
+	.parents = mcbsp1_mux_fck_parents,
+};
+
+static struct ti_clk_gate gpt8_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 9,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_gate gpt8_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 9,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt8_ick = {
+	.name = "gpt8_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt8_ick_data,
+};
+
+static const char *gpt10_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt10_mux_fck_data = {
+	.bit_shift = 6,
+	.num_parents = ARRAY_SIZE(gpt10_mux_fck_parents),
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+	.parents = gpt10_mux_fck_parents,
+};
+
+static struct ti_clk_gate mmchs3_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 30,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mmchs3_ick = {
+	.name = "mmchs3_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs3_ick_data,
+};
+
+static struct ti_clk_gate gpio3_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 14,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio3_ick = {
+	.name = "gpio3_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio3_ick_data,
+};
+
+static const char *traceclk_src_fck_parents[] = {
+	"sys_ck",
+	"emu_core_alwon_ck",
+	"emu_per_alwon_ck",
+	"emu_mpu_alwon_ck",
+};
+
+static struct ti_clk_mux traceclk_src_fck_data = {
+	.bit_shift = 2,
+	.num_parents = ARRAY_SIZE(traceclk_src_fck_parents),
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.parents = traceclk_src_fck_parents,
+};
+
+static struct ti_clk traceclk_src_fck = {
+	.name = "traceclk_src_fck",
+	.type = TI_CLK_MUX,
+	.data = &traceclk_src_fck_data,
+};
+
+static struct ti_clk_divider traceclk_fck_data = {
+	.parent = "traceclk_src_fck",
+	.bit_shift = 11,
+	.max_div = 7,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk traceclk_fck = {
+	.name = "traceclk_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &traceclk_fck_data,
+};
+
+static struct ti_clk_gate mcbsp5_gate_fck_data = {
+	.parent = "mcbsp_clks",
+	.bit_shift = 10,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_gate sad2d_ick_data = {
+	.parent = "l3_ick",
+	.bit_shift = 3,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk sad2d_ick = {
+	.name = "sad2d_ick",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sad2d_ick_data,
+};
+
+static const char *gpt1_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt1_mux_fck_data = {
+	.num_parents = ARRAY_SIZE(gpt1_mux_fck_parents),
+	.reg = 0xc40,
+	.module = TI_CLKM_CM,
+	.parents = gpt1_mux_fck_parents,
+};
+
+static struct ti_clk_gate hecc_ck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 3,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+	.flags = CLKF_AM35XX,
+};
+
+static struct ti_clk hecc_ck = {
+	.name = "hecc_ck",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hecc_ck_data,
+};
+
+static struct ti_clk_gate gpt1_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 0,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_composite gpt1_fck_data = {
+	.mux = &gpt1_mux_fck_data,
+	.gate = &gpt1_gate_fck_data,
+};
+
+static struct ti_clk gpt1_fck = {
+	.name = "gpt1_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt1_fck_data,
+};
+
+static struct ti_clk_gate dpll4_m2x2_ck_omap36xx_data = {
+	.parent = "dpll4_m2x2_mul_ck",
+	.bit_shift = 0x1b,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSDIV | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m2x2_ck_omap36xx = {
+	.name = "dpll4_m2x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m2x2_ck_omap36xx_data,
+	.patch = &dpll4_m2x2_ck,
+};
+
+static struct ti_clk_divider gfx_l3_fck_data = {
+	.parent = "l3_ick",
+	.max_div = 7,
+	.reg = 0xb40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk gfx_l3_fck = {
+	.name = "gfx_l3_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &gfx_l3_fck_data,
+};
+
+static struct ti_clk_gate gfx_cg1_ck_data = {
+	.parent = "gfx_l3_fck",
+	.bit_shift = 1,
+	.reg = 0xb00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk gfx_cg1_ck = {
+	.name = "gfx_cg1_ck",
+	.clkdm_name = "gfx_3430es1_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gfx_cg1_ck_data,
+};
+
+static struct ti_clk_gate mailboxes_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 7,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mailboxes_ick = {
+	.name = "mailboxes_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mailboxes_ick_data,
+};
+
+static struct ti_clk_gate sha11_ick_data = {
+	.parent = "security_l4_ick2",
+	.bit_shift = 1,
+	.reg = 0xa14,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk sha11_ick = {
+	.name = "sha11_ick",
+	.type = TI_CLK_GATE,
+	.data = &sha11_ick_data,
+};
+
+static struct ti_clk_gate hsotgusb_ick_am35xx_data = {
+	.parent = "ipss_ick",
+	.bit_shift = 0,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+	.flags = CLKF_AM35XX,
+};
+
+static struct ti_clk hsotgusb_ick_am35xx = {
+	.name = "hsotgusb_ick_am35xx",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hsotgusb_ick_am35xx_data,
+};
+
+static struct ti_clk_gate mmchs3_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 30,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mmchs3_fck = {
+	.name = "mmchs3_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs3_fck_data,
+};
+
+static struct ti_clk_divider pclk_fck_data = {
+	.parent = "emu_src_ck",
+	.bit_shift = 8,
+	.max_div = 7,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk pclk_fck = {
+	.name = "pclk_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &pclk_fck_data,
+};
+
+static const char *dpll4_ck_omap36xx_parents[] = {
+	"sys_ck",
+	"sys_ck",
+};
+
+static struct ti_clk_dpll dpll4_ck_omap36xx_data = {
+	.num_parents = ARRAY_SIZE(dpll4_ck_omap36xx_parents),
+	.control_reg = 0xd00,
+	.idlest_reg = 0xd20,
+	.mult_div1_reg = 0xd44,
+	.autoidle_reg = 0xd30,
+	.module = TI_CLKM_CM,
+	.parents = dpll4_ck_omap36xx_parents,
+	.modes = 0x82,
+	.div1_mask = 0x7f,
+	.idlest_mask = 0x2,
+	.auto_recal_bit = 0x13,
+	.max_divider = 0x80,
+	.min_divider = 0x1,
+	.recal_en_bit = 0x6,
+	.max_multiplier = 0xfff,
+	.enable_mask = 0x70000,
+	.mult_mask = 0xfff00,
+	.recal_st_bit = 0x6,
+	.autoidle_mask = 0x38,
+	.sddiv_mask = 0xff000000,
+	.dco_mask = 0xe00000,
+	.flags = CLKF_PER | CLKF_J_TYPE,
+};
+
+static struct ti_clk dpll4_ck_omap36xx = {
+	.name = "dpll4_ck",
+	.type = TI_CLK_DPLL,
+	.data = &dpll4_ck_omap36xx_data,
+	.patch = &dpll4_ck,
+};
+
+static struct ti_clk_gate uart3_fck_data = {
+	.parent = "per_48m_fck",
+	.bit_shift = 11,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk uart3_fck = {
+	.name = "uart3_fck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart3_fck_data,
+};
+
+static struct ti_clk_fixed_factor wkup_32k_fck_data = {
+	.parent = "omap_32k_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk wkup_32k_fck = {
+	.name = "wkup_32k_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &wkup_32k_fck_data,
+};
+
+static struct ti_clk_gate sys_clkout1_data = {
+	.parent = "osc_sys_ck",
+	.bit_shift = 7,
+	.reg = 0xd70,
+	.module = TI_CLKM_PRM,
+};
+
+static struct ti_clk sys_clkout1 = {
+	.name = "sys_clkout1",
+	.type = TI_CLK_GATE,
+	.data = &sys_clkout1_data,
+};
+
+static struct ti_clk_fixed_factor gpmc_fck_data = {
+	.parent = "core_l3_ick",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk gpmc_fck = {
+	.name = "gpmc_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &gpmc_fck_data,
+};
+
+static struct ti_clk_fixed_factor dpll5_m2_d20_ck_data = {
+	.parent = "dpll5_m2_ck",
+	.div = 20,
+	.mult = 1,
+};
+
+static struct ti_clk dpll5_m2_d20_ck = {
+	.name = "dpll5_m2_d20_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll5_m2_d20_ck_data,
+};
+
+static struct ti_clk_gate dpll4_m5x2_ck_omap36xx_data = {
+	.parent = "dpll4_m5x2_mul_ck",
+	.bit_shift = 0x1e,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSDIV | CLKF_SET_RATE_PARENT | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m5x2_ck_omap36xx = {
+	.name = "dpll4_m5x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m5x2_ck_omap36xx_data,
+	.patch = &dpll4_m5x2_ck,
+};
+
+static struct ti_clk_gate ssi_ssr_gate_fck_3430es2_data = {
+	.parent = "corex2_fck",
+	.bit_shift = 0,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_NO_WAIT,
+};
+
+static struct ti_clk_gate uart1_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 13,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk uart1_ick = {
+	.name = "uart1_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart1_ick_data,
+};
+
+static struct ti_clk_gate iva2_ck_data = {
+	.parent = "dpll2_m2_ck",
+	.bit_shift = 0,
+	.reg = 0x0,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk iva2_ck = {
+	.name = "iva2_ck",
+	.clkdm_name = "iva2_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &iva2_ck_data,
+};
+
+static struct ti_clk_gate pka_ick_data = {
+	.parent = "security_l3_ick",
+	.bit_shift = 4,
+	.reg = 0xa14,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk pka_ick = {
+	.name = "pka_ick",
+	.type = TI_CLK_GATE,
+	.data = &pka_ick_data,
+};
+
+static struct ti_clk_gate gpt12_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 1,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt12_ick = {
+	.name = "gpt12_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt12_ick_data,
+};
+
+static const char *mcbsp5_mux_fck_parents[] = {
+	"core_96m_fck",
+	"mcbsp_clks",
+};
+
+static struct ti_clk_mux mcbsp5_mux_fck_data = {
+	.bit_shift = 4,
+	.num_parents = ARRAY_SIZE(mcbsp5_mux_fck_parents),
+	.reg = 0x2d8,
+	.module = TI_CLKM_SCRM,
+	.parents = mcbsp5_mux_fck_parents,
+};
+
+static struct ti_clk_composite mcbsp5_fck_data = {
+	.mux = &mcbsp5_mux_fck_data,
+	.gate = &mcbsp5_gate_fck_data,
+};
+
+static struct ti_clk mcbsp5_fck = {
+	.name = "mcbsp5_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &mcbsp5_fck_data,
+};
+
+static struct ti_clk_gate usbhost_48m_fck_data = {
+	.parent = "omap_48m_fck",
+	.bit_shift = 0,
+	.reg = 0x1400,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_DSS,
+};
+
+static struct ti_clk usbhost_48m_fck = {
+	.name = "usbhost_48m_fck",
+	.clkdm_name = "usbhost_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usbhost_48m_fck_data,
+};
+
+static struct ti_clk_gate des1_ick_data = {
+	.parent = "security_l4_ick2",
+	.bit_shift = 0,
+	.reg = 0xa14,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk des1_ick = {
+	.name = "des1_ick",
+	.type = TI_CLK_GATE,
+	.data = &des1_ick_data,
+};
+
+static struct ti_clk_gate sgx_gate_fck_data = {
+	.parent = "core_ck",
+	.bit_shift = 1,
+	.reg = 0xb00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_fixed_factor core_d4_ck_data = {
+	.parent = "core_ck",
+	.div = 4,
+	.mult = 1,
+};
+
+static struct ti_clk core_d4_ck = {
+	.name = "core_d4_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_d4_ck_data,
+};
+
+static struct ti_clk_fixed_factor omap_192m_alwon_fck_data = {
+	.parent = "dpll4_m2x2_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk omap_192m_alwon_fck = {
+	.name = "omap_192m_alwon_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_192m_alwon_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_d2_ck_data = {
+	.parent = "core_ck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk core_d2_ck = {
+	.name = "core_d2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_d2_ck_data,
+};
+
+static struct ti_clk_fixed_factor corex2_d3_fck_data = {
+	.parent = "corex2_fck",
+	.div = 3,
+	.mult = 1,
+};
+
+static struct ti_clk corex2_d3_fck = {
+	.name = "corex2_d3_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &corex2_d3_fck_data,
+};
+
+static struct ti_clk_fixed_factor corex2_d5_fck_data = {
+	.parent = "corex2_fck",
+	.div = 5,
+	.mult = 1,
+};
+
+static struct ti_clk corex2_d5_fck = {
+	.name = "corex2_d5_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &corex2_d5_fck_data,
+};
+
+static const char *sgx_mux_fck_parents[] = {
+	"core_d3_ck",
+	"core_d4_ck",
+	"core_d6_ck",
+	"cm_96m_fck",
+	"omap_192m_alwon_fck",
+	"core_d2_ck",
+	"corex2_d3_fck",
+	"corex2_d5_fck",
+};
+
+static struct ti_clk_mux sgx_mux_fck_data = {
+	.num_parents = ARRAY_SIZE(sgx_mux_fck_parents),
+	.reg = 0xb40,
+	.module = TI_CLKM_CM,
+	.parents = sgx_mux_fck_parents,
+};
+
+static struct ti_clk_composite sgx_fck_data = {
+	.mux = &sgx_mux_fck_data,
+	.gate = &sgx_gate_fck_data,
+};
+
+static struct ti_clk sgx_fck = {
+	.name = "sgx_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &sgx_fck_data,
+};
+
+static struct ti_clk_gate mcspi1_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 18,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mcspi1_fck = {
+	.name = "mcspi1_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi1_fck_data,
+};
+
+static struct ti_clk_gate mmchs2_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 25,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mmchs2_fck = {
+	.name = "mmchs2_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs2_fck_data,
+};
+
+static struct ti_clk_gate mcspi2_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 19,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mcspi2_fck = {
+	.name = "mcspi2_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi2_fck_data,
+};
+
+static struct ti_clk_gate vpfe_fck_data = {
+	.parent = "pclk_ck",
+	.bit_shift = 10,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+};
+
+static struct ti_clk vpfe_fck = {
+	.name = "vpfe_fck",
+	.type = TI_CLK_GATE,
+	.data = &vpfe_fck_data,
+};
+
+static struct ti_clk_gate gpt4_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 5,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_gate mcbsp1_gate_fck_data = {
+	.parent = "mcbsp_clks",
+	.bit_shift = 9,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_gate gpt5_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 6,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static const char *gpt5_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt5_mux_fck_data = {
+	.bit_shift = 3,
+	.num_parents = ARRAY_SIZE(gpt5_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt5_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt5_fck_data = {
+	.mux = &gpt5_mux_fck_data,
+	.gate = &gpt5_gate_fck_data,
+};
+
+static struct ti_clk gpt5_fck = {
+	.name = "gpt5_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt5_fck_data,
+};
+
+static struct ti_clk_gate ts_fck_data = {
+	.parent = "omap_32k_fck",
+	.bit_shift = 1,
+	.reg = 0xa08,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk ts_fck = {
+	.name = "ts_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &ts_fck_data,
+};
+
+static struct ti_clk_fixed_factor wdt1_fck_data = {
+	.parent = "secure_32k_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk wdt1_fck = {
+	.name = "wdt1_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &wdt1_fck_data,
+};
+
+static struct ti_clk_gate dpll4_m6x2_ck_omap36xx_data = {
+	.parent = "dpll4_m6x2_mul_ck",
+	.bit_shift = 0x1f,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSDIV | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m6x2_ck_omap36xx = {
+	.name = "dpll4_m6x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m6x2_ck_omap36xx_data,
+	.patch = &dpll4_m6x2_ck,
+};
+
+static const char *gpt4_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt4_mux_fck_data = {
+	.bit_shift = 2,
+	.num_parents = ARRAY_SIZE(gpt4_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt4_mux_fck_parents,
+};
+
+static struct ti_clk_gate usbhost_ick_data = {
+	.parent = "l4_ick",
+	.bit_shift = 0,
+	.reg = 0x1410,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_DSS | CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk usbhost_ick = {
+	.name = "usbhost_ick",
+	.clkdm_name = "usbhost_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usbhost_ick_data,
+};
+
+static struct ti_clk_gate mcbsp2_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 0,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcbsp2_ick = {
+	.name = "mcbsp2_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcbsp2_ick_data,
+};
+
+static struct ti_clk_gate omapctrl_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 6,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk omapctrl_ick = {
+	.name = "omapctrl_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &omapctrl_ick_data,
+};
+
+static struct ti_clk_fixed_factor omap_96m_d4_fck_data = {
+	.parent = "omap_96m_fck",
+	.div = 4,
+	.mult = 1,
+};
+
+static struct ti_clk omap_96m_d4_fck = {
+	.name = "omap_96m_d4_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_96m_d4_fck_data,
+};
+
+static struct ti_clk_gate gpt6_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 7,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt6_ick = {
+	.name = "gpt6_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt6_ick_data,
+};
+
+static struct ti_clk_gate dpll3_m3x2_ck_omap36xx_data = {
+	.parent = "dpll3_m3x2_mul_ck",
+	.bit_shift = 0xc,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSDIV | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll3_m3x2_ck_omap36xx = {
+	.name = "dpll3_m3x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll3_m3x2_ck_omap36xx_data,
+	.patch = &dpll3_m3x2_ck,
+};
+
+static struct ti_clk_gate i2c3_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 17,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk i2c3_ick = {
+	.name = "i2c3_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c3_ick_data,
+};
+
+static struct ti_clk_gate gpio6_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 17,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio6_ick = {
+	.name = "gpio6_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio6_ick_data,
+};
+
+static struct ti_clk_gate mspro_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 23,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mspro_ick = {
+	.name = "mspro_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mspro_ick_data,
+};
+
+static struct ti_clk_composite mcbsp1_fck_data = {
+	.mux = &mcbsp1_mux_fck_data,
+	.gate = &mcbsp1_gate_fck_data,
+};
+
+static struct ti_clk mcbsp1_fck = {
+	.name = "mcbsp1_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &mcbsp1_fck_data,
+};
+
+static struct ti_clk_gate gpt3_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 4,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_fixed rmii_ck_data = {
+	.frequency = 50000000,
+};
+
+static struct ti_clk rmii_ck = {
+	.name = "rmii_ck",
+	.type = TI_CLK_FIXED,
+	.data = &rmii_ck_data,
+};
+
+static struct ti_clk_gate gpt6_gate_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 7,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_composite gpt6_fck_data = {
+	.mux = &gpt6_mux_fck_data,
+	.gate = &gpt6_gate_fck_data,
+};
+
+static struct ti_clk gpt6_fck = {
+	.name = "gpt6_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt6_fck_data,
+};
+
+static struct ti_clk_fixed_factor dpll5_m2_d4_ck_data = {
+	.parent = "dpll5_m2_ck",
+	.div = 4,
+	.mult = 1,
+};
+
+static struct ti_clk dpll5_m2_d4_ck = {
+	.name = "dpll5_m2_d4_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll5_m2_d4_ck_data,
+};
+
+static struct ti_clk_fixed_factor sys_d2_ck_data = {
+	.parent = "sys_ck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk sys_d2_ck = {
+	.name = "sys_d2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &sys_d2_ck_data,
+};
+
+static struct ti_clk_fixed_factor omap_96m_d2_fck_data = {
+	.parent = "omap_96m_fck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk omap_96m_d2_fck = {
+	.name = "omap_96m_d2_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_96m_d2_fck_data,
+};
+
+static struct ti_clk_fixed_factor dpll5_m2_d8_ck_data = {
+	.parent = "dpll5_m2_ck",
+	.div = 8,
+	.mult = 1,
+};
+
+static struct ti_clk dpll5_m2_d8_ck = {
+	.name = "dpll5_m2_d8_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll5_m2_d8_ck_data,
+};
+
+static struct ti_clk_fixed_factor dpll5_m2_d16_ck_data = {
+	.parent = "dpll5_m2_ck",
+	.div = 16,
+	.mult = 1,
+};
+
+static struct ti_clk dpll5_m2_d16_ck = {
+	.name = "dpll5_m2_d16_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll5_m2_d16_ck_data,
+};
+
+static const char *usim_mux_fck_parents[] = {
+	"sys_ck",
+	"sys_d2_ck",
+	"omap_96m_d2_fck",
+	"omap_96m_d4_fck",
+	"omap_96m_d8_fck",
+	"omap_96m_d10_fck",
+	"dpll5_m2_d4_ck",
+	"dpll5_m2_d8_ck",
+	"dpll5_m2_d16_ck",
+	"dpll5_m2_d20_ck",
+};
+
+static struct ti_clk_mux usim_mux_fck_data = {
+	.bit_shift = 3,
+	.num_parents = ARRAY_SIZE(usim_mux_fck_parents),
+	.reg = 0xc40,
+	.module = TI_CLKM_CM,
+	.parents = usim_mux_fck_parents,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk_composite usim_fck_data = {
+	.mux = &usim_mux_fck_data,
+	.gate = &usim_gate_fck_data,
+};
+
+static struct ti_clk usim_fck = {
+	.name = "usim_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &usim_fck_data,
+};
+
+static int ssi_ssr_div_fck_3430es2_divs[] = {
+	0,
+	1,
+	2,
+	3,
+	4,
+	0,
+	6,
+	0,
+	8,
+};
+
+static struct ti_clk_divider ssi_ssr_div_fck_3430es2_data = {
+	.num_dividers = ARRAY_SIZE(ssi_ssr_div_fck_3430es2_divs),
+	.parent = "corex2_fck",
+	.bit_shift = 8,
+	.dividers = ssi_ssr_div_fck_3430es2_divs,
+	.reg = 0xa40,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_composite ssi_ssr_fck_3430es2_data = {
+	.gate = &ssi_ssr_gate_fck_3430es2_data,
+	.divider = &ssi_ssr_div_fck_3430es2_data,
+};
+
+static struct ti_clk ssi_ssr_fck_3430es2 = {
+	.name = "ssi_ssr_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &ssi_ssr_fck_3430es2_data,
+};
+
+static struct ti_clk_gate dss1_alwon_fck_3430es1_data = {
+	.parent = "dpll4_m4x2_ck",
+	.bit_shift = 0,
+	.reg = 0xe00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SET_RATE_PARENT,
+};
+
+static struct ti_clk dss1_alwon_fck_3430es1 = {
+	.name = "dss1_alwon_fck",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss1_alwon_fck_3430es1_data,
+};
+
+static struct ti_clk_gate gpt3_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 4,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt3_ick = {
+	.name = "gpt3_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt3_ick_data,
+};
+
+static struct ti_clk_fixed_factor omap_12m_fck_data = {
+	.parent = "omap_48m_fck",
+	.div = 4,
+	.mult = 1,
+};
+
+static struct ti_clk omap_12m_fck = {
+	.name = "omap_12m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &omap_12m_fck_data,
+};
+
+static struct ti_clk_fixed_factor core_12m_fck_data = {
+	.parent = "omap_12m_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk core_12m_fck = {
+	.name = "core_12m_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &core_12m_fck_data,
+};
+
+static struct ti_clk_gate hdq_fck_data = {
+	.parent = "core_12m_fck",
+	.bit_shift = 22,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk hdq_fck = {
+	.name = "hdq_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hdq_fck_data,
+};
+
+static struct ti_clk_gate usbtll_fck_data = {
+	.parent = "dpll5_m2_ck",
+	.bit_shift = 2,
+	.reg = 0xa08,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk usbtll_fck = {
+	.name = "usbtll_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usbtll_fck_data,
+};
+
+static struct ti_clk_gate hsotgusb_fck_am35xx_data = {
+	.parent = "sys_ck",
+	.bit_shift = 8,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+};
+
+static struct ti_clk hsotgusb_fck_am35xx = {
+	.name = "hsotgusb_fck_am35xx",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hsotgusb_fck_am35xx_data,
+};
+
+static struct ti_clk_gate hsotgusb_ick_3430es2_data = {
+	.parent = "core_l3_ick",
+	.bit_shift = 4,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSOTGUSB | CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk hsotgusb_ick_3430es2 = {
+	.name = "hsotgusb_ick_3430es2",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hsotgusb_ick_3430es2_data,
+};
+
+static struct ti_clk_gate gfx_l3_ck_data = {
+	.parent = "l3_ick",
+	.bit_shift = 0,
+	.reg = 0xb10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk gfx_l3_ck = {
+	.name = "gfx_l3_ck",
+	.clkdm_name = "gfx_3430es1_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gfx_l3_ck_data,
+};
+
+static struct ti_clk_fixed_factor gfx_l3_ick_data = {
+	.parent = "gfx_l3_ck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk gfx_l3_ick = {
+	.name = "gfx_l3_ick",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &gfx_l3_ick_data,
+};
+
+static struct ti_clk_gate mcbsp1_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 9,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcbsp1_ick = {
+	.name = "mcbsp1_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcbsp1_ick_data,
+};
+
+static struct ti_clk_fixed_factor gpt12_fck_data = {
+	.parent = "secure_32k_fck",
+	.div = 1,
+	.mult = 1,
+};
+
+static struct ti_clk gpt12_fck = {
+	.name = "gpt12_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &gpt12_fck_data,
+};
+
+static struct ti_clk_gate gfx_cg2_ck_data = {
+	.parent = "gfx_l3_fck",
+	.bit_shift = 2,
+	.reg = 0xb00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk gfx_cg2_ck = {
+	.name = "gfx_cg2_ck",
+	.clkdm_name = "gfx_3430es1_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gfx_cg2_ck_data,
+};
+
+static struct ti_clk_gate i2c2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 16,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk i2c2_ick = {
+	.name = "i2c2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c2_ick_data,
+};
+
+static struct ti_clk_gate gpio4_dbck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 15,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio4_dbck = {
+	.name = "gpio4_dbck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio4_dbck_data,
+};
+
+static struct ti_clk_gate i2c3_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 17,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk i2c3_fck = {
+	.name = "i2c3_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c3_fck_data,
+};
+
+static struct ti_clk_composite gpt3_fck_data = {
+	.mux = &gpt3_mux_fck_data,
+	.gate = &gpt3_gate_fck_data,
+};
+
+static struct ti_clk gpt3_fck = {
+	.name = "gpt3_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt3_fck_data,
+};
+
+static struct ti_clk_gate i2c1_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 15,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk i2c1_ick = {
+	.name = "i2c1_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &i2c1_ick_data,
+};
+
+static struct ti_clk_gate omap_32ksync_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 2,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk omap_32ksync_ick = {
+	.name = "omap_32ksync_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &omap_32ksync_ick_data,
+};
+
+static struct ti_clk_gate aes2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 28,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk aes2_ick = {
+	.name = "aes2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &aes2_ick_data,
+};
+
+static const char *gpt8_mux_fck_parents[] = {
+	"omap_32k_fck",
+	"sys_ck",
+};
+
+static struct ti_clk_mux gpt8_mux_fck_data = {
+	.bit_shift = 6,
+	.num_parents = ARRAY_SIZE(gpt8_mux_fck_parents),
+	.reg = 0x1040,
+	.module = TI_CLKM_CM,
+	.parents = gpt8_mux_fck_parents,
+};
+
+static struct ti_clk_composite gpt8_fck_data = {
+	.mux = &gpt8_mux_fck_data,
+	.gate = &gpt8_gate_fck_data,
+};
+
+static struct ti_clk gpt8_fck = {
+	.name = "gpt8_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt8_fck_data,
+};
+
+static struct ti_clk_gate mcbsp4_gate_fck_data = {
+	.parent = "mcbsp_clks",
+	.bit_shift = 2,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk_composite mcbsp4_fck_data = {
+	.mux = &mcbsp4_mux_fck_data,
+	.gate = &mcbsp4_gate_fck_data,
+};
+
+static struct ti_clk mcbsp4_fck = {
+	.name = "mcbsp4_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &mcbsp4_fck_data,
+};
+
+static struct ti_clk_gate gpio2_dbck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 13,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio2_dbck = {
+	.name = "gpio2_dbck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio2_dbck_data,
+};
+
+static struct ti_clk_gate usbtll_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 2,
+	.reg = 0xa18,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk usbtll_ick = {
+	.name = "usbtll_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &usbtll_ick_data,
+};
+
+static struct ti_clk_gate mcspi4_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 21,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcspi4_ick = {
+	.name = "mcspi4_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi4_ick_data,
+};
+
+static struct ti_clk_gate dss_96m_fck_data = {
+	.parent = "omap_96m_fck",
+	.bit_shift = 2,
+	.reg = 0xe00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk dss_96m_fck = {
+	.name = "dss_96m_fck",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss_96m_fck_data,
+};
+
+static struct ti_clk_divider rm_ick_data = {
+	.parent = "l4_ick",
+	.bit_shift = 1,
+	.max_div = 3,
+	.reg = 0xc40,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk rm_ick = {
+	.name = "rm_ick",
+	.type = TI_CLK_DIVIDER,
+	.data = &rm_ick_data,
+};
+
+static struct ti_clk_gate hdq_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 22,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk hdq_ick = {
+	.name = "hdq_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &hdq_ick_data,
+};
+
+static struct ti_clk_fixed_factor dpll3_x2_ck_data = {
+	.parent = "dpll3_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll3_x2_ck = {
+	.name = "dpll3_x2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll3_x2_ck_data,
+};
+
+static struct ti_clk_gate mad2d_ick_data = {
+	.parent = "l3_ick",
+	.bit_shift = 3,
+	.reg = 0xa18,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mad2d_ick = {
+	.name = "mad2d_ick",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mad2d_ick_data,
+};
+
+static struct ti_clk_gate fshostusb_fck_data = {
+	.parent = "core_48m_fck",
+	.bit_shift = 5,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk fshostusb_fck = {
+	.name = "fshostusb_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &fshostusb_fck_data,
+};
+
+static struct ti_clk_gate sr1_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 6,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk sr1_fck = {
+	.name = "sr1_fck",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sr1_fck_data,
+};
+
+static struct ti_clk_gate des2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 26,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk des2_ick = {
+	.name = "des2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &des2_ick_data,
+};
+
+static struct ti_clk_gate sdrc_ick_data = {
+	.parent = "core_l3_ick",
+	.bit_shift = 1,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk sdrc_ick = {
+	.name = "sdrc_ick",
+	.clkdm_name = "core_l3_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sdrc_ick_data,
+};
+
+static struct ti_clk_composite gpt4_fck_data = {
+	.mux = &gpt4_mux_fck_data,
+	.gate = &gpt4_gate_fck_data,
+};
+
+static struct ti_clk gpt4_fck = {
+	.name = "gpt4_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt4_fck_data,
+};
+
+static struct ti_clk_gate dpll4_m3x2_ck_omap36xx_data = {
+	.parent = "dpll4_m3x2_mul_ck",
+	.bit_shift = 0x1c,
+	.reg = 0xd00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_HSDIV | CLKF_SET_BIT_TO_DISABLE,
+};
+
+static struct ti_clk dpll4_m3x2_ck_omap36xx = {
+	.name = "dpll4_m3x2_ck",
+	.type = TI_CLK_GATE,
+	.data = &dpll4_m3x2_ck_omap36xx_data,
+	.patch = &dpll4_m3x2_ck,
+};
+
+static struct ti_clk_gate cpefuse_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 0,
+	.reg = 0xa08,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk cpefuse_fck = {
+	.name = "cpefuse_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &cpefuse_fck_data,
+};
+
+static struct ti_clk_gate mcspi3_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 20,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcspi3_ick = {
+	.name = "mcspi3_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi3_ick_data,
+};
+
+static struct ti_clk_fixed_factor ssi_sst_fck_3430es2_data = {
+	.parent = "ssi_ssr_fck",
+	.div = 2,
+	.mult = 1,
+};
+
+static struct ti_clk ssi_sst_fck_3430es2 = {
+	.name = "ssi_sst_fck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &ssi_sst_fck_3430es2_data,
+};
+
+static struct ti_clk_gate gpio1_dbck_data = {
+	.parent = "wkup_32k_fck",
+	.bit_shift = 3,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio1_dbck = {
+	.name = "gpio1_dbck",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio1_dbck_data,
+};
+
+static struct ti_clk_gate gpt4_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 5,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt4_ick = {
+	.name = "gpt4_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt4_ick_data,
+};
+
+static struct ti_clk_gate gpt2_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 3,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt2_ick = {
+	.name = "gpt2_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt2_ick_data,
+};
+
+static struct ti_clk_gate mmchs1_fck_data = {
+	.parent = "core_96m_fck",
+	.bit_shift = 24,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk mmchs1_fck = {
+	.name = "mmchs1_fck",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mmchs1_fck_data,
+};
+
+static struct ti_clk_fixed dummy_apb_pclk_data = {
+	.frequency = 0x0,
+};
+
+static struct ti_clk dummy_apb_pclk = {
+	.name = "dummy_apb_pclk",
+	.type = TI_CLK_FIXED,
+	.data = &dummy_apb_pclk_data,
+};
+
+static struct ti_clk_gate gpio6_dbck_data = {
+	.parent = "per_32k_alwon_fck",
+	.bit_shift = 17,
+	.reg = 0x1000,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk gpio6_dbck = {
+	.name = "gpio6_dbck",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio6_dbck_data,
+};
+
+static struct ti_clk_gate uart2_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 14,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk uart2_ick = {
+	.name = "uart2_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &uart2_ick_data,
+};
+
+static struct ti_clk_fixed_factor dpll4_x2_ck_data = {
+	.parent = "dpll4_ck",
+	.div = 1,
+	.mult = 2,
+};
+
+static struct ti_clk dpll4_x2_ck = {
+	.name = "dpll4_x2_ck",
+	.type = TI_CLK_FIXED_FACTOR,
+	.data = &dpll4_x2_ck_data,
+};
+
+static struct ti_clk_gate gpt7_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 8,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpt7_ick = {
+	.name = "gpt7_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpt7_ick_data,
+};
+
+static struct ti_clk_gate dss_tv_fck_data = {
+	.parent = "omap_54m_fck",
+	.bit_shift = 2,
+	.reg = 0xe00,
+	.module = TI_CLKM_CM,
+};
+
+static struct ti_clk dss_tv_fck = {
+	.name = "dss_tv_fck",
+	.clkdm_name = "dss_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &dss_tv_fck_data,
+};
+
+static struct ti_clk_gate mcbsp5_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 10,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcbsp5_ick = {
+	.name = "mcbsp5_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcbsp5_ick_data,
+};
+
+static struct ti_clk_gate mcspi1_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 18,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk mcspi1_ick = {
+	.name = "mcspi1_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &mcspi1_ick_data,
+};
+
+static struct ti_clk_gate d2d_26m_fck_data = {
+	.parent = "sys_ck",
+	.bit_shift = 3,
+	.reg = 0xa00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk d2d_26m_fck = {
+	.name = "d2d_26m_fck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &d2d_26m_fck_data,
+};
+
+static struct ti_clk_gate wdt3_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 12,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk wdt3_ick = {
+	.name = "wdt3_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &wdt3_ick_data,
+};
+
+static struct ti_clk_divider pclkx2_fck_data = {
+	.parent = "emu_src_ck",
+	.bit_shift = 6,
+	.max_div = 3,
+	.reg = 0x1140,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_STARTS_AT_ONE,
+};
+
+static struct ti_clk pclkx2_fck = {
+	.name = "pclkx2_fck",
+	.type = TI_CLK_DIVIDER,
+	.data = &pclkx2_fck_data,
+};
+
+static struct ti_clk_gate sha12_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 27,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk sha12_ick = {
+	.name = "sha12_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sha12_ick_data,
+};
+
+static struct ti_clk_gate emac_fck_data = {
+	.parent = "rmii_ck",
+	.bit_shift = 9,
+	.reg = 0x59c,
+	.module = TI_CLKM_SCRM,
+};
+
+static struct ti_clk emac_fck = {
+	.name = "emac_fck",
+	.type = TI_CLK_GATE,
+	.data = &emac_fck_data,
+};
+
+static struct ti_clk_composite gpt10_fck_data = {
+	.mux = &gpt10_mux_fck_data,
+	.gate = &gpt10_gate_fck_data,
+};
+
+static struct ti_clk gpt10_fck = {
+	.name = "gpt10_fck",
+	.type = TI_CLK_COMPOSITE,
+	.data = &gpt10_fck_data,
+};
+
+static struct ti_clk_gate wdt2_fck_data = {
+	.parent = "wkup_32k_fck",
+	.bit_shift = 5,
+	.reg = 0xc00,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk wdt2_fck = {
+	.name = "wdt2_fck",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &wdt2_fck_data,
+};
+
+static struct ti_clk_gate cam_ick_data = {
+	.parent = "l4_ick",
+	.bit_shift = 0,
+	.reg = 0xf10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_NO_WAIT | CLKF_INTERFACE,
+};
+
+static struct ti_clk cam_ick = {
+	.name = "cam_ick",
+	.clkdm_name = "cam_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &cam_ick_data,
+};
+
+static struct ti_clk_gate ssi_ick_3430es2_data = {
+	.parent = "ssi_l4_ick",
+	.bit_shift = 0,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_SSI | CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk ssi_ick_3430es2 = {
+	.name = "ssi_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &ssi_ick_3430es2_data,
+};
+
+static struct ti_clk_gate gpio4_ick_data = {
+	.parent = "per_l4_ick",
+	.bit_shift = 15,
+	.reg = 0x1010,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk gpio4_ick = {
+	.name = "gpio4_ick",
+	.clkdm_name = "per_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &gpio4_ick_data,
+};
+
+static struct ti_clk_gate wdt1_ick_data = {
+	.parent = "wkup_l4_ick",
+	.bit_shift = 4,
+	.reg = 0xc10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk wdt1_ick = {
+	.name = "wdt1_ick",
+	.clkdm_name = "wkup_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &wdt1_ick_data,
+};
+
+static struct ti_clk_gate rng_ick_data = {
+	.parent = "security_l4_ick2",
+	.bit_shift = 2,
+	.reg = 0xa14,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk rng_ick = {
+	.name = "rng_ick",
+	.type = TI_CLK_GATE,
+	.data = &rng_ick_data,
+};
+
+static struct ti_clk_gate icr_ick_data = {
+	.parent = "core_l4_ick",
+	.bit_shift = 29,
+	.reg = 0xa10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_OMAP3 | CLKF_INTERFACE,
+};
+
+static struct ti_clk icr_ick = {
+	.name = "icr_ick",
+	.clkdm_name = "core_l4_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &icr_ick_data,
+};
+
+static struct ti_clk_gate sgx_ick_data = {
+	.parent = "l3_ick",
+	.bit_shift = 0,
+	.reg = 0xb10,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_WAIT,
+};
+
+static struct ti_clk sgx_ick = {
+	.name = "sgx_ick",
+	.clkdm_name = "sgx_clkdm",
+	.type = TI_CLK_GATE,
+	.data = &sgx_ick_data,
+};
+
+static struct ti_clk_divider sys_clkout2_data = {
+	.parent = "clkout2_src_ck",
+	.bit_shift = 3,
+	.max_div = 64,
+	.reg = 0xd70,
+	.module = TI_CLKM_CM,
+	.flags = CLKF_INDEX_POWER_OF_TWO,
+};
+
+static struct ti_clk sys_clkout2 = {
+	.name = "sys_clkout2",
+	.type = TI_CLK_DIVIDER,
+	.data = &sys_clkout2_data,
+};
+
+static struct ti_clk_alias omap34xx_omap36xx_clks[] = {
+	CLK(NULL, "security_l4_ick2", &security_l4_ick2),
+	CLK(NULL, "aes1_ick", &aes1_ick),
+	CLK("omap_rng", "ick", &rng_ick),
+	CLK("omap3-rom-rng", "ick", &rng_ick),
+	CLK(NULL, "sha11_ick", &sha11_ick),
+	CLK(NULL, "des1_ick", &des1_ick),
+	CLK(NULL, "cam_mclk", &cam_mclk),
+	CLK(NULL, "cam_ick", &cam_ick),
+	CLK(NULL, "csi2_96m_fck", &csi2_96m_fck),
+	CLK(NULL, "security_l3_ick", &security_l3_ick),
+	CLK(NULL, "pka_ick", &pka_ick),
+	CLK(NULL, "icr_ick", &icr_ick),
+	CLK(NULL, "des2_ick", &des2_ick),
+	CLK(NULL, "mspro_ick", &mspro_ick),
+	CLK(NULL, "mailboxes_ick", &mailboxes_ick),
+	CLK(NULL, "ssi_l4_ick", &ssi_l4_ick),
+	CLK(NULL, "sr1_fck", &sr1_fck),
+	CLK(NULL, "sr2_fck", &sr2_fck),
+	CLK(NULL, "sr_l4_ick", &sr_l4_ick),
+	CLK(NULL, "dpll2_fck", &dpll2_fck),
+	CLK(NULL, "dpll2_ck", &dpll2_ck),
+	CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck),
+	CLK(NULL, "iva2_ck", &iva2_ck),
+	CLK(NULL, "modem_fck", &modem_fck),
+	CLK(NULL, "sad2d_ick", &sad2d_ick),
+	CLK(NULL, "mad2d_ick", &mad2d_ick),
+	CLK(NULL, "mspro_fck", &mspro_fck),
+	{ NULL },
+};
+
+static struct ti_clk_alias omap36xx_omap3430es2plus_clks[] = {
+	CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2),
+	CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2),
+	CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es2),
+	CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es2),
+	CLK(NULL, "ssi_ick", &ssi_ick_3430es2),
+	CLK(NULL, "sys_d2_ck", &sys_d2_ck),
+	CLK(NULL, "omap_96m_d2_fck", &omap_96m_d2_fck),
+	CLK(NULL, "omap_96m_d4_fck", &omap_96m_d4_fck),
+	CLK(NULL, "omap_96m_d8_fck", &omap_96m_d8_fck),
+	CLK(NULL, "omap_96m_d10_fck", &omap_96m_d10_fck),
+	CLK(NULL, "dpll5_m2_d4_ck", &dpll5_m2_d4_ck),
+	CLK(NULL, "dpll5_m2_d8_ck", &dpll5_m2_d8_ck),
+	CLK(NULL, "dpll5_m2_d16_ck", &dpll5_m2_d16_ck),
+	CLK(NULL, "dpll5_m2_d20_ck", &dpll5_m2_d20_ck),
+	CLK(NULL, "usim_fck", &usim_fck),
+	CLK(NULL, "usim_ick", &usim_ick),
+	{ NULL },
+};
+
+static struct ti_clk_alias omap3xxx_clks[] = {
+	CLK(NULL, "apb_pclk", &dummy_apb_pclk),
+	CLK(NULL, "omap_32k_fck", &omap_32k_fck),
+	CLK(NULL, "virt_12m_ck", &virt_12m_ck),
+	CLK(NULL, "virt_13m_ck", &virt_13m_ck),
+	CLK(NULL, "virt_19200000_ck", &virt_19200000_ck),
+	CLK(NULL, "virt_26000000_ck", &virt_26000000_ck),
+	CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck),
+	CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck),
+	CLK(NULL, "osc_sys_ck", &osc_sys_ck),
+	CLK("twl", "fck", &osc_sys_ck),
+	CLK(NULL, "sys_ck", &sys_ck),
+	CLK(NULL, "timer_sys_ck", &sys_ck),
+	CLK(NULL, "dpll4_ck", &dpll4_ck),
+	CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck),
+	CLK(NULL, "dpll4_m2x2_mul_ck", &dpll4_m2x2_mul_ck),
+	CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck),
+	CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck),
+	CLK(NULL, "dpll3_ck", &dpll3_ck),
+	CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck),
+	CLK(NULL, "dpll3_m3x2_mul_ck", &dpll3_m3x2_mul_ck),
+	CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck),
+	CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck),
+	CLK(NULL, "sys_altclk", &sys_altclk),
+	CLK(NULL, "mcbsp_clks", &mcbsp_clks),
+	CLK(NULL, "sys_clkout1", &sys_clkout1),
+	CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck),
+	CLK(NULL, "core_ck", &core_ck),
+	CLK(NULL, "dpll1_fck", &dpll1_fck),
+	CLK(NULL, "dpll1_ck", &dpll1_ck),
+	CLK(NULL, "cpufreq_ck", &dpll1_ck),
+	CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck),
+	CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck),
+	CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck),
+	CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck),
+	CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck),
+	CLK(NULL, "cm_96m_fck", &cm_96m_fck),
+	CLK(NULL, "omap_96m_fck", &omap_96m_fck),
+	CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck),
+	CLK(NULL, "dpll4_m3x2_mul_ck", &dpll4_m3x2_mul_ck),
+	CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck),
+	CLK(NULL, "omap_54m_fck", &omap_54m_fck),
+	CLK(NULL, "cm_96m_d2_fck", &cm_96m_d2_fck),
+	CLK(NULL, "omap_48m_fck", &omap_48m_fck),
+	CLK(NULL, "omap_12m_fck", &omap_12m_fck),
+	CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck),
+	CLK(NULL, "dpll4_m4x2_mul_ck", &dpll4_m4x2_mul_ck),
+	CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck),
+	CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck),
+	CLK(NULL, "dpll4_m5x2_mul_ck", &dpll4_m5x2_mul_ck),
+	CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck),
+	CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck),
+	CLK(NULL, "dpll4_m6x2_mul_ck", &dpll4_m6x2_mul_ck),
+	CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck),
+	CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck),
+	CLK(NULL, "clkout2_src_ck", &clkout2_src_ck),
+	CLK(NULL, "sys_clkout2", &sys_clkout2),
+	CLK(NULL, "corex2_fck", &corex2_fck),
+	CLK(NULL, "mpu_ck", &mpu_ck),
+	CLK(NULL, "arm_fck", &arm_fck),
+	CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck),
+	CLK(NULL, "l3_ick", &l3_ick),
+	CLK(NULL, "l4_ick", &l4_ick),
+	CLK(NULL, "rm_ick", &rm_ick),
+	CLK(NULL, "timer_32k_ck", &omap_32k_fck),
+	CLK(NULL, "gpt10_fck", &gpt10_fck),
+	CLK(NULL, "gpt11_fck", &gpt11_fck),
+	CLK(NULL, "core_96m_fck", &core_96m_fck),
+	CLK(NULL, "mmchs2_fck", &mmchs2_fck),
+	CLK(NULL, "mmchs1_fck", &mmchs1_fck),
+	CLK(NULL, "i2c3_fck", &i2c3_fck),
+	CLK(NULL, "i2c2_fck", &i2c2_fck),
+	CLK(NULL, "i2c1_fck", &i2c1_fck),
+	CLK(NULL, "mcbsp5_fck", &mcbsp5_fck),
+	CLK(NULL, "mcbsp1_fck", &mcbsp1_fck),
+	CLK(NULL, "core_48m_fck", &core_48m_fck),
+	CLK(NULL, "mcspi4_fck", &mcspi4_fck),
+	CLK(NULL, "mcspi3_fck", &mcspi3_fck),
+	CLK(NULL, "mcspi2_fck", &mcspi2_fck),
+	CLK(NULL, "mcspi1_fck", &mcspi1_fck),
+	CLK(NULL, "uart2_fck", &uart2_fck),
+	CLK(NULL, "uart1_fck", &uart1_fck),
+	CLK(NULL, "core_12m_fck", &core_12m_fck),
+	CLK("omap_hdq.0", "fck", &hdq_fck),
+	CLK(NULL, "hdq_fck", &hdq_fck),
+	CLK(NULL, "core_l3_ick", &core_l3_ick),
+	CLK(NULL, "sdrc_ick", &sdrc_ick),
+	CLK(NULL, "gpmc_fck", &gpmc_fck),
+	CLK(NULL, "core_l4_ick", &core_l4_ick),
+	CLK("omap_hsmmc.1", "ick", &mmchs2_ick),
+	CLK("omap_hsmmc.0", "ick", &mmchs1_ick),
+	CLK(NULL, "mmchs2_ick", &mmchs2_ick),
+	CLK(NULL, "mmchs1_ick", &mmchs1_ick),
+	CLK("omap_hdq.0", "ick", &hdq_ick),
+	CLK(NULL, "hdq_ick", &hdq_ick),
+	CLK("omap2_mcspi.4", "ick", &mcspi4_ick),
+	CLK("omap2_mcspi.3", "ick", &mcspi3_ick),
+	CLK("omap2_mcspi.2", "ick", &mcspi2_ick),
+	CLK("omap2_mcspi.1", "ick", &mcspi1_ick),
+	CLK(NULL, "mcspi4_ick", &mcspi4_ick),
+	CLK(NULL, "mcspi3_ick", &mcspi3_ick),
+	CLK(NULL, "mcspi2_ick", &mcspi2_ick),
+	CLK(NULL, "mcspi1_ick", &mcspi1_ick),
+	CLK("omap_i2c.3", "ick", &i2c3_ick),
+	CLK("omap_i2c.2", "ick", &i2c2_ick),
+	CLK("omap_i2c.1", "ick", &i2c1_ick),
+	CLK(NULL, "i2c3_ick", &i2c3_ick),
+	CLK(NULL, "i2c2_ick", &i2c2_ick),
+	CLK(NULL, "i2c1_ick", &i2c1_ick),
+	CLK(NULL, "uart2_ick", &uart2_ick),
+	CLK(NULL, "uart1_ick", &uart1_ick),
+	CLK(NULL, "gpt11_ick", &gpt11_ick),
+	CLK(NULL, "gpt10_ick", &gpt10_ick),
+	CLK("omap-mcbsp.5", "ick", &mcbsp5_ick),
+	CLK("omap-mcbsp.1", "ick", &mcbsp1_ick),
+	CLK(NULL, "mcbsp5_ick", &mcbsp5_ick),
+	CLK(NULL, "mcbsp1_ick", &mcbsp1_ick),
+	CLK(NULL, "omapctrl_ick", &omapctrl_ick),
+	CLK(NULL, "dss_tv_fck", &dss_tv_fck),
+	CLK(NULL, "dss_96m_fck", &dss_96m_fck),
+	CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck),
+	CLK(NULL, "init_60m_fclk", &dummy_ck),
+	CLK(NULL, "gpt1_fck", &gpt1_fck),
+	CLK(NULL, "aes2_ick", &aes2_ick),
+	CLK(NULL, "wkup_32k_fck", &wkup_32k_fck),
+	CLK(NULL, "gpio1_dbck", &gpio1_dbck),
+	CLK(NULL, "sha12_ick", &sha12_ick),
+	CLK(NULL, "wdt2_fck", &wdt2_fck),
+	CLK(NULL, "wkup_l4_ick", &wkup_l4_ick),
+	CLK("omap_wdt", "ick", &wdt2_ick),
+	CLK(NULL, "wdt2_ick", &wdt2_ick),
+	CLK(NULL, "wdt1_ick", &wdt1_ick),
+	CLK(NULL, "gpio1_ick", &gpio1_ick),
+	CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick),
+	CLK(NULL, "gpt12_ick", &gpt12_ick),
+	CLK(NULL, "gpt1_ick", &gpt1_ick),
+	CLK(NULL, "per_96m_fck", &per_96m_fck),
+	CLK(NULL, "per_48m_fck", &per_48m_fck),
+	CLK(NULL, "uart3_fck", &uart3_fck),
+	CLK(NULL, "gpt2_fck", &gpt2_fck),
+	CLK(NULL, "gpt3_fck", &gpt3_fck),
+	CLK(NULL, "gpt4_fck", &gpt4_fck),
+	CLK(NULL, "gpt5_fck", &gpt5_fck),
+	CLK(NULL, "gpt6_fck", &gpt6_fck),
+	CLK(NULL, "gpt7_fck", &gpt7_fck),
+	CLK(NULL, "gpt8_fck", &gpt8_fck),
+	CLK(NULL, "gpt9_fck", &gpt9_fck),
+	CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck),
+	CLK(NULL, "gpio6_dbck", &gpio6_dbck),
+	CLK(NULL, "gpio5_dbck", &gpio5_dbck),
+	CLK(NULL, "gpio4_dbck", &gpio4_dbck),
+	CLK(NULL, "gpio3_dbck", &gpio3_dbck),
+	CLK(NULL, "gpio2_dbck", &gpio2_dbck),
+	CLK(NULL, "wdt3_fck", &wdt3_fck),
+	CLK(NULL, "per_l4_ick", &per_l4_ick),
+	CLK(NULL, "gpio6_ick", &gpio6_ick),
+	CLK(NULL, "gpio5_ick", &gpio5_ick),
+	CLK(NULL, "gpio4_ick", &gpio4_ick),
+	CLK(NULL, "gpio3_ick", &gpio3_ick),
+	CLK(NULL, "gpio2_ick", &gpio2_ick),
+	CLK(NULL, "wdt3_ick", &wdt3_ick),
+	CLK(NULL, "uart3_ick", &uart3_ick),
+	CLK(NULL, "uart4_ick", &uart4_ick),
+	CLK(NULL, "gpt9_ick", &gpt9_ick),
+	CLK(NULL, "gpt8_ick", &gpt8_ick),
+	CLK(NULL, "gpt7_ick", &gpt7_ick),
+	CLK(NULL, "gpt6_ick", &gpt6_ick),
+	CLK(NULL, "gpt5_ick", &gpt5_ick),
+	CLK(NULL, "gpt4_ick", &gpt4_ick),
+	CLK(NULL, "gpt3_ick", &gpt3_ick),
+	CLK(NULL, "gpt2_ick", &gpt2_ick),
+	CLK("omap-mcbsp.2", "ick", &mcbsp2_ick),
+	CLK("omap-mcbsp.3", "ick", &mcbsp3_ick),
+	CLK("omap-mcbsp.4", "ick", &mcbsp4_ick),
+	CLK(NULL, "mcbsp4_ick", &mcbsp2_ick),
+	CLK(NULL, "mcbsp3_ick", &mcbsp3_ick),
+	CLK(NULL, "mcbsp2_ick", &mcbsp4_ick),
+	CLK(NULL, "mcbsp2_fck", &mcbsp2_fck),
+	CLK(NULL, "mcbsp3_fck", &mcbsp3_fck),
+	CLK(NULL, "mcbsp4_fck", &mcbsp4_fck),
+	CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
+	CLK("etb", "emu_src_ck", &emu_src_ck),
+	CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
+	CLK(NULL, "emu_src_ck", &emu_src_ck),
+	CLK(NULL, "pclk_fck", &pclk_fck),
+	CLK(NULL, "pclkx2_fck", &pclkx2_fck),
+	CLK(NULL, "atclk_fck", &atclk_fck),
+	CLK(NULL, "traceclk_src_fck", &traceclk_src_fck),
+	CLK(NULL, "traceclk_fck", &traceclk_fck),
+	CLK(NULL, "secure_32k_fck", &secure_32k_fck),
+	CLK(NULL, "gpt12_fck", &gpt12_fck),
+	CLK(NULL, "wdt1_fck", &wdt1_fck),
+	{ NULL },
+};
+
+static struct ti_clk_alias omap36xx_am35xx_omap3430es2plus_clks[] = {
+	CLK(NULL, "dpll5_ck", &dpll5_ck),
+	CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck),
+	CLK(NULL, "core_d3_ck", &core_d3_ck),
+	CLK(NULL, "core_d4_ck", &core_d4_ck),
+	CLK(NULL, "core_d6_ck", &core_d6_ck),
+	CLK(NULL, "omap_192m_alwon_fck", &omap_192m_alwon_fck),
+	CLK(NULL, "core_d2_ck", &core_d2_ck),
+	CLK(NULL, "corex2_d3_fck", &corex2_d3_fck),
+	CLK(NULL, "corex2_d5_fck", &corex2_d5_fck),
+	CLK(NULL, "sgx_fck", &sgx_fck),
+	CLK(NULL, "sgx_ick", &sgx_ick),
+	CLK(NULL, "cpefuse_fck", &cpefuse_fck),
+	CLK(NULL, "ts_fck", &ts_fck),
+	CLK(NULL, "usbtll_fck", &usbtll_fck),
+	CLK(NULL, "usbtll_ick", &usbtll_ick),
+	CLK("omap_hsmmc.2", "ick", &mmchs3_ick),
+	CLK(NULL, "mmchs3_ick", &mmchs3_ick),
+	CLK(NULL, "mmchs3_fck", &mmchs3_fck),
+	CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es2),
+	CLK("omapdss_dss", "ick", &dss_ick_3430es2),
+	CLK(NULL, "dss_ick", &dss_ick_3430es2),
+	CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck),
+	CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck),
+	CLK(NULL, "usbhost_ick", &usbhost_ick),
+	{ NULL },
+};
+
+static struct ti_clk_alias omap3430es1_clks[] = {
+	CLK(NULL, "gfx_l3_ck", &gfx_l3_ck),
+	CLK(NULL, "gfx_l3_fck", &gfx_l3_fck),
+	CLK(NULL, "gfx_l3_ick", &gfx_l3_ick),
+	CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck),
+	CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck),
+	CLK(NULL, "d2d_26m_fck", &d2d_26m_fck),
+	CLK(NULL, "fshostusb_fck", &fshostusb_fck),
+	CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1),
+	CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1),
+	CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es1),
+	CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es1),
+	CLK(NULL, "fac_ick", &fac_ick),
+	CLK(NULL, "ssi_ick", &ssi_ick_3430es1),
+	CLK(NULL, "usb_l4_ick", &usb_l4_ick),
+	CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es1),
+	CLK("omapdss_dss", "ick", &dss_ick_3430es1),
+	CLK(NULL, "dss_ick", &dss_ick_3430es1),
+	{ NULL },
+};
+
+static struct ti_clk_alias omap36xx_clks[] = {
+	CLK(NULL, "uart4_fck", &uart4_fck),
+	{ NULL },
+};
+
+static struct ti_clk_alias am35xx_clks[] = {
+	CLK(NULL, "ipss_ick", &ipss_ick),
+	CLK(NULL, "rmii_ck", &rmii_ck),
+	CLK(NULL, "pclk_ck", &pclk_ck),
+	CLK(NULL, "emac_ick", &emac_ick),
+	CLK(NULL, "emac_fck", &emac_fck),
+	CLK("davinci_emac.0", NULL, &emac_ick),
+	CLK("davinci_mdio.0", NULL, &emac_fck),
+	CLK("vpfe-capture", "master", &vpfe_ick),
+	CLK("vpfe-capture", "slave", &vpfe_fck),
+	CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_am35xx),
+	CLK(NULL, "hsotgusb_fck", &hsotgusb_fck_am35xx),
+	CLK(NULL, "hecc_ck", &hecc_ck),
+	CLK(NULL, "uart4_ick", &uart4_ick_am35xx),
+	CLK(NULL, "uart4_fck", &uart4_fck_am35xx),
+	{ NULL },
+};
+
+static struct ti_clk *omap36xx_clk_patches[] = {
+	&dpll4_m3x2_ck_omap36xx,
+	&dpll3_m3x2_ck_omap36xx,
+	&dpll4_m6x2_ck_omap36xx,
+	&dpll4_m2x2_ck_omap36xx,
+	&dpll4_m5x2_ck_omap36xx,
+	&dpll4_ck_omap36xx,
+	NULL,
+};
+
+static const char *enable_init_clks[] = {
+	"sdrc_ick",
+	"gpmc_fck",
+	"omapctrl_ick",
+};
+
+static void __init omap3_clk_legacy_common_init(void)
+{
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(clk_get_rate(osc_sys_ck.clk) / 1000000),
+		(clk_get_rate(osc_sys_ck.clk) / 100000) % 10,
+		(clk_get_rate(core_ck.clk) / 1000000),
+		(clk_get_rate(arm_fck.clk) / 1000000));
+}
+
+int __init omap3430es1_clk_legacy_init(void)
+{
+	int r;
+
+	r = ti_clk_register_legacy_clks(omap3430es1_clks);
+	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+
+	omap3_clk_legacy_common_init();
+
+	return r;
+}
+
+int __init omap3430_clk_legacy_init(void)
+{
+	int r;
+
+	r = ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+
+	omap3_clk_legacy_common_init();
+	omap3_clk_lock_dpll5();
+
+	return r;
+}
+
+int __init omap36xx_clk_legacy_init(void)
+{
+	int r;
+
+	ti_clk_patch_legacy_clks(omap36xx_clk_patches);
+	r = ti_clk_register_legacy_clks(omap36xx_clks);
+	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+
+	omap3_clk_legacy_common_init();
+	omap3_clk_lock_dpll5();
+
+	return r;
+}
+
+int __init am35xx_clk_legacy_init(void)
+{
+	int r;
+
+	r = ti_clk_register_legacy_clks(am35xx_clks);
+	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+
+	omap3_clk_legacy_common_init();
+	omap3_clk_lock_dpll5();
+
+	return r;
+}

+ 1 - 7
drivers/clk/ti/clk-3xxx.c

@@ -327,7 +327,6 @@ enum {
 	OMAP3_SOC_OMAP3430_ES1,
 	OMAP3_SOC_OMAP3430_ES2_PLUS,
 	OMAP3_SOC_OMAP3630,
-	OMAP3_SOC_TI81XX,
 };
 
 static int __init omap3xxx_dt_clk_init(int soc_type)
@@ -370,7 +369,7 @@ static int __init omap3xxx_dt_clk_init(int soc_type)
 		(clk_get_rate(clk_get_sys(NULL, "core_ck")) / 1000000),
 		(clk_get_rate(clk_get_sys(NULL, "arm_fck")) / 1000000));
 
-	if (soc_type != OMAP3_SOC_TI81XX && soc_type != OMAP3_SOC_OMAP3430_ES1)
+	if (soc_type != OMAP3_SOC_OMAP3430_ES1)
 		omap3_clk_lock_dpll5();
 
 	return 0;
@@ -390,8 +389,3 @@ int __init am35xx_dt_clk_init(void)
 {
 	return omap3xxx_dt_clk_init(OMAP3_SOC_AM35XX);
 }
-
-int __init ti81xx_dt_clk_init(void)
-{
-	return omap3xxx_dt_clk_init(OMAP3_SOC_TI81XX);
-}

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä