Browse Source

Merge branch 'clk-next' into v3.19-rc7

Michael Turquette 10 years ago
parent
commit
54eea32f7e
100 changed files with 11900 additions and 4984 deletions
  1. 2 0
      Documentation/clk.txt
  2. 15 0
      Documentation/devicetree/bindings/clock/exynos7-clock.txt
  3. 21 0
      Documentation/devicetree/bindings/clock/qcom,lcc.txt
  4. 3 2
      Documentation/devicetree/bindings/clock/qoriq-clock.txt
  5. 1 0
      Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
  6. 33 0
      Documentation/devicetree/bindings/clock/renesas,r8a73a4-cpg-clocks.txt
  7. 8 4
      Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
  8. 36 7
      Documentation/devicetree/bindings/clock/sunxi.txt
  9. 42 0
      Documentation/devicetree/bindings/clock/ti,cdce706.txt
  10. 33 0
      Documentation/devicetree/bindings/clock/ti/fapll.txt
  11. 4 4
      Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
  12. 5 0
      MAINTAINERS
  13. 52 20
      arch/arm/boot/dts/sun4i-a10.dtsi
  14. 39 15
      arch/arm/boot/dts/sun5i-a10s.dtsi
  15. 31 13
      arch/arm/boot/dts/sun5i-a13.dtsi
  16. 55 31
      arch/arm/boot/dts/sun6i-a31.dtsi
  17. 52 20
      arch/arm/boot/dts/sun7i-a20.dtsi
  18. 64 32
      arch/arm/boot/dts/sun8i-a23.dtsi
  19. 1 1
      arch/arm/mach-omap2/Makefile
  20. 0 3692
      arch/arm/mach-omap2/cclock3xxx_data.c
  21. 0 16
      arch/arm/mach-omap2/clock.c
  22. 8 6
      arch/arm/mach-omap2/clock.h
  23. 0 11
      arch/arm/mach-omap2/clock_common_data.c
  24. 8 5
      arch/arm/mach-omap2/dpll3xxx.c
  25. 2 0
      arch/arm/mach-omap2/dpll44xx.c
  26. 19 9
      arch/arm/mach-omap2/io.c
  27. 1 0
      arch/arm/mach-omap2/prm.h
  28. 11 0
      arch/arm/mach-omap2/prm_common.c
  29. 8 0
      arch/mips/alchemy/common/clock.c
  30. 5 0
      arch/powerpc/kernel/time.c
  31. 5 6
      arch/powerpc/platforms/512x/clock-commonclk.c
  32. 13 5
      drivers/clk/Kconfig
  33. 3 1
      drivers/clk/Makefile
  34. 2 0
      drivers/clk/at91/clk-programmable.c
  35. 2 0
      drivers/clk/bcm/clk-kona.c
  36. 348 0
      drivers/clk/clk-asm9260.c
  37. 700 0
      drivers/clk/clk-cdce706.c
  38. 7 2
      drivers/clk/clk-composite.c
  39. 144 84
      drivers/clk/clk-divider.c
  40. 17 1
      drivers/clk/clk-gate.c
  41. 16 0
      drivers/clk/clk-mux.c
  42. 41 68
      drivers/clk/clk-qoriq.c
  43. 689 301
      drivers/clk/clk.c
  44. 5 0
      drivers/clk/clk.h
  45. 66 19
      drivers/clk/clkdev.c
  46. 2 0
      drivers/clk/hisilicon/clk-hi3620.c
  47. 2 0
      drivers/clk/mmp/clk-mix.c
  48. 1 0
      drivers/clk/pxa/Makefile
  49. 364 0
      drivers/clk/pxa/clk-pxa3xx.c
  50. 18 0
      drivers/clk/qcom/Kconfig
  51. 4 0
      drivers/clk/qcom/Makefile
  52. 1 0
      drivers/clk/qcom/clk-pll.c
  53. 8 2
      drivers/clk/qcom/clk-rcg.c
  54. 6 0
      drivers/clk/qcom/clk-rcg2.c
  55. 70 0
      drivers/clk/qcom/clk-regmap-divider.c
  56. 29 0
      drivers/clk/qcom/clk-regmap-divider.h
  57. 59 0
      drivers/clk/qcom/clk-regmap-mux.c
  58. 29 0
      drivers/clk/qcom/clk-regmap-mux.h
  59. 12 0
      drivers/clk/qcom/gcc-ipq806x.c
  60. 473 0
      drivers/clk/qcom/lcc-ipq806x.c
  61. 585 0
      drivers/clk/qcom/lcc-msm8960.c
  62. 35 13
      drivers/clk/rockchip/clk-rk3288.c
  63. 22 10
      drivers/clk/samsung/clk-exynos-audss.c
  64. 47 170
      drivers/clk/samsung/clk-exynos3250.c
  65. 5 5
      drivers/clk/samsung/clk-exynos4.c
  66. 48 168
      drivers/clk/samsung/clk-exynos4415.c
  67. 406 2
      drivers/clk/samsung/clk-exynos7.c
  68. 10 3
      drivers/clk/samsung/clk.c
  69. 2 1
      drivers/clk/samsung/clk.h
  70. 2 0
      drivers/clk/shmobile/Makefile
  71. 11 4
      drivers/clk/shmobile/clk-div6.c
  72. 241 0
      drivers/clk/shmobile/clk-r8a73a4.c
  73. 88 0
      drivers/clk/shmobile/clk-rcar-gen2.c
  74. 15 4
      drivers/clk/st/clk-flexgen.c
  75. 1 0
      drivers/clk/sunxi/Makefile
  76. 6 6
      drivers/clk/sunxi/clk-factors.c
  77. 4 3
      drivers/clk/sunxi/clk-factors.h
  78. 166 58
      drivers/clk/sunxi/clk-mod0.c
  79. 2 0
      drivers/clk/sunxi/clk-sun6i-ar100.c
  80. 11 2
      drivers/clk/sunxi/clk-sun8i-mbus.c
  81. 85 34
      drivers/clk/sunxi/clk-sun9i-core.c
  82. 219 0
      drivers/clk/sunxi/clk-sun9i-mmc.c
  83. 222 40
      drivers/clk/sunxi/clk-sunxi.c
  84. 3 1
      drivers/clk/ti/Makefile
  85. 4653 0
      drivers/clk/ti/clk-3xxx-legacy.c
  86. 1 7
      drivers/clk/ti/clk-3xxx.c
  87. 1 1
      drivers/clk/ti/clk-44xx.c
  88. 1 1
      drivers/clk/ti/clk-54xx.c
  89. 1 1
      drivers/clk/ti/clk-7xx.c
  90. 53 0
      drivers/clk/ti/clk-816x.c
  91. 125 0
      drivers/clk/ti/clk.c
  92. 172 0
      drivers/clk/ti/clock.h
  93. 42 4
      drivers/clk/ti/composite.c
  94. 131 1
      drivers/clk/ti/divider.c
  95. 108 11
      drivers/clk/ti/dpll.c
  96. 410 0
      drivers/clk/ti/fapll.c
  97. 131 30
      drivers/clk/ti/gate.c
  98. 72 24
      drivers/clk/ti/interface.c
  99. 68 2
      drivers/clk/ti/mux.c
  100. 0 1
      drivers/clk/ux500/clk-prcc.c

+ 2 - 0
Documentation/clk.txt

@@ -73,6 +73,8 @@ the operations defined in clk.h:
 						unsigned long *parent_rate);
 						unsigned long *parent_rate);
 		long		(*determine_rate)(struct clk_hw *hw,
 		long		(*determine_rate)(struct clk_hw *hw,
 						unsigned long rate,
 						unsigned long rate,
+						unsigned long min_rate,
+						unsigned long max_rate,
 						unsigned long *best_parent_rate,
 						unsigned long *best_parent_rate,
 						struct clk_hw **best_parent_clk);
 						struct clk_hw **best_parent_clk);
 		int		(*set_parent)(struct clk_hw *hw, u8 index);
 		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-peris"
 	- "samsung,exynos7-clock-fsys0"
 	- "samsung,exynos7-clock-fsys0"
 	- "samsung,exynos7-clock-fsys1"
 	- "samsung,exynos7-clock-fsys1"
+	- "samsung,exynos7-clock-mscl"
+	- "samsung,exynos7-clock-aud"
 
 
  - reg: physical base address of the controller and the length of
  - reg: physical base address of the controller and the length of
 	memory mapped region.
 	memory mapped region.
@@ -53,6 +55,7 @@ Input clocks for top0 clock controller:
 	- dout_sclk_bus1_pll
 	- dout_sclk_bus1_pll
 	- dout_sclk_cc_pll
 	- dout_sclk_cc_pll
 	- dout_sclk_mfc_pll
 	- dout_sclk_mfc_pll
+	- dout_sclk_aud_pll
 
 
 Input clocks for top1 clock controller:
 Input clocks for top1 clock controller:
 	- fin_pll
 	- fin_pll
@@ -76,6 +79,14 @@ Input clocks for peric1 clock controller:
 	- sclk_uart1
 	- sclk_uart1
 	- sclk_uart2
 	- sclk_uart2
 	- sclk_uart3
 	- sclk_uart3
+	- sclk_spi0
+	- sclk_spi1
+	- sclk_spi2
+	- sclk_spi3
+	- sclk_spi4
+	- sclk_i2s1
+	- sclk_pcm1
+	- sclk_spdif
 
 
 Input clocks for peris clock controller:
 Input clocks for peris clock controller:
 	- fin_pll
 	- fin_pll
@@ -91,3 +102,7 @@ Input clocks for fsys1 clock controller:
 	- dout_aclk_fsys1_200
 	- dout_aclk_fsys1_200
 	- dout_sclk_mmc0
 	- dout_sclk_mmc0
 	- dout_sclk_mmc1
 	- dout_sclk_mmc1
+
+Input clocks for aud clock controller:
+	- fin_pll
+	- fout_aud_pll

+ 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
 SYSCLK signal. The SYSCLK input (frequency) is multiplied using
 multiple phase locked loops (PLL) to create a variety of frequencies
 multiple phase locked loops (PLL) to create a variety of frequencies
 which can then be passed to a variety of internal logic, including
 which can then be passed to a variety of internal logic, including
@@ -29,6 +29,7 @@ Required properties:
 	* "fsl,t4240-clockgen"
 	* "fsl,t4240-clockgen"
 	* "fsl,b4420-clockgen"
 	* "fsl,b4420-clockgen"
 	* "fsl,b4860-clockgen"
 	* "fsl,b4860-clockgen"
+	* "fsl,ls1021a-clockgen"
 	Chassis clock strings include:
 	Chassis clock strings include:
 	* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
 	* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
 	* "fsl,qoriq-clockgen-2.0": for chassis 2.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
   - compatible: Must be one of the following
     - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
     - "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,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) MSTP gate clocks
     - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) 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
     - "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
   - compatible: Must be one of
     - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
     - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
     - "renesas,r8a7791-cpg-clocks" for the r8a7791 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,r8a7794-cpg-clocks" for the r8a7794 CPG
     - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 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
   - 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-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "main",
   - 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
 Example
@@ -26,8 +29,9 @@ Example
 		compatible = "renesas,r8a7790-cpg-clocks",
 		compatible = "renesas,r8a7790-cpg-clocks",
 			     "renesas,rcar-gen2-cpg-clocks";
 			     "renesas,rcar-gen2-cpg-clocks";
 		reg = <0 0xe6150000 0 0x1000>;
 		reg = <0 0xe6150000 0 0x1000>;
-		clocks = <&extal_clk>;
+		clocks = <&extal_clk &usb_extal_clk>;
 		#clock-cells = <1>;
 		#clock-cells = <1>;
 		clock-output-names = "main", "pll0, "pll1", "pll3",
 		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,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
 	"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
 	"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-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,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
 	"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
 	"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
 	"allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80
 	"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,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
 	"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
 	"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
 	"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
 	"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,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,sun8i-a23-mbus-clk" - for the MBUS clock on A23
 	"allwinner,sun7i-a20-out-clk" - for the external output clocks
 	"allwinner,sun7i-a20-out-clk" - for the external output clocks
 	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
 	"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
 - #clock-cells : from common clock binding; shall be set to 0 except for
 	the following compatibles where it shall be set to 1:
 	the following compatibles where it shall be set to 1:
 	"allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk",
 	"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.
 - clock-output-names : shall be the corresponding names of the outputs.
 	If the clock module only has one output, the name shall be the
 	If the clock module only has one output, the name shall be the
 	module name.
 	module name.
@@ -81,6 +85,10 @@ Required properties for all clocks:
 And "allwinner,*-usb-clk" clocks also require:
 And "allwinner,*-usb-clk" clocks also require:
 - reset-cells : shall be set to 1
 - 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
 For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
 dummy clocks at 25 MHz and 125 MHz, respectively. See example.
 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
 is the normal PLL6 output, or "pll6". The second output is rate doubled
 PLL6, or "pll6x2".
 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:
 For example:
 
 
 osc24M: clk@01c20050 {
 osc24M: clk@01c20050 {
@@ -138,11 +154,11 @@ cpu: cpu@01c20054 {
 };
 };
 
 
 mmc0_clk: clk@01c20088 {
 mmc0_clk: clk@01c20088 {
-	#clock-cells = <0>;
-	compatible = "allwinner,sun4i-mod0-clk";
+	#clock-cells = <1>;
+	compatible = "allwinner,sun4i-a10-mmc-clk";
 	reg = <0x01c20088 0x4>;
 	reg = <0x01c20088 0x4>;
 	clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 	clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-	clock-output-names = "mmc0";
+	clock-output-names = "mmc0", "mmc0_output", "mmc0_sample";
 };
 };
 
 
 mii_phy_tx_clk: clk@2 {
 mii_phy_tx_clk: clk@2 {
@@ -170,3 +186,16 @@ gmac_clk: clk@01c20164 {
 	clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
 	clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
 	clock-output-names = "gmac";
 	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:
 Required properties:
  - compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc"
  - compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc"
  - reg : mmc controller base registers
  - 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
  - interrupts : mmc controller interrupt
 
 
 Optional properties:
 Optional properties:
@@ -25,8 +25,8 @@ Examples:
 	mmc0: mmc@01c0f000 {
 	mmc0: mmc@01c0f000 {
 		compatible = "allwinner,sun5i-a13-mmc";
 		compatible = "allwinner,sun5i-a13-mmc";
 		reg = <0x01c0f000 0x1000>;
 		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>;
 		interrupts = <0 32 4>;
 		status = "disabled";
 		status = "disabled";
 	};
 	};

+ 5 - 0
MAINTAINERS

@@ -9566,6 +9566,11 @@ L:	linux-omap@vger.kernel.org
 S:	Maintained
 S:	Maintained
 F:	drivers/thermal/ti-soc-thermal/
 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
 TI CLOCK DRIVER
 M:	Tero Kristo <t-kristo@ti.com>
 M:	Tero Kristo <t-kristo@ti.com>
 L:	linux-omap@vger.kernel.org
 L:	linux-omap@vger.kernel.org

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

@@ -226,35 +226,43 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 		};
 
 
 		mmc1_clk: clk@01c2008c {
 		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>;
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 		};
 
 
 		mmc2_clk: clk@01c20090 {
 		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>;
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 		};
 
 
 		mmc3_clk: clk@01c20094 {
 		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>;
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 		};
 
 
 		ts_clk: clk@01c20098 {
 		ts_clk: clk@01c20098 {
@@ -398,8 +406,14 @@
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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>;
 			interrupts = <32>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -407,8 +421,14 @@
 		mmc1: mmc@01c10000 {
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c10000 0x1000>;
 			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>;
 			interrupts = <33>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -416,8 +436,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c11000 0x1000>;
 			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>;
 			interrupts = <34>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -425,8 +451,14 @@
 		mmc3: mmc@01c12000 {
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun4i-a10-mmc";
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c12000 0x1000>;
 			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>;
 			interrupts = <35>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};

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

@@ -207,27 +207,33 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 		};
 
 
 		mmc1_clk: clk@01c2008c {
 		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>;
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 		};
 
 
 		mmc2_clk: clk@01c20090 {
 		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>;
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 		};
 
 
 		ts_clk: clk@01c20098 {
 		ts_clk: clk@01c20098 {
@@ -355,8 +361,14 @@
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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>;
 			interrupts = <32>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -364,8 +376,14 @@
 		mmc1: mmc@01c10000 {
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
 			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>;
 			interrupts = <33>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -373,8 +391,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			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>;
 			interrupts = <34>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};

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

@@ -190,27 +190,33 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 		};
 
 
 		mmc1_clk: clk@01c2008c {
 		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>;
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 		};
 
 
 		mmc2_clk: clk@01c20090 {
 		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>;
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 		};
 
 
 		ts_clk: clk@01c20098 {
 		ts_clk: clk@01c20098 {
@@ -322,8 +328,14 @@
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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>;
 			interrupts = <32>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -331,8 +343,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			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>;
 			interrupts = <34>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};

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

@@ -168,19 +168,11 @@
 			clock-output-names = "axi";
 			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 {
 		ahb1: ahb1@01c20054 {
 			#clock-cells = <0>;
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-ahb-clk";
+			compatible = "allwinner,sun6i-a31-ahb1-clk";
 			reg = <0x01c20054 0x4>;
 			reg = <0x01c20054 0x4>;
-			clocks = <&ahb1_mux>;
+			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
 			clock-output-names = "ahb1";
 			clock-output-names = "ahb1";
 		};
 		};
 
 
@@ -243,35 +235,43 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 		};
 
 
 		mmc1_clk: clk@01c2008c {
 		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>;
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 		};
 
 
 		mmc2_clk: clk@01c20090 {
 		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>;
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 		};
 
 
 		mmc3_clk: clk@01c20094 {
 		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>;
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 0>;
 			clocks = <&osc24M>, <&pll6 0>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 		};
 
 
 		spi0_clk: clk@01c200a0 {
 		spi0_clk: clk@01c200a0 {
@@ -361,15 +361,21 @@
 			#dma-cells = <1>;
 			#dma-cells = <1>;
 
 
 			/* DMA controller requires AHB1 clocked from PLL6 */
 			/* DMA controller requires AHB1 clocked from PLL6 */
-			assigned-clocks = <&ahb1_mux>;
+			assigned-clocks = <&ahb1>;
 			assigned-clock-parents = <&pll6 0>;
 			assigned-clock-parents = <&pll6 0>;
 		};
 		};
 
 
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 8>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 60 4>;
 			interrupts = <0 60 4>;
@@ -379,8 +385,14 @@
 		mmc1: mmc@01c10000 {
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 9>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 61 4>;
 			interrupts = <0 61 4>;
@@ -390,8 +402,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 10>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 62 4>;
 			interrupts = <0 62 4>;
@@ -401,8 +419,14 @@
 		mmc3: mmc@01c12000 {
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c12000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 11>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 63 4>;
 			interrupts = <0 63 4>;

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

@@ -266,35 +266,43 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			reg = <0x01c20088 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0";
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
 		};
 		};
 
 
 		mmc1_clk: clk@01c2008c {
 		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>;
 			reg = <0x01c2008c 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1";
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
 		};
 		};
 
 
 		mmc2_clk: clk@01c20090 {
 		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>;
 			reg = <0x01c20090 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2";
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
 		};
 		};
 
 
 		mmc3_clk: clk@01c20094 {
 		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>;
 			reg = <0x01c20094 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc3";
+			clock-output-names = "mmc3",
+					     "mmc3_output",
+					     "mmc3_sample";
 		};
 		};
 
 
 		ts_clk: clk@01c20098 {
 		ts_clk: clk@01c20098 {
@@ -510,8 +518,14 @@
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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 = <0 32 4>;
 			interrupts = <0 32 4>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -519,8 +533,14 @@
 		mmc1: mmc@01c10000 {
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
 			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 = <0 33 4>;
 			interrupts = <0 33 4>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -528,8 +548,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			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 = <0 34 4>;
 			interrupts = <0 34 4>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};
@@ -537,8 +563,14 @@
 		mmc3: mmc@01c12000 {
 		mmc3: mmc@01c12000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c12000 0x1000>;
 			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 = <0 35 4>;
 			interrupts = <0 35 4>;
 			status = "disabled";
 			status = "disabled";
 		};
 		};

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

@@ -101,11 +101,19 @@
 		};
 		};
 
 
 		/* dummy clock until actually implemented */
 		/* dummy clock until actually implemented */
-		pll6: pll6_clk {
+		pll5: pll5_clk {
 			#clock-cells = <0>;
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			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 {
 		cpu: cpu_clk@01c20050 {
@@ -131,19 +139,11 @@
 			clock-output-names = "axi";
 			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 {
 		ahb1: ahb1_clk@01c20054 {
 			#clock-cells = <0>;
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-ahb-clk";
+			compatible = "allwinner,sun6i-a31-ahb1-clk";
 			reg = <0x01c20054 0x4>;
 			reg = <0x01c20054 0x4>;
-			clocks = <&ahb1_mux>;
+			clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
 			clock-output-names = "ahb1";
 			clock-output-names = "ahb1";
 		};
 		};
 
 
@@ -184,7 +184,7 @@
 			#clock-cells = <0>;
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-a10-apb1-clk";
 			compatible = "allwinner,sun4i-a10-apb1-clk";
 			reg = <0x01c20058 0x4>;
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
+			clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
 			clock-output-names = "apb2";
 			clock-output-names = "apb2";
 		};
 		};
 
 
@@ -200,27 +200,41 @@
 		};
 		};
 
 
 		mmc0_clk: clk@01c20088 {
 		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>;
 			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 {
 		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>;
 			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 {
 		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>;
 			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";
 		};
 		};
 	};
 	};
 
 
@@ -242,8 +256,14 @@
 		mmc0: mmc@01c0f000 {
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 8>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 60 4>;
 			interrupts = <0 60 4>;
@@ -253,8 +273,14 @@
 		mmc1: mmc@01c10000 {
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 9>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 61 4>;
 			interrupts = <0 61 4>;
@@ -264,8 +290,14 @@
 		mmc2: mmc@01c11000 {
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			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>;
 			resets = <&ahb1_rst 10>;
 			reset-names = "ahb";
 			reset-names = "ahb";
 			interrupts = <0 62 4>;
 			interrupts = <0 62 4>;

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

@@ -187,7 +187,7 @@ obj-$(CONFIG_SOC_OMAP2430)		+= clock2430.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clkt34xx_dpll3m2.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clkt34xx_dpll3m2.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock3517.o clock36xx.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_OMAP3)		+= clkt_iclk.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common)
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common)
 obj-$(CONFIG_ARCH_OMAP4)		+= dpll3xxx.o dpll44xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= dpll3xxx.o dpll44xx.o

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

@@ -1,3692 +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 (soc_is_am33xx()) {
-		cpu_mask = RATE_IN_AM33XX;
-	} else if (cpu_is_ti814x()) {
-		cpu_mask = RATE_IN_TI814X;
-	} 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 (!cpu_is_ti81xx() && (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/clk-provider.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
-#include <linux/clk-private.h>
 #include <asm/cpu.h>
 #include <asm/cpu.h>
 
 
 #include <trace/events/power.h>
 #include <trace/events/power.h>
@@ -629,21 +628,6 @@ const struct clk_hw_omap_ops clkhwops_wait = {
 	.find_companion	= omap2_clk_dflt_find_companion,
 	.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
  * 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
  * @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;
 struct clockdomain;
 
 
 #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name)	\
 #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name)	\
-	static struct clk _name = {				\
+	static struct clk_core _name##_core = {			\
 		.name = #_name,					\
 		.name = #_name,					\
 		.hw = &_name##_hw.hw,				\
 		.hw = &_name##_hw.hw,				\
 		.parent_names = _parent_array_name,		\
 		.parent_names = _parent_array_name,		\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.ops = &_clkops_name,				\
 		.ops = &_clkops_name,				\
+	};							\
+	static struct clk _name = {				\
+		.core = &_name##_core,				\
 	};
 	};
 
 
 #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name,	\
 #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name,	\
 				_clkops_name, _flags)		\
 				_clkops_name, _flags)		\
-	static struct clk _name = {				\
+	static struct clk_core _name##_core = {			\
 		.name = #_name,					\
 		.name = #_name,					\
 		.hw = &_name##_hw.hw,				\
 		.hw = &_name##_hw.hw,				\
 		.parent_names = _parent_array_name,		\
 		.parent_names = _parent_array_name,		\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.num_parents = ARRAY_SIZE(_parent_array_name),	\
 		.ops = &_clkops_name,				\
 		.ops = &_clkops_name,				\
 		.flags = _flags,				\
 		.flags = _flags,				\
+	};							\
+	static struct clk _name = {				\
+		.core = &_name##_core,				\
 	};
 	};
 
 
 #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name)		\
 #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name)		\
@@ -239,7 +245,6 @@ struct ti_clk_features {
 extern struct ti_clk_features ti_clk_features;
 extern struct ti_clk_features ti_clk_features;
 
 
 extern const struct clkops clkops_omap2_dflt_wait;
 extern const struct clkops clkops_omap2_dflt_wait;
-extern const struct clkops clkops_dummy;
 extern const struct clkops clkops_omap2_dflt;
 extern const struct clkops clkops_omap2_dflt;
 
 
 extern struct clk_functions omap2_clk_functions;
 extern struct clk_functions omap2_clk_functions;
@@ -248,7 +253,6 @@ extern const struct clksel_rate gpt_32k_rates[];
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate dsp_ick_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_iclk_wait;
 extern const struct clk_hw_omap_ops clkhwops_wait;
 extern const struct clk_hw_omap_ops clkhwops_wait;
@@ -273,7 +277,5 @@ extern void __iomem *clk_memmaps[];
 extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 extern void omap2_clkops_disable_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);
 void __init ti_clk_init_features(void);
 #endif
 #endif

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

@@ -16,7 +16,6 @@
  * OMAP3xxx clock definition files.
  * OMAP3xxx clock definition files.
  */
  */
 
 
-#include <linux/clk-private.h>
 #include "clock.h"
 #include "clock.h"
 
 
 /* clksel_rate data common to 24xx/343x */
 /* 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 = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
 	{ .div = 0 },
 	{ .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);
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	int r;
 	int r;
 	struct dpll_data *dd;
 	struct dpll_data *dd;
-	struct clk *parent;
+	struct clk_hw *parent;
 
 
 	dd = clk->dpll_data;
 	dd = clk->dpll_data;
 	if (!dd)
 	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)) {
 	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);
 		r = _omap3_noncore_dpll_bypass(clk);
 	} else {
 	} else {
-		WARN_ON(parent != dd->clk_ref);
+		WARN_ON(parent != __clk_get_hw(dd->clk_ref));
 		r = _omap3_noncore_dpll_lock(clk);
 		r = _omap3_noncore_dpll_lock(clk);
 	}
 	}
 
 
@@ -473,6 +473,8 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
  * in failure.
  * in failure.
  */
  */
 long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
 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,
 				       unsigned long *best_parent_rate,
 				       struct clk_hw **best_parent_clk)
 				       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)
 	if (!dd)
 		return -EINVAL;
 		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;
 		return -EINVAL;
 
 
 	if (dd->last_rounded_rate == 0)
 	if (dd->last_rounded_rate == 0)

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

@@ -222,6 +222,8 @@ out:
  * in failure.
  * in failure.
  */
  */
 long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 					struct clk_hw **best_parent_clk)
 {
 {

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

@@ -461,7 +461,17 @@ void __init omap3_init_early(void)
 	omap3xxx_clockdomains_init();
 	omap3xxx_clockdomains_init();
 	omap3xxx_hwmod_init();
 	omap3xxx_hwmod_init();
 	omap_hwmod_init_postsetup();
 	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)
 void __init omap3430_init_early(void)
@@ -509,8 +519,6 @@ void __init ti81xx_init_early(void)
 	omap_hwmod_init_postsetup();
 	omap_hwmod_init_postsetup();
 	if (of_have_populated_dt())
 	if (of_have_populated_dt())
 		omap_clk_soc_init = ti81xx_dt_clk_init;
 		omap_clk_soc_init = ti81xx_dt_clk_init;
-	else
-		omap_clk_soc_init = omap3xxx_clk_init;
 }
 }
 
 
 void __init omap3_init_late(void)
 void __init omap3_init_late(void)
@@ -731,15 +739,17 @@ int __init omap_clk_init(void)
 
 
 	ti_clk_init_features();
 	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();
 	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 u16 prm_features;
 extern void omap2_set_globals_prm(void __iomem *prm);
 extern void omap2_set_globals_prm(void __iomem *prm);
 int of_prcm_init(void);
 int of_prcm_init(void);
+void omap3_prcm_legacy_iomaps_init(void);
 # endif
 # endif
 
 
 /*
 /*

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

@@ -35,6 +35,8 @@
 #include "prm44xx.h"
 #include "prm44xx.h"
 #include "common.h"
 #include "common.h"
 #include "clock.h"
 #include "clock.h"
+#include "cm.h"
+#include "control.h"
 
 
 /*
 /*
  * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
  * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
@@ -637,6 +639,15 @@ int __init of_prcm_init(void)
 	return 0;
 	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)
 static int __init prm_late_init(void)
 {
 {
 	if (prm_ll_data->late_init)
 	if (prm_ll_data->late_init)

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

@@ -373,6 +373,8 @@ static long alchemy_calc_div(unsigned long rate, unsigned long prate,
 }
 }
 
 
 static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
 static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
+					unsigned long min_rate,
+					unsigned long max_rate,
 					unsigned long *best_parent_rate,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk,
 					struct clk_hw **best_parent_clk,
 					int scale, int maxdiv)
 					int scale, int maxdiv)
@@ -546,6 +548,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,
 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 					struct clk_hw **best_parent_clk)
 {
 {
@@ -678,6 +682,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,
 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 					struct clk_hw **best_parent_clk)
 {
 {
@@ -897,6 +903,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,
 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 					struct clk_hw **best_parent_clk)
 {
 {

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

@@ -54,6 +54,7 @@
 #include <linux/irq.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/irq_work.h>
 #include <linux/irq_work.h>
+#include <linux/clk-provider.h>
 #include <asm/trace.h>
 #include <asm/trace.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
@@ -943,6 +944,10 @@ void __init time_init(void)
 
 
 	init_decrementer_clockevent();
 	init_decrementer_clockevent();
 	tick_setup_hrtimer_broadcast();
 	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)
 int __init mpc5121_clk_init(void)
 {
 {
 	struct device_node *clk_np;
 	struct device_node *clk_np;
@@ -1186,12 +1191,6 @@ int __init mpc5121_clk_init(void)
 	/* invalidate all not yet registered clock slots */
 	/* invalidate all not yet registered clock slots */
 	mpc512x_clk_preset_data();
 	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
 	 * add a dummy clock for those situations where a clock spec is
 	 * required yet no real clock is involved
 	 * required yet no real clock is involved

+ 13 - 5
drivers/clk/Kconfig

@@ -101,12 +101,12 @@ config COMMON_CLK_AXI_CLKGEN
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  FPGAs. It is commonly used in Analog Devices' reference designs.
 	  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---
 	---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
 config COMMON_CLK_XGENE
 	bool "Clock driver for APM XGene SoC"
 	bool "Clock driver for APM XGene SoC"
@@ -134,6 +134,14 @@ config COMMON_CLK_PXA
 	---help---
 	---help---
 	  Sypport for the Marvell PXA SoC.
 	  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"
 source "drivers/clk/qcom/Kconfig"
 
 
 endmenu
 endmenu

+ 3 - 1
drivers/clk/Makefile

@@ -16,9 +16,11 @@ endif
 
 
 # hardware specific clock types
 # hardware specific clock types
 # please keep this section sorted lexicographically by file/directory path name
 # 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_COMMON_CLK_AXI_CLKGEN)	+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)		+= clk-axm5516.o
 obj-$(CONFIG_ARCH_AXXIA)		+= clk-axm5516.o
 obj-$(CONFIG_ARCH_BCM2835)		+= clk-bcm2835.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_CLPS711X)		+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
 obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.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_NOMADIK)		+= clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
 obj-$(CONFIG_COMMON_CLK_PALMAS)		+= clk-palmas.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_RK808)		+= clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SI5351)		+= clk-si5351.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,
 static long clk_programmable_determine_rate(struct clk_hw *hw,
 					    unsigned long rate,
 					    unsigned long rate,
+					    unsigned long min_rate,
+					    unsigned long max_rate,
 					    unsigned long *best_parent_rate,
 					    unsigned long *best_parent_rate,
 					    struct clk_hw **best_parent_hw)
 					    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,
 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)
 		unsigned long *best_parent_rate, struct clk_hw **best_parent)
 {
 {
 	struct kona_clk *bcm_clk = to_kona_clk(hw);
 	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");

+ 7 - 2
drivers/clk/clk-composite.c

@@ -56,6 +56,8 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
 }
 }
 
 
 static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_p)
 					struct clk_hw **best_parent_p)
 {
 {
@@ -73,7 +75,9 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 
 
 	if (rate_hw && rate_ops && rate_ops->determine_rate) {
 	if (rate_hw && rate_ops && rate_ops->determine_rate) {
 		rate_hw->clk = hw->clk;
 		rate_hw->clk = hw->clk;
-		return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
+		return rate_ops->determine_rate(rate_hw, rate, min_rate,
+						max_rate,
+						best_parent_rate,
 						best_parent_p);
 						best_parent_p);
 	} else if (rate_hw && rate_ops && rate_ops->round_rate &&
 	} else if (rate_hw && rate_ops && rate_ops->round_rate &&
 		   mux_hw && mux_ops && mux_ops->set_parent) {
 		   mux_hw && mux_ops && mux_ops->set_parent) {
@@ -117,7 +121,8 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 		return best_rate;
 		return best_rate;
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 		mux_hw->clk = hw->clk;
 		mux_hw->clk = hw->clk;
-		return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
+		return mux_ops->determine_rate(mux_hw, rate, min_rate,
+					       max_rate, best_parent_rate,
 					       best_parent_p);
 					       best_parent_p);
 	} else {
 	} else {
 		pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
 		pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");

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

@@ -30,7 +30,7 @@
 
 
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 #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)
 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;
 	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,
 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;
 	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;
 		return val;
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return 1 << val;
 		return 1 << val;
-	if (divider->table)
-		return _get_table_div(divider->table, val);
+	if (table)
+		return _get_table_div(table, val);
 	return val + 1;
 	return val + 1;
 }
 }
 
 
@@ -98,29 +100,28 @@ static unsigned int _get_table_val(const struct clk_div_table *table,
 	return 0;
 	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;
 		return div;
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return __ffs(div);
 		return __ffs(div);
-	if (divider->table)
-		return  _get_table_val(divider->table, div);
+	if (table)
+		return  _get_table_val(table, div);
 	return div - 1;
 	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) {
 	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",
 			"%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
 			__clk_get_name(hw->clk));
 			__clk_get_name(hw->clk));
 		return parent_rate;
 		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);
 	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
  * 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;
 	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);
 		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;
 	return true;
 }
 }
 
 
@@ -191,71 +207,76 @@ static int _round_down_table(const struct clk_div_table *table, int div)
 	return down;
 	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);
 	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);
 		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;
 	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;
 	int up, down, div;
 
 
 	up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
 	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);
 		up = __roundup_pow_of_two(div);
 		down = __rounddown_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;
 	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 abs(rate - now) < abs(rate - best);
 
 
 	return now <= rate && now > 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++;
 	div++;
 
 
-	if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
 		return __roundup_pow_of_two(div);
 		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;
 	return div;
 }
 }
 
 
 static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 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;
 	int i, bestdiv = 0;
 	unsigned long parent_rate, best = 0, now, maxdiv;
 	unsigned long parent_rate, best = 0, now, maxdiv;
 	unsigned long parent_rate_saved = *best_parent_rate;
 	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)
 	if (!rate)
 		rate = 1;
 		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)) {
 	if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
 		parent_rate = *best_parent_rate;
 		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 == 0 ? 1 : bestdiv;
 		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
 		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
 		return 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);
 	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;
 			continue;
 		if (rate * i == parent_rate_saved) {
 		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),
 		parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
 				MULT_ROUND_UP(rate, i));
 				MULT_ROUND_UP(rate, i));
 		now = DIV_ROUND_UP(parent_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;
 			bestdiv = i;
 			best = now;
 			best = now;
 			*best_parent_rate = parent_rate;
 			*best_parent_rate = parent_rate;
@@ -310,48 +323,79 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 	}
 	}
 
 
 	if (!bestdiv) {
 	if (!bestdiv) {
-		bestdiv = _get_maxdiv(divider);
+		bestdiv = _get_maxdiv(table, width, flags);
 		*best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1);
 		*best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1);
 	}
 	}
 
 
 	return bestdiv;
 	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;
 	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);
 	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);
 	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 int div, value;
-	unsigned long flags = 0;
-	u32 val;
 
 
 	div = DIV_ROUND_UP(parent_rate, rate);
 	div = DIV_ROUND_UP(parent_rate, rate);
 
 
-	if (!_is_valid_div(divider, div))
+	if (!_is_valid_div(table, div, flags))
 		return -EINVAL;
 		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)
 	if (divider->lock)
 		spin_lock_irqsave(divider->lock, flags);
 		spin_lock_irqsave(divider->lock, flags);
 
 
 	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
 	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
-		val = div_mask(divider) << (divider->shift + 16);
+		val = div_mask(divider->width) << (divider->shift + 16);
 	} else {
 	} else {
 		val = clk_readl(divider->reg);
 		val = clk_readl(divider->reg);
-		val &= ~(div_mask(divider) << divider->shift);
+		val &= ~(div_mask(divider->width) << divider->shift);
 	}
 	}
 	val |= value << divider->shift;
 	val |= value << divider->shift;
 	clk_writel(val, divider->reg);
 	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);
 			width, clk_divider_flags, table, lock);
 }
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
 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;
 	struct clk_init_data init;
 
 
 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
-		if (bit_idx > 16) {
+		if (bit_idx > 15) {
 			pr_err("gate bit exceeds LOWORD field\n");
 			pr_err("gate bit exceeds LOWORD field\n");
 			return ERR_PTR(-EINVAL);
 			return ERR_PTR(-EINVAL);
 		}
 		}
@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
 	return clk;
 	return clk;
 }
 }
 EXPORT_SYMBOL_GPL(clk_register_gate);
 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);
 				      NULL, lock);
 }
 }
 EXPORT_SYMBOL_GPL(clk_register_mux);
 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);

+ 41 - 68
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
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  * 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/clk-provider.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -19,6 +22,7 @@
 struct cmux_clk {
 struct cmux_clk {
 	struct clk_hw hw;
 	struct clk_hw hw;
 	void __iomem *reg;
 	void __iomem *reg;
+	unsigned int clk_per_pll;
 	u32 flags;
 	u32 flags;
 };
 };
 
 
@@ -27,14 +31,12 @@ struct cmux_clk {
 #define CLKSEL_ADJUST		BIT(0)
 #define CLKSEL_ADJUST		BIT(0)
 #define to_cmux_clk(p)		container_of(p, struct cmux_clk, hw)
 #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)
 static int cmux_set_parent(struct clk_hw *hw, u8 idx)
 {
 {
 	struct cmux_clk *clk = to_cmux_clk(hw);
 	struct cmux_clk *clk = to_cmux_clk(hw);
 	u32 clksel;
 	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)
 	if (clk->flags & CLKSEL_ADJUST)
 		clksel += 8;
 		clksel += 8;
 	clksel = (clksel & 0xf) << CLKSEL_SHIFT;
 	clksel = (clksel & 0xf) << CLKSEL_SHIFT;
@@ -52,12 +54,12 @@ static u8 cmux_get_parent(struct clk_hw *hw)
 	clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
 	clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
 	if (clk->flags & CLKSEL_ADJUST)
 	if (clk->flags & CLKSEL_ADJUST)
 		clksel -= 8;
 		clksel -= 8;
-	clksel = (clksel >> 2) * clocks_per_pll + clksel % 4;
+	clksel = (clksel >> 2) * clk->clk_per_pll + clksel % 4;
 
 
 	return clksel;
 	return clksel;
 }
 }
 
 
-const struct clk_ops cmux_ops = {
+static const struct clk_ops cmux_ops = {
 	.get_parent = cmux_get_parent,
 	.get_parent = cmux_get_parent,
 	.set_parent = cmux_set_parent,
 	.set_parent = cmux_set_parent,
 };
 };
@@ -72,6 +74,7 @@ static void __init core_mux_init(struct device_node *np)
 	u32	offset;
 	u32	offset;
 	const char *clk_name;
 	const char *clk_name;
 	const char **parent_names;
 	const char **parent_names;
+	struct of_phandle_args clkspec;
 
 
 	rc = of_property_read_u32(np, "reg", &offset);
 	rc = of_property_read_u32(np, "reg", &offset);
 	if (rc) {
 	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);
 		pr_err("%s: get clock count error\n", np->name);
 		return;
 		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;
 		return;
-	}
 
 
 	for (i = 0; i < count; i++)
 	for (i = 0; i < count; i++)
 		parent_names[i] = of_clk_get_parent_name(np, 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;
 		goto err_name;
-	}
+
 	cmux_clk->reg = of_iomap(np, 0);
 	cmux_clk->reg = of_iomap(np, 0);
 	if (!cmux_clk->reg) {
 	if (!cmux_clk->reg) {
 		pr_err("%s: could not map register\n", __func__);
 		pr_err("%s: could not map register\n", __func__);
 		goto err_clk;
 		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");
 	node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
 	if (node && (offset >= 0x80))
 	if (node && (offset >= 0x80))
 		cmux_clk->flags = CLKSEL_ADJUST;
 		cmux_clk->flags = CLKSEL_ADJUST;
 
 
 	rc = of_property_read_string_index(np, "clock-output-names",
 	rc = of_property_read_string_index(np, "clock-output-names",
-			0, &clk_name);
+					   0, &clk_name);
 	if (rc) {
 	if (rc) {
 		pr_err("%s: read clock names error\n", np->name);
 		pr_err("%s: read clock names error\n", np->name);
 		goto err_clk;
 		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);
 	rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
 	if (rc) {
 	if (rc) {
 		pr_err("Could not register clock provider for node:%s\n",
 		pr_err("Could not register clock provider for node:%s\n",
-			 np->name);
+		       np->name);
 		goto err_clk;
 		goto err_clk;
 	}
 	}
 	goto err_name;
 	goto err_name;
@@ -155,7 +166,7 @@ static void __init core_pll_init(struct device_node *np)
 
 
 	base = of_iomap(np, 0);
 	base = of_iomap(np, 0);
 	if (!base) {
 	if (!base) {
-		pr_err("clk-ppc: iomap error\n");
+		pr_err("iomap error\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -181,24 +192,17 @@ static void __init core_pll_init(struct device_node *np)
 		goto err_map;
 		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;
 		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;
 		goto err_clks;
-	}
 
 
 	for (i = 0; i < count; i++) {
 	for (i = 0; i < count; i++) {
 		rc = of_property_read_string_index(np, "clock-output-names",
 		rc = of_property_read_string_index(np, "clock-output-names",
-				i, &clk_name);
+						   i, &clk_name);
 		if (rc) {
 		if (rc) {
 			pr_err("%s: could not get clock names\n", np->name);
 			pr_err("%s: could not get clock names\n", np->name);
 			goto err_cell;
 			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);
 	rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
 	if (rc) {
 	if (rc) {
 		pr_err("Could not register clk provider for node:%s\n",
 		pr_err("Could not register clk provider for node:%s\n",
-			 np->name);
+		       np->name);
 		goto err_cell;
 		goto err_cell;
 	}
 	}
 
 
@@ -252,7 +256,7 @@ static void __init sysclk_init(struct device_node *node)
 	u32 rate;
 	u32 rate;
 
 
 	if (!np) {
 	if (!np) {
-		pr_err("ppc-clk: could not get parent node\n");
+		pr_err("could not get parent node\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -267,40 +271,9 @@ static void __init sysclk_init(struct device_node *node)
 	if (!IS_ERR(clk))
 	if (!IS_ERR(clk))
 		of_clk_add_provider(np, of_clk_src_simple_get, clk);
 		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)
-{
-	of_clk_init(clk_match);
-
-	return 0;
-}
-
-static const struct of_device_id ppc_clk_ids[] __initconst = {
-	{ .compatible = "fsl,qoriq-clockgen-1.0", },
-	{ .compatible = "fsl,qoriq-clockgen-2.0", },
-	{}
-};
-
-static struct platform_driver ppc_corenet_clk_driver = {
-	.driver = {
-		.name = "ppc_corenet_clock",
-		.of_match_table = ppc_clk_ids,
-	},
-	.probe = ppc_corenet_clk_probe,
-};
-
-static int __init ppc_corenet_clk_init(void)
-{
-	return platform_driver_register(&ppc_corenet_clk_driver);
-}
-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);

+ 689 - 301
drivers/clk/clk.c

@@ -9,7 +9,7 @@
  * Standard functionality for the common clock API.  See Documentation/clk.txt
  * 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/clk/clk-conf.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
@@ -37,6 +37,55 @@ static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_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             ***/
 /***           locking             ***/
 static void clk_prepare_lock(void)
 static void clk_prepare_lock(void)
 {
 {
@@ -114,7 +163,8 @@ static struct hlist_head *orphan_list[] = {
 	NULL,
 	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)
 	if (!c)
 		return;
 		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",
 	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
 		   level * 3 + 1, "",
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
 		   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)
 				     int level)
 {
 {
-	struct clk *child;
+	struct clk_core *child;
 
 
 	if (!c)
 	if (!c)
 		return;
 		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)
 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;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
 
 	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase\n");
 	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,
 	.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)
 	if (!c)
 		return;
 		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, "\"%s\": { ", c->name);
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"prepare_count\": %d,", c->prepare_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)
 	if (!c)
 		return;
 		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)
 static int clk_dump(struct seq_file *s, void *data)
 {
 {
-	struct clk *c;
+	struct clk_core *c;
 	bool first_node = true;
 	bool first_node = true;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 	struct hlist_head **lists = (struct hlist_head **)s->private;
 
 
@@ -240,7 +290,7 @@ static const struct file_operations clk_dump_fops = {
 	.release	= single_release,
 	.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;
 	struct dentry *d;
 	int ret = -ENOMEM;
 	int ret = -ENOMEM;
@@ -315,7 +365,7 @@ out:
  * initialized.  Otherwise it bails out early since the debugfs clk tree
  * 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.
  * 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;
 	int ret = 0;
 
 
@@ -340,16 +390,12 @@ unlock:
  * debugfs clk tree if clk->dentry points to debugfs created by
  * debugfs clk tree if clk->dentry points to debugfs created by
  * clk_debug_register in __clk_init.
  * 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);
 	mutex_lock(&clk_debug_lock);
-	if (!clk->dentry)
-		goto out;
-
 	hlist_del_init(&clk->debug_node);
 	hlist_del_init(&clk->debug_node);
 	debugfs_remove_recursive(clk->dentry);
 	debugfs_remove_recursive(clk->dentry);
 	clk->dentry = NULL;
 	clk->dentry = NULL;
-out:
 	mutex_unlock(&clk_debug_lock);
 	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;
 	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;
 	return d;
 }
 }
@@ -379,7 +426,7 @@ EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
  */
  */
 static int __init clk_debug_init(void)
 static int __init clk_debug_init(void)
 {
 {
-	struct clk *clk;
+	struct clk_core *clk;
 	struct dentry *d;
 	struct dentry *d;
 
 
 	rootdir = debugfs_create_dir("clk", NULL);
 	rootdir = debugfs_create_dir("clk", NULL);
@@ -418,22 +465,20 @@ static int __init clk_debug_init(void)
 }
 }
 late_initcall(clk_debug_init);
 late_initcall(clk_debug_init);
 #else
 #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
 #endif
 
 
 /* caller must hold prepare_lock */
 /* 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)
 	hlist_for_each_entry(child, &clk->children, child_node)
 		clk_unprepare_unused_subtree(child);
 		clk_unprepare_unused_subtree(child);
@@ -444,7 +489,7 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
 	if (clk->flags & CLK_IGNORE_UNUSED)
 	if (clk->flags & CLK_IGNORE_UNUSED)
 		return;
 		return;
 
 
-	if (__clk_is_prepared(clk)) {
+	if (clk_core_is_prepared(clk)) {
 		if (clk->ops->unprepare_unused)
 		if (clk->ops->unprepare_unused)
 			clk->ops->unprepare_unused(clk->hw);
 			clk->ops->unprepare_unused(clk->hw);
 		else if (clk->ops->unprepare)
 		else if (clk->ops->unprepare)
@@ -453,14 +498,11 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
 }
 }
 
 
 /* caller must hold prepare_lock */
 /* 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;
 	unsigned long flags;
 
 
-	if (!clk)
-		goto out;
-
 	hlist_for_each_entry(child, &clk->children, child_node)
 	hlist_for_each_entry(child, &clk->children, child_node)
 		clk_disable_unused_subtree(child);
 		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
 	 * sequence.  call .disable_unused if available, otherwise fall
 	 * back to .disable
 	 * back to .disable
 	 */
 	 */
-	if (__clk_is_enabled(clk)) {
+	if (clk_core_is_enabled(clk)) {
 		if (clk->ops->disable_unused)
 		if (clk->ops->disable_unused)
 			clk->ops->disable_unused(clk->hw);
 			clk->ops->disable_unused(clk->hw);
 		else if (clk->ops->disable)
 		else if (clk->ops->disable)
@@ -486,9 +528,6 @@ static void clk_disable_unused_subtree(struct clk *clk)
 
 
 unlock_out:
 unlock_out:
 	clk_enable_unlock(flags);
 	clk_enable_unlock(flags);
-
-out:
-	return;
 }
 }
 
 
 static bool clk_ignore_unused;
 static bool clk_ignore_unused;
@@ -501,7 +540,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup);
 
 
 static int clk_disable_unused(void)
 static int clk_disable_unused(void)
 {
 {
-	struct clk *clk;
+	struct clk_core *clk;
 
 
 	if (clk_ignore_unused) {
 	if (clk_ignore_unused) {
 		pr_warn("clk: Not disabling unused clocks\n");
 		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)
 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);
 EXPORT_SYMBOL_GPL(__clk_get_name);
 
 
 struct clk_hw *__clk_get_hw(struct clk *clk)
 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);
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
 
 u8 __clk_get_num_parents(struct clk *clk)
 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);
 EXPORT_SYMBOL_GPL(__clk_get_num_parents);
 
 
 struct clk *__clk_get_parent(struct clk *clk)
 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);
 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)
 	if (!clk || index >= clk->num_parents)
 		return NULL;
 		return NULL;
 	else if (!clk->parents)
 	else if (!clk->parents)
-		return __clk_lookup(clk->parent_names[index]);
+		return clk_core_lookup(clk->parent_names[index]);
 	else if (!clk->parents[index])
 	else if (!clk->parents[index])
 		return clk->parents[index] =
 		return clk->parents[index] =
-			__clk_lookup(clk->parent_names[index]);
+			clk_core_lookup(clk->parent_names[index]);
 	else
 	else
 		return clk->parents[index];
 		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);
 EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
 
 
 unsigned int __clk_get_enable_count(struct clk *clk)
 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;
 	unsigned long ret;
 
 
@@ -593,9 +649,17 @@ unsigned long __clk_get_rate(struct clk *clk)
 out:
 out:
 	return ret;
 	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);
 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)
 	if (!clk)
 		return 0;
 		return 0;
@@ -605,11 +669,11 @@ static unsigned long __clk_get_accuracy(struct clk *clk)
 
 
 unsigned long __clk_get_flags(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);
 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;
 	int ret;
 
 
@@ -630,7 +694,15 @@ out:
 	return !!ret;
 	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;
 	int ret;
 
 
@@ -650,12 +722,21 @@ bool __clk_is_enabled(struct clk *clk)
 out:
 out:
 	return !!ret;
 	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);
 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))
 	if (!strcmp(clk->name, name))
 		return clk;
 		return clk;
@@ -669,10 +750,10 @@ static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
 	return NULL;
 	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)
 	if (!name)
 		return NULL;
 		return NULL;
@@ -694,42 +775,53 @@ struct clk *__clk_lookup(const char *name)
 	return NULL;
 	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)
+{
+	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 *clk = hw->clk, *parent, *best_parent = NULL;
+	struct clk_core *core = hw->core, *parent, *best_parent = NULL;
 	int i, num_parents;
 	int i, num_parents;
 	unsigned long parent_rate, best = 0;
 	unsigned long parent_rate, best = 0;
 
 
 	/* if NO_REPARENT flag set, pass through to current parent */
 	/* 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->hw, rate,
+						    min_rate, max_rate);
 		else if (parent)
 		else if (parent)
-			best = __clk_get_rate(parent);
+			best = clk_core_get_rate_nolock(parent);
 		else
 		else
-			best = __clk_get_rate(clk);
+			best = clk_core_get_rate_nolock(core);
 		goto out;
 		goto out;
 	}
 	}
 
 
 	/* find the parent that can provide the fastest rate <= rate */
 	/* 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++) {
 	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)
 		if (!parent)
 			continue;
 			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
 		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 = parent;
 			best = parent_rate;
 			best = parent_rate;
 		}
 		}
@@ -742,11 +834,63 @@ out:
 
 
 	return best;
 	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);
 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        ***/
 /***        clk api        ***/
 
 
-void __clk_unprepare(struct clk *clk)
+static void clk_core_unprepare(struct clk_core *clk)
 {
 {
 	if (!clk)
 	if (!clk)
 		return;
 		return;
@@ -762,7 +906,7 @@ void __clk_unprepare(struct clk *clk)
 	if (clk->ops->unprepare)
 	if (clk->ops->unprepare)
 		clk->ops->unprepare(clk->hw);
 		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;
 		return;
 
 
 	clk_prepare_lock();
 	clk_prepare_lock();
-	__clk_unprepare(clk);
+	clk_core_unprepare(clk->core);
 	clk_prepare_unlock();
 	clk_prepare_unlock();
 }
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
 
-int __clk_prepare(struct clk *clk)
+static int clk_core_prepare(struct clk_core *clk)
 {
 {
 	int ret = 0;
 	int ret = 0;
 
 
@@ -795,14 +939,14 @@ int __clk_prepare(struct clk *clk)
 		return 0;
 		return 0;
 
 
 	if (clk->prepare_count == 0) {
 	if (clk->prepare_count == 0) {
-		ret = __clk_prepare(clk->parent);
+		ret = clk_core_prepare(clk->parent);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 
 
 		if (clk->ops->prepare) {
 		if (clk->ops->prepare) {
 			ret = clk->ops->prepare(clk->hw);
 			ret = clk->ops->prepare(clk->hw);
 			if (ret) {
 			if (ret) {
-				__clk_unprepare(clk->parent);
+				clk_core_unprepare(clk->parent);
 				return ret;
 				return ret;
 			}
 			}
 		}
 		}
@@ -829,15 +973,18 @@ int clk_prepare(struct clk *clk)
 {
 {
 	int ret;
 	int ret;
 
 
+	if (!clk)
+		return 0;
+
 	clk_prepare_lock();
 	clk_prepare_lock();
-	ret = __clk_prepare(clk);
+	ret = clk_core_prepare(clk->core);
 	clk_prepare_unlock();
 	clk_prepare_unlock();
 
 
 	return ret;
 	return ret;
 }
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
 EXPORT_SYMBOL_GPL(clk_prepare);
 
 
-static void __clk_disable(struct clk *clk)
+static void clk_core_disable(struct clk_core *clk)
 {
 {
 	if (!clk)
 	if (!clk)
 		return;
 		return;
@@ -851,7 +998,15 @@ static void __clk_disable(struct clk *clk)
 	if (clk->ops->disable)
 	if (clk->ops->disable)
 		clk->ops->disable(clk->hw);
 		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);
 EXPORT_SYMBOL_GPL(clk_disable);
 
 
-static int __clk_enable(struct clk *clk)
+static int clk_core_enable(struct clk_core *clk)
 {
 {
 	int ret = 0;
 	int ret = 0;
 
 
@@ -890,7 +1045,7 @@ static int __clk_enable(struct clk *clk)
 		return -ESHUTDOWN;
 		return -ESHUTDOWN;
 
 
 	if (clk->enable_count == 0) {
 	if (clk->enable_count == 0) {
-		ret = __clk_enable(clk->parent);
+		ret = clk_core_enable(clk->parent);
 
 
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
@@ -898,7 +1053,7 @@ static int __clk_enable(struct clk *clk)
 		if (clk->ops->enable) {
 		if (clk->ops->enable) {
 			ret = clk->ops->enable(clk->hw);
 			ret = clk->ops->enable(clk->hw);
 			if (ret) {
 			if (ret) {
-				__clk_disable(clk->parent);
+				clk_core_disable(clk->parent);
 				return ret;
 				return ret;
 			}
 			}
 		}
 		}
@@ -908,6 +1063,14 @@ static int __clk_enable(struct clk *clk)
 	return 0;
 	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_enable - ungate a clock
  * @clk: the clk being ungated
  * @clk: the clk being ungated
@@ -934,17 +1097,13 @@ int clk_enable(struct clk *clk)
 }
 }
 EXPORT_SYMBOL_GPL(clk_enable);
 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;
 	unsigned long parent_rate = 0;
-	struct clk *parent;
+	struct clk_core *parent;
 	struct clk_hw *parent_hw;
 	struct clk_hw *parent_hw;
 
 
 	if (!clk)
 	if (!clk)
@@ -956,15 +1115,59 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
 
 
 	if (clk->ops->determine_rate) {
 	if (clk->ops->determine_rate) {
 		parent_hw = parent ? parent->hw : NULL;
 		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)
 	} else if (clk->ops->round_rate)
 		return clk->ops->round_rate(clk->hw, rate, &parent_rate);
 		return clk->ops->round_rate(clk->hw, rate, &parent_rate);
 	else if (clk->flags & CLK_SET_RATE_PARENT)
 	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
 	else
 		return clk->rate;
 		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);
 EXPORT_SYMBOL_GPL(__clk_round_rate);
 
 
 /**
 /**
@@ -980,6 +1183,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 {
 {
 	unsigned long ret;
 	unsigned long ret;
 
 
+	if (!clk)
+		return 0;
+
 	clk_prepare_lock();
 	clk_prepare_lock();
 	ret = __clk_round_rate(clk, rate);
 	ret = __clk_round_rate(clk, rate);
 	clk_prepare_unlock();
 	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
  * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
  * a driver returns that.
  * 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)
 		unsigned long old_rate, unsigned long new_rate)
 {
 {
 	struct clk_notifier *cn;
 	struct clk_notifier *cn;
 	struct clk_notifier_data cnd;
 	struct clk_notifier_data cnd;
 	int ret = NOTIFY_DONE;
 	int ret = NOTIFY_DONE;
 
 
-	cnd.clk = clk;
 	cnd.old_rate = old_rate;
 	cnd.old_rate = old_rate;
 	cnd.new_rate = new_rate;
 	cnd.new_rate = new_rate;
 
 
 	list_for_each_entry(cn, &clk_notifier_list, node) {
 	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,
 			ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
 					&cnd);
 					&cnd);
-			break;
 		}
 		}
 	}
 	}
 
 
@@ -1035,10 +1240,10 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
  *
  *
  * Caller must hold prepare_lock.
  * 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;
 	unsigned long parent_accuracy = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 
 	if (clk->parent)
 	if (clk->parent)
 		parent_accuracy = clk->parent->accuracy;
 		parent_accuracy = clk->parent->accuracy;
@@ -1053,6 +1258,20 @@ static void __clk_recalc_accuracies(struct clk *clk)
 		__clk_recalc_accuracies(child);
 		__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_get_accuracy - return the accuracy of clk
  * @clk: the clk whose accuracy is being returned
  * @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)
 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);
 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)
 	if (clk->ops->recalc_rate)
 		return clk->ops->recalc_rate(clk->hw, parent_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.
  * 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 old_rate;
 	unsigned long parent_rate = 0;
 	unsigned long parent_rate = 0;
-	struct clk *child;
+	struct clk_core *child;
 
 
 	old_rate = clk->rate;
 	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_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;
 	unsigned long rate;
 
 
@@ -1139,14 +1345,32 @@ unsigned long clk_get_rate(struct clk *clk)
 	if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
 	if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
 		__clk_recalc_rates(clk, 0);
 		__clk_recalc_rates(clk, 0);
 
 
-	rate = __clk_get_rate(clk);
+	rate = clk_core_get_rate_nolock(clk);
 	clk_prepare_unlock();
 	clk_prepare_unlock();
 
 
 	return rate;
 	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);
 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;
 	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,
 	 * find index of new parent clock using cached parent ptrs,
 	 * or if not yet cached, use string name comparison and cache
 	 * 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++) {
 	for (i = 0; i < clk->num_parents; i++) {
 		if (clk->parents[i] == parent)
 		if (clk->parents[i] == parent)
@@ -1170,7 +1394,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 			continue;
 			continue;
 
 
 		if (!strcmp(clk->parent_names[i], parent->name)) {
 		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;
 			return i;
 		}
 		}
 	}
 	}
@@ -1178,7 +1402,7 @@ static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
 	return -EINVAL;
 	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);
 	hlist_del(&clk->child_node);
 
 
@@ -1195,10 +1419,11 @@ static void clk_reparent(struct clk *clk, struct clk *new_parent)
 	clk->parent = 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;
 	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
 	 * 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.
 	 * See also: Comment for clk_set_parent() below.
 	 */
 	 */
 	if (clk->prepare_count) {
 	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 */
 	/* 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;
 	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
 	 * Finish the migration of prepare state and undo the changes done
 	 * for preventing a race with clk_enable().
 	 * 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;
 	unsigned long flags;
 	int ret = 0;
 	int ret = 0;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 
 	old_parent = __clk_set_parent_before(clk, 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);
 		clk_enable_unlock(flags);
 
 
 		if (clk->prepare_count) {
 		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;
 		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.
  * 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;
 	unsigned long new_rate;
 	int ret = NOTIFY_DONE;
 	int ret = NOTIFY_DONE;
 
 
@@ -1319,10 +1547,10 @@ out:
 	return ret;
 	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_rate = new_rate;
 	clk->new_parent = new_parent;
 	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
  * calculate the new rates returning the topmost clock that has to be
  * changed.
  * 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;
 	struct clk_hw *parent_hw;
 	unsigned long best_parent_rate = 0;
 	unsigned long best_parent_rate = 0;
 	unsigned long new_rate;
 	unsigned long new_rate;
+	unsigned long min_rate;
+	unsigned long max_rate;
 	int p_index = 0;
 	int p_index = 0;
 
 
 	/* sanity */
 	/* sanity */
@@ -1360,16 +1591,22 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
 	if (parent)
 	if (parent)
 		best_parent_rate = parent->rate;
 		best_parent_rate = parent->rate;
 
 
+	clk_core_get_boundaries(clk, &min_rate, &max_rate);
+
 	/* find the closest rate and parent clk/rate */
 	/* find the closest rate and parent clk/rate */
 	if (clk->ops->determine_rate) {
 	if (clk->ops->determine_rate) {
 		parent_hw = parent ? parent->hw : NULL;
 		parent_hw = parent ? parent->hw : NULL;
 		new_rate = clk->ops->determine_rate(clk->hw, rate,
 		new_rate = clk->ops->determine_rate(clk->hw, rate,
+						    min_rate,
+						    max_rate,
 						    &best_parent_rate,
 						    &best_parent_rate,
 						    &parent_hw);
 						    &parent_hw);
-		parent = parent_hw ? parent_hw->clk : NULL;
+		parent = parent_hw ? parent_hw->core : NULL;
 	} else if (clk->ops->round_rate) {
 	} else if (clk->ops->round_rate) {
 		new_rate = clk->ops->round_rate(clk->hw, rate,
 		new_rate = clk->ops->round_rate(clk->hw, rate,
 						&best_parent_rate);
 						&best_parent_rate);
+		if (new_rate < min_rate || new_rate > max_rate)
+			return NULL;
 	} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
 	} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
 		/* pass-through clock without adjustable parent */
 		/* pass-through clock without adjustable parent */
 		clk->new_rate = clk->rate;
 		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 */
 	/* try finding the new parent index */
-	if (parent) {
+	if (parent && clk->num_parents > 1) {
 		p_index = clk_fetch_parent_index(clk, parent);
 		p_index = clk_fetch_parent_index(clk, parent);
 		if (p_index < 0) {
 		if (p_index < 0) {
 			pr_debug("%s: clk %s can not be parent of clk %s\n",
 			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
  * so that in case of an error we can walk down the whole tree again and
  * abort the change.
  * 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;
 	int ret = NOTIFY_DONE;
 
 
 	if (clk->rate == clk->new_rate)
 	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
  * walk down a subtree and set the new rates notifying the rate
  * change on the way
  * 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;
 	struct hlist_node *tmp;
 	unsigned long old_rate;
 	unsigned long old_rate;
 	unsigned long best_parent_rate = 0;
 	unsigned long best_parent_rate = 0;
 	bool skip_set_rate = false;
 	bool skip_set_rate = false;
-	struct clk *old_parent;
+	struct clk_core *old_parent;
 
 
 	old_rate = clk->rate;
 	old_rate = clk->rate;
 
 
@@ -1506,6 +1744,45 @@ static void clk_change_rate(struct clk *clk)
 		clk_change_rate(clk->new_child);
 		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_set_rate - specify a new rate for clk
  * @clk: the clk whose rate is being changed
  * @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)
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
 {
-	struct clk *top, *fail_clk;
-	int ret = 0;
+	int ret;
 
 
 	if (!clk)
 	if (!clk)
 		return 0;
 		return 0;
@@ -1538,41 +1814,81 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	/* prevent racing with updates to the clock topology */
 	/* prevent racing with updates to the clock topology */
 	clk_prepare_lock();
 	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();
 	clk_prepare_unlock();
 
 
 	return ret;
 	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
  * 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
  * 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
  * .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;
 	u8 index;
 
 
 	/* handle the trivial cases */
 	/* handle the trivial cases */
@@ -1613,7 +1929,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
 
 
 	if (clk->num_parents == 1) {
 	if (clk->num_parents == 1) {
 		if (IS_ERR_OR_NULL(clk->parent))
 		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;
 		ret = clk->parent;
 		goto out;
 		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
 	 * 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);
 	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 *),
 			kcalloc(clk->num_parents, sizeof(struct clk *),
 					GFP_KERNEL);
 					GFP_KERNEL);
 
 
-	ret = clk_get_parent_by_index(clk, index);
+	ret = clk_core_get_parent_by_index(clk, index);
 
 
 out:
 out:
 	return ret;
 	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_reparent(clk, new_parent);
 	__clk_recalc_accuracies(clk);
 	__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
- *
- * 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.
+ * clk_has_parent - check if a clock is a possible parent for another
+ * @clk: clock source
+ * @parent: parent clock source
  *
  *
- * 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 ret = 0;
 	int p_index = 0;
 	int p_index = 0;
@@ -1728,6 +2062,31 @@ out:
 
 
 	return ret;
 	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);
 EXPORT_SYMBOL_GPL(clk_set_parent);
 
 
 /**
 /**
@@ -1764,13 +2123,13 @@ int clk_set_phase(struct clk *clk, int degrees)
 
 
 	clk_prepare_lock();
 	clk_prepare_lock();
 
 
-	if (!clk->ops->set_phase)
+	if (!clk->core->ops->set_phase)
 		goto out_unlock;
 		goto out_unlock;
 
 
-	ret = clk->ops->set_phase(clk->hw, degrees);
+	ret = clk->core->ops->set_phase(clk->core->hw, degrees);
 
 
 	if (!ret)
 	if (!ret)
-		clk->phase = degrees;
+		clk->core->phase = degrees;
 
 
 out_unlock:
 out_unlock:
 	clk_prepare_unlock();
 	clk_prepare_unlock();
@@ -1778,15 +2137,9 @@ out_unlock:
 out:
 out:
 	return ret;
 	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;
 	int ret = 0;
 
 
@@ -1800,28 +2153,48 @@ int clk_get_phase(struct clk *clk)
 out:
 out:
 	return ret;
 	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
  * __clk_init - initialize the data structures in a struct clk
  * @dev:	device initializing this clk, placeholder for now
  * @dev:	device initializing this clk, placeholder for now
  * @clk:	clk being initialized
  * @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.
  * 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;
 	int i, ret = 0;
-	struct clk *orphan;
+	struct clk_core *orphan;
 	struct hlist_node *tmp2;
 	struct hlist_node *tmp2;
+	struct clk_core *clk;
+	unsigned long rate;
 
 
-	if (!clk)
+	if (!clk_user)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	clk = clk_user->core;
+
 	clk_prepare_lock();
 	clk_prepare_lock();
 
 
 	/* check to see if a clock with this name is already registered */
 	/* 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",
 		pr_debug("%s: clk %s already initialized\n",
 				__func__, clk->name);
 				__func__, clk->name);
 		ret = -EEXIST;
 		ret = -EEXIST;
@@ -1873,7 +2246,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 		clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
 		clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
 					GFP_KERNEL);
 					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
 		 * clk_init'd; thus any access to clk->parents[] must check
 		 * for a NULL pointer.  We can always perform lazy lookups for
 		 * for a NULL pointer.  We can always perform lazy lookups for
 		 * missing parents later on.
 		 * missing parents later on.
@@ -1881,7 +2254,7 @@ int __clk_init(struct device *dev, struct clk *clk)
 		if (clk->parents)
 		if (clk->parents)
 			for (i = 0; i < clk->num_parents; i++)
 			for (i = 0; i < clk->num_parents; i++)
 				clk->parents[i] =
 				clk->parents[i] =
-					__clk_lookup(clk->parent_names[i]);
+					clk_core_lookup(clk->parent_names[i]);
 	}
 	}
 
 
 	clk->parent = __clk_init_parent(clk);
 	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.
 	 * then rate is set to zero.
 	 */
 	 */
 	if (clk->ops->recalc_rate)
 	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)
 	else if (clk->parent)
-		clk->rate = clk->parent->rate;
+		rate = clk->parent->rate;
 	else
 	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
 	 * 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) {
 		if (orphan->num_parents && orphan->ops->get_parent) {
 			i = orphan->ops->get_parent(orphan->hw);
 			i = orphan->ops->get_parent(orphan->hw);
 			if (!strcmp(clk->name, orphan->parent_names[i]))
 			if (!strcmp(clk->name, orphan->parent_names[i]))
-				__clk_reparent(orphan, clk);
+				clk_core_reparent(orphan, clk);
 			continue;
 			continue;
 		}
 		}
 
 
 		for (i = 0; i < orphan->num_parents; i++)
 		for (i = 0; i < orphan->num_parents; i++)
 			if (!strcmp(clk->name, orphan->parent_names[i])) {
 			if (!strcmp(clk->name, orphan->parent_names[i])) {
-				__clk_reparent(orphan, clk);
+				clk_core_reparent(orphan, clk);
 				break;
 				break;
 			}
 			}
 	 }
 	 }
@@ -1983,47 +2357,39 @@ out:
 	return ret;
 	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;
 	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;
+
+	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;
 
 
-	ret = __clk_init(dev, clk);
-	if (ret)
-		return ERR_PTR(ret);
+	clk_prepare_lock();
+	hlist_add_head(&clk->child_node, &hw->core->clks);
+	clk_prepare_unlock();
 
 
 	return clk;
 	return clk;
 }
 }
-EXPORT_SYMBOL_GPL(__clk_register);
+
+static 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
  * 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)
 struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 {
 {
 	int i, ret;
 	int i, ret;
-	struct clk *clk;
+	struct clk_core *clk;
 
 
 	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
 	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
 	if (!clk) {
 	if (!clk) {
@@ -2060,7 +2426,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 	clk->hw = hw;
 	clk->hw = hw;
 	clk->flags = hw->init->flags;
 	clk->flags = hw->init->flags;
 	clk->num_parents = hw->init->num_parents;
 	clk->num_parents = hw->init->num_parents;
-	hw->clk = clk;
+	hw->core = clk;
 
 
 	/* allocate local copy in case parent_names is __initdata */
 	/* allocate local copy in case parent_names is __initdata */
 	clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
 	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)
 	if (!ret)
-		return clk;
+		return hw->clk;
+
+	__clk_free_clk(hw->clk);
+	hw->clk = NULL;
 
 
 fail_parent_names_copy:
 fail_parent_names_copy:
 	while (--i >= 0)
 	while (--i >= 0)
@@ -2107,7 +2485,7 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
  */
 static void __clk_release(struct kref *ref)
 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;
 	int i = clk->num_parents;
 
 
 	kfree(clk->parents);
 	kfree(clk->parents);
@@ -2165,12 +2543,13 @@ void clk_unregister(struct clk *clk)
 	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
 	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
 		return;
 		return;
 
 
-	clk_debug_unregister(clk);
+	clk_debug_unregister(clk->core);
 
 
 	clk_prepare_lock();
 	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;
 		return;
 	}
 	}
 	/*
 	/*
@@ -2178,24 +2557,25 @@ void clk_unregister(struct clk *clk)
 	 * a reference to this clock.
 	 * a reference to this clock.
 	 */
 	 */
 	flags = clk_enable_lock();
 	flags = clk_enable_lock();
-	clk->ops = &clk_nodrv_ops;
+	clk->core->ops = &clk_nodrv_ops;
 	clk_enable_unlock(flags);
 	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;
 		struct hlist_node *t;
 
 
 		/* Reparent all children to the orphan list. */
 		/* 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",
 		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();
 	clk_prepare_unlock();
 }
 }
@@ -2263,11 +2643,13 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
  */
  */
 int __clk_get(struct clk *clk)
 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;
 			return 0;
 
 
-		kref_get(&clk->ref);
+		kref_get(&core->ref);
 	}
 	}
 	return 1;
 	return 1;
 }
 }
@@ -2280,11 +2662,17 @@ void __clk_put(struct clk *clk)
 		return;
 		return;
 
 
 	clk_prepare_lock();
 	clk_prepare_lock();
-	owner = clk->owner;
-	kref_put(&clk->ref, __clk_release);
+
+	hlist_del(&clk->child_node);
+	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();
 	clk_prepare_unlock();
 
 
 	module_put(owner);
 	module_put(owner);
+
+	kfree(clk);
 }
 }
 
 
 /***        clk rate change notifiers        ***/
 /***        clk rate change notifiers        ***/
@@ -2339,7 +2727,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
 
 
 	ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
 	ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
 
 
-	clk->notifier_count++;
+	clk->core->notifier_count++;
 
 
 out:
 out:
 	clk_prepare_unlock();
 	clk_prepare_unlock();
@@ -2376,7 +2764,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
 	if (cn->clk == clk) {
 	if (cn->clk == clk) {
 		ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
 		ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
 
 
-		clk->notifier_count--;
+		clk->core->notifier_count--;
 
 
 		/* XXX the notifier code should handle this better */
 		/* XXX the notifier code should handle this better */
 		if (!cn->notifier_head.head) {
 		if (!cn->notifier_head.head) {

+ 5 - 0
drivers/clk/clk.h

@@ -9,9 +9,14 @@
  * published by the Free Software Foundation.
  * published by the Free Software Foundation.
  */
  */
 
 
+struct clk_hw;
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 #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_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);
 void of_clk_lock(void);
 void of_clk_lock(void);
 void of_clk_unlock(void);
 void of_clk_unlock(void);
 #endif
 #endif
+
+struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+			     const char *con_id);

+ 66 - 19
drivers/clk/clkdev.c

@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of.h>
 
 
 #include "clk.h"
 #include "clk.h"
@@ -53,7 +54,7 @@ struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
 	return clk;
 	return clk;
 }
 }
 
 
-struct clk *of_clk_get(struct device_node *np, int index)
+static struct clk *__of_clk_get(struct device_node *np, int index)
 {
 {
 	struct of_phandle_args clkspec;
 	struct of_phandle_args clkspec;
 	struct clk *clk;
 	struct clk *clk;
@@ -69,20 +70,24 @@ struct clk *of_clk_get(struct device_node *np, int index)
 
 
 	clk = of_clk_get_by_clkspec(&clkspec);
 	clk = of_clk_get_by_clkspec(&clkspec);
 	of_node_put(clkspec.np);
 	of_node_put(clkspec.np);
+
+	return clk;
+}
+
+struct clk *of_clk_get(struct device_node *np, int index)
+{
+	struct clk *clk = __of_clk_get(np, index);
+
+	if (!IS_ERR(clk))
+		clk = __clk_create_clk(__clk_get_hw(clk), np->full_name, NULL);
+
 	return clk;
 	return clk;
 }
 }
 EXPORT_SYMBOL(of_clk_get);
 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);
 	struct clk *clk = ERR_PTR(-ENOENT);
 
 
@@ -97,9 +102,11 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 		 */
 		 */
 		if (name)
 		if (name)
 			index = of_property_match_string(np, "clock-names", 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);
+		if (!IS_ERR(clk)) {
+			clk = __clk_create_clk(__clk_get_hw(clk), dev_id, name);
 			break;
 			break;
+		}
 		else if (name && index >= 0) {
 		else if (name && index >= 0) {
 			if (PTR_ERR(clk) != -EPROBE_DEFER)
 			if (PTR_ERR(clk) != -EPROBE_DEFER)
 				pr_err("ERROR: could not get clock %s:%s(%i)\n",
 				pr_err("ERROR: could not get clock %s:%s(%i)\n",
@@ -119,7 +126,33 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 
 
 	return clk;
 	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);
 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
 #endif
 
 
 /*
 /*
@@ -168,14 +201,29 @@ 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 *clk_get_sys(const char *dev_id, const char *con_id)
 {
 {
 	struct clk_lookup *cl;
 	struct clk_lookup *cl;
+	struct clk *clk = NULL;
 
 
 	mutex_lock(&clocks_mutex);
 	mutex_lock(&clocks_mutex);
+
 	cl = clk_find(dev_id, con_id);
 	cl = clk_find(dev_id, con_id);
-	if (cl && !__clk_get(cl->clk))
+	if (!cl)
+		goto out;
+
+	if (!__clk_get(cl->clk)) {
 		cl = NULL;
 		cl = NULL;
+		goto out;
+	}
+
+#if defined(CONFIG_COMMON_CLK)
+	clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id);
+#else
+	clk = cl->clk;
+#endif
+
+out:
 	mutex_unlock(&clocks_mutex);
 	mutex_unlock(&clocks_mutex);
 
 
-	return cl ? cl->clk : ERR_PTR(-ENOENT);
+	return cl ? clk : ERR_PTR(-ENOENT);
 }
 }
 EXPORT_SYMBOL(clk_get_sys);
 EXPORT_SYMBOL(clk_get_sys);
 
 
@@ -185,10 +233,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
 	struct clk *clk;
 	struct clk *clk;
 
 
 	if (dev) {
 	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;
 			return clk;
 	}
 	}
 
 
@@ -331,6 +377,7 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 
 
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(clk_register_clkdev);
 
 
 /**
 /**
  * clk_register_clkdevs - register a set of clk_lookup for a struct clk
  * 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,
 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,
 			      unsigned long *best_parent_rate,
 			      struct clk_hw **best_parent_p)
 			      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,
 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,
 					unsigned long *best_parent_rate,
 					struct clk_hw **best_parent_clk)
 					struct clk_hw **best_parent_clk)
 {
 {

+ 1 - 0
drivers/clk/pxa/Makefile

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

+ 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,
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  i2c, USB, SD/eMMC, etc.
 	  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
 config MSM_GCC_8660
 	tristate "MSM8660 Global Clock Controller"
 	tristate "MSM8660 Global Clock Controller"
 	depends on COMMON_CLK_QCOM
 	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,
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  i2c, USB, SD/eMMC, SATA, PCIe, etc.
 	  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
 config MSM_MMCC_8960
 	tristate "MSM8960 Multimedia Clock Controller"
 	tristate "MSM8960 Multimedia Clock Controller"
 	select MSM_GCC_8960
 	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-rcg.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-branch.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
 clk-qcom-y += reset.o
 
 
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.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_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.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_GCC_8974) += gcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.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
 static long
 clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
 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)
 		       unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_pll *pll = to_clk_pll(hw);
 	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,
 static long _freq_tbl_determine_rate(struct clk_hw *hw,
 		const struct freq_tbl *f, unsigned long rate,
 		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 *p_rate, struct clk_hw **p_hw)
 {
 {
 	unsigned long clk_flags;
 	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,
 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)
 		unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_rcg *rcg = to_clk_rcg(hw);
 	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,
 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)
 		unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
 	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,
 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)
 		unsigned long *p_rate, struct clk_hw **p_hw)
 {
 {
 	struct clk_rcg *rcg = to_clk_rcg(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,
 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)
 		unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	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,
 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)
 				 unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	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);
 EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
 
 
 static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
 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)
 			 unsigned long *p_rate, struct clk_hw **p_hw)
 {
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(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,
 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)
 				 unsigned long *p_rate, struct clk_hw **p)
 {
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	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 = {
 static struct clk_pll pll8 = {
 	.l_reg = 0x3144,
 	.l_reg = 0x3144,
 	.m_reg = 0x3148,
 	.m_reg = 0x3148,
@@ -2163,6 +2174,7 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
 	[PLL0] = &pll0.clkr,
 	[PLL0] = &pll0.clkr,
 	[PLL0_VOTE] = &pll0_vote,
 	[PLL0_VOTE] = &pll0_vote,
 	[PLL3] = &pll3.clkr,
 	[PLL3] = &pll3.clkr,
+	[PLL4_VOTE] = &pll4_vote,
 	[PLL8] = &pll8.clkr,
 	[PLL8] = &pll8.clkr,
 	[PLL8_VOTE] = &pll8_vote,
 	[PLL8_VOTE] = &pll8_vote,
 	[PLL14] = &pll14.clkr,
 	[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,
 	COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
 			RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 8, GFLAGS),
 			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_CLKSEL_CON(17), 0,
 			RK3288_CLKGATE_CON(1), 9, GFLAGS),
 			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),
 			RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
 	MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
 	MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
 			RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
 	COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 10, GFLAGS),
 			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_CLKSEL_CON(18), 0,
 			RK3288_CLKGATE_CON(1), 11, GFLAGS),
 			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),
 			RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
 	COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 12, GFLAGS),
 			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_CLKSEL_CON(19), 0,
 			RK3288_CLKGATE_CON(1), 13, GFLAGS),
 			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),
 			RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
 	COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 14, GFLAGS),
 			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_CLKSEL_CON(20), 0,
 			RK3288_CLKGATE_CON(1), 15, GFLAGS),
 			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),
 			RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
 	COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(2), 12, GFLAGS),
 			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_CLKSEL_CON(7), 0,
 			RK3288_CLKGATE_CON(2), 13, GFLAGS),
 			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),
 			RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
 
 
 	COMPOSITE(0, "mac_src", mux_pll_src_npll_cpll_gpll_p, 0,
 	COMPOSITE(0, "mac_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,
 	GATE(0, "jtag", "ext_jtag", 0,
 			RK3288_CLKGATE_CON(4), 14, GFLAGS),
 			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_CLKSEL_CON(13), 11, 2, MFLAGS,
 			RK3288_CLKGATE_CON(5), 14, GFLAGS),
 			RK3288_CLKGATE_CON(5), 14, GFLAGS),
 	COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
 	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_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(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),
 	GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
 
 
 	/* sclk_gpu gates */
 	/* sclk_gpu gates */
@@ -805,6 +805,20 @@ static int rk3288_clk_suspend(void)
 		rk3288_saved_cru_regs[i] =
 		rk3288_saved_cru_regs[i] =
 				readl_relaxed(rk3288_cru_base + reg_id);
 				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;
 	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",
 		pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
 			__func__, PTR_ERR(clk));
 			__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,
 	rockchip_clk_register_plls(rk3288_pll_clks,
 				   ARRAY_SIZE(rk3288_pll_clks),
 				   ARRAY_SIZE(rk3288_pll_clks),
 				   RK3288_GRF_SOC_STATUS1);
 				   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 */
 /* register exynos_audss clocks */
 static int exynos_audss_clk_probe(struct platform_device *pdev)
 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;
 	return 0;
 
 
 unregister:
 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))
 	if (!IS_ERR(epll))
 		clk_disable_unprepare(epll);
 		clk_disable_unprepare(epll);
@@ -232,18 +249,13 @@ unregister:
 
 
 static int exynos_audss_clk_remove(struct platform_device *pdev)
 static int exynos_audss_clk_remove(struct platform_device *pdev)
 {
 {
-	int i;
-
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
 	unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
 	unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
 #endif
 #endif
 
 
 	of_clk_del_provider(pdev->dev.of_node);
 	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))
 	if (!IS_ERR(epll))
 		clk_disable_unprepare(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_CORE1_WFI			(1 << 1)
 #define PWR_CTRL1_USE_CORE0_WFI			(1 << 0)
 #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 = {
 static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
 	SRC_LEFTBUS,
 	SRC_LEFTBUS,
 	DIV_LEFTBUS,
 	DIV_LEFTBUS,
@@ -195,43 +174,6 @@ static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
 	PWR_CTRL2,
 	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 */
 /* list of all parent clock list */
 PNAME(mout_vpllsrc_p)		= { "fin_pll", };
 PNAME(mout_vpllsrc_p)		= { "fin_pll", };
 
 
@@ -782,18 +724,18 @@ static struct samsung_pll_rate_table exynos3250_vpll_rates[] = {
 	{ /* sentinel */ }
 	{ /* 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;
 	unsigned int tmp;
 
 
@@ -814,38 +756,31 @@ static void __init exynos3_core_down_clock(void)
 	__raw_writel(0x0, reg_base + PWR_CTRL2);
 	__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)
 static void __init exynos3250_cmu_init(struct device_node *np)
 {
 {
 	struct samsung_clk_provider *ctx;
 	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)
 	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);
 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 EPLL_CON2		0x111c
 #define SRC_EPLL		0x1120
 #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 = {
 static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = {
 	BPLL_LOCK,
 	BPLL_LOCK,
 	BPLL_CON0,
 	BPLL_CON0,
@@ -899,43 +828,6 @@ static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = {
 	SRC_EPLL,
 	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_epll_p)	= { "fin_pll", "fout_epll", };
 PNAME(mout_bpll_p)	= { "fin_pll", "fout_bpll", };
 PNAME(mout_bpll_p)	= { "fin_pll", "fout_bpll", };
 PNAME(mout_mpll_mif_p)	= { "fin_pll", "sclk_mpll_mif", };
 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),
 	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)
 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",
 CLK_OF_DECLARE(exynos3250_cmu_dmc, "samsung,exynos3250-cmu-dmc",
 		exynos3250_cmu_dmc_init);
 		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 */
 /* list of divider clocks supported in all exynos4 soc's */
 static struct samsung_div_clock exynos4_div_clks[] __initdata = {
 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_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
 	DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
 	DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
 			CLKOUT_CMU_LEFTBUS, 8, 6),
 			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_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
 	DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
 	DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
 			CLKOUT_CMU_RIGHTBUS, 8, 6),
 			CLKOUT_CMU_RIGHTBUS, 8, 6),
@@ -781,10 +781,10 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
 			CLK_SET_RATE_PARENT, 0),
 			CLK_SET_RATE_PARENT, 0),
 	DIV(0, "div_clkout_top", "mout_clkout_top", CLKOUT_CMU_TOP, 8, 6),
 	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_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
 	DIV(0, "div_dphy", "mout_dphy", DIV_DMC0, 8, 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_dmcd", "div_dmc", DIV_DMC0, 16, 3),
 	DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
 	DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
 	DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
 	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,
 	DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
 						8, 3, CLK_GET_RATE_NOCACHE, 0),
 						8, 3, CLK_GET_RATE_NOCACHE, 0),
 	DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
 	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),
 	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_CPU0		0x14500
 #define DIV_CPU1		0x14504
 #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 = {
 static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
 	SRC_LEFTBUS,
 	SRC_LEFTBUS,
 	DIV_LEFTBUS,
 	DIV_LEFTBUS,
@@ -219,41 +206,6 @@ static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
 	DIV_CPU1,
 	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 */
 /* list of all parent clock list */
 PNAME(mout_g3d_pllsrc_p)	= { "fin_pll", };
 PNAME(mout_g3d_pllsrc_p)	= { "fin_pll", };
 
 
@@ -959,56 +911,40 @@ static struct samsung_pll_rate_table exynos4415_epll_rates[] = {
 	{ /* sentinel */ }
 	{ /* 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)
 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);
 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 SRC_DMC			0x300
 #define DIV_DMC1		0x504
 #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 = {
 static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
 	MPLL_LOCK,
 	MPLL_LOCK,
 	MPLL_CON0,
 	MPLL_CON0,
@@ -1050,42 +976,6 @@ static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
 	DIV_DMC1,
 	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_mpll_p)		= { "fin_pll", "fout_mpll", };
 PNAME(mout_bpll_p)		= { "fin_pll", "fout_bpll", };
 PNAME(mout_bpll_p)		= { "fin_pll", "fout_bpll", };
 PNAME(mbpll_p)			= { "mout_mpll", "mout_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),
 	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)
 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",
 CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
 		exynos4415_cmu_dmc_init);
 		exynos4415_cmu_dmc_init);

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

@@ -34,6 +34,7 @@
 #define DIV_TOPC0		0x0600
 #define DIV_TOPC0		0x0600
 #define DIV_TOPC1		0x0604
 #define DIV_TOPC1		0x0604
 #define DIV_TOPC3		0x060C
 #define DIV_TOPC3		0x060C
+#define ENABLE_ACLK_TOPC1	0x0804
 
 
 static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
 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),
 	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 */
 /* 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_bus0_pll_ctrl_p)	= { "fin_pll", "fout_bus0_pll" };
 PNAME(mout_bus1_pll_ctrl_p)	= { "fin_pll", "fout_bus1_pll" };
 PNAME(mout_bus1_pll_ctrl_p)	= { "fin_pll", "fout_bus1_pll" };
 PNAME(mout_cc_pll_ctrl_p)	= { "fin_pll", "fout_cc_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(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p,
 		MUX_SEL_TOPC1, 16, 1),
 		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_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),
 	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(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133",
 		DIV_TOPC0, 4, 4),
 		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(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
 		DIV_TOPC1, 24, 4),
 		DIV_TOPC1, 24, 4),
 
 
@@ -125,6 +131,18 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
 		DIV_TOPC3, 12, 3),
 		DIV_TOPC3, 12, 3),
 	DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
 	DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
 		DIV_TOPC3, 16, 3),
 		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 = {
 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),
 		BUS1_DPLL_CON0, NULL),
 	PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK,
 	PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK,
 		MFC_PLL_CON0, NULL),
 		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 = {
 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),
 	.nr_mux_clks		= ARRAY_SIZE(topc_mux_clks),
 	.div_clks		= topc_div_clks,
 	.div_clks		= topc_div_clks,
 	.nr_div_clks		= ARRAY_SIZE(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,
 	.fixed_factor_clks	= topc_fixed_factor_clks,
 	.nr_fixed_factor_clks	= ARRAY_SIZE(topc_fixed_factor_clks),
 	.nr_fixed_factor_clks	= ARRAY_SIZE(topc_fixed_factor_clks),
 	.nr_clk_ids		= TOPC_NR_CLK,
 	.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_TOP00			0x0200
 #define MUX_SEL_TOP01			0x0204
 #define MUX_SEL_TOP01			0x0204
 #define MUX_SEL_TOP03			0x020C
 #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 MUX_SEL_TOP0_PERIC3		0x023C
 #define DIV_TOP03			0x060C
 #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 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
 #define ENABLE_SCLK_TOP0_PERIC3		0x0A3C
 
 
 /* List of parent clocks for Muxes in CMU_TOP0 */
 /* 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_bus1_pll_p)	= { "fin_pll", "dout_sclk_bus1_pll" };
 PNAME(mout_cc_pll_p)	= { "fin_pll", "dout_sclk_cc_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_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",
 PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll",
 	"ffac_top0_bus0_pll_div2"};
 	"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",
 PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll",
 	"mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
 	"mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
 	"mout_top0_half_mfc_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 = {
 static unsigned long top0_clk_regs[] __initdata = {
 	MUX_SEL_TOP00,
 	MUX_SEL_TOP00,
 	MUX_SEL_TOP01,
 	MUX_SEL_TOP01,
 	MUX_SEL_TOP03,
 	MUX_SEL_TOP03,
+	MUX_SEL_TOP0_PERIC0,
+	MUX_SEL_TOP0_PERIC1,
+	MUX_SEL_TOP0_PERIC2,
 	MUX_SEL_TOP0_PERIC3,
 	MUX_SEL_TOP0_PERIC3,
 	DIV_TOP03,
 	DIV_TOP03,
+	DIV_TOP0_PERIC0,
+	DIV_TOP0_PERIC1,
+	DIV_TOP0_PERIC2,
 	DIV_TOP0_PERIC3,
 	DIV_TOP0_PERIC3,
+	ENABLE_SCLK_TOP0_PERIC0,
+	ENABLE_SCLK_TOP0_PERIC1,
+	ENABLE_SCLK_TOP0_PERIC2,
 	ENABLE_SCLK_TOP0_PERIC3,
 	ENABLE_SCLK_TOP0_PERIC3,
 };
 };
 
 
 static struct samsung_mux_clock top0_mux_clks[] __initdata = {
 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_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_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),
 	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_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_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_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_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_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_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 = {
 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(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66",
 		DIV_TOP03, 20, 6),
 		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_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_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_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_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 = {
 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",
 	GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_sclk_uart3",
 		ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0),
 		ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0),
 	GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_sclk_uart2",
 	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),
 		ENABLE_SCLK_TOP0_PERIC3, 12, 0, 0),
 	GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0",
 	GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0",
 		ENABLE_SCLK_TOP0_PERIC3, 16, 0, 0),
 		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 = {
 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_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_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_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2),
 	MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 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(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
 		DIV_TOP1_FSYS0, 24, 4),
 		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(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
 		DIV_TOP1_FSYS1, 24, 4),
 		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 = {
 static struct samsung_gate_clock top1_gate_clks[] __initdata = {
 	GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
 	GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
 		ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0),
 		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",
 	GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
 		ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0),
 		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) */
 /* Register Offset definitions for CMU_PERIC1 (0x14C80000) */
 #define MUX_SEL_PERIC10			0x0200
 #define MUX_SEL_PERIC10			0x0200
 #define MUX_SEL_PERIC11			0x0204
 #define MUX_SEL_PERIC11			0x0204
+#define MUX_SEL_PERIC12			0x0208
 #define ENABLE_PCLK_PERIC1		0x0900
 #define ENABLE_PCLK_PERIC1		0x0900
 #define ENABLE_SCLK_PERIC10		0x0A00
 #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_uart1_p)	= { "fin_pll", "sclk_uart1" };
 PNAME(mout_sclk_uart2_p)	= { "fin_pll", "sclk_uart2" };
 PNAME(mout_sclk_uart2_p)	= { "fin_pll", "sclk_uart2" };
 PNAME(mout_sclk_uart3_p)	= { "fin_pll", "sclk_uart3" };
 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 = {
 static unsigned long peric1_clk_regs[] __initdata = {
 	MUX_SEL_PERIC10,
 	MUX_SEL_PERIC10,
 	MUX_SEL_PERIC11,
 	MUX_SEL_PERIC11,
+	MUX_SEL_PERIC12,
 	ENABLE_PCLK_PERIC1,
 	ENABLE_PCLK_PERIC1,
 	ENABLE_SCLK_PERIC10,
 	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(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p,
 		MUX_SEL_PERIC10, 0, 1),
 		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(0, "mout_sclk_uart1_user", mout_sclk_uart1_p,
 		MUX_SEL_PERIC11, 20, 1),
 		MUX_SEL_PERIC11, 20, 1),
 	MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p,
 	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),
 		ENABLE_PCLK_PERIC1, 10, 0, 0),
 	GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user",
 	GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user",
 		ENABLE_PCLK_PERIC1, 11, 0, 0),
 		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",
 	GATE(SCLK_UART1, "sclk_uart1_user", "mout_sclk_uart1_user",
 		ENABLE_SCLK_PERIC10, 9, 0, 0),
 		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),
 		ENABLE_SCLK_PERIC10, 10, 0, 0),
 	GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user",
 	GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user",
 		ENABLE_SCLK_PERIC10, 11, 0, 0),
 		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 = {
 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) */
 /* Register Offset definitions for CMU_FSYS0 (0x10E90000) */
 #define MUX_SEL_FSYS00			0x0200
 #define MUX_SEL_FSYS00			0x0200
 #define MUX_SEL_FSYS01			0x0204
 #define MUX_SEL_FSYS01			0x0204
+#define MUX_SEL_FSYS02			0x0208
+#define ENABLE_ACLK_FSYS00		0x0800
 #define ENABLE_ACLK_FSYS01		0x0804
 #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
  * 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_aclk_fsys0_200_p)	= { "fin_pll", "dout_aclk_fsys0_200" };
 PNAME(mout_sclk_mmc2_p)		= { "fin_pll", "sclk_mmc2" };
 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 = {
 static unsigned long fsys0_clk_regs[] __initdata = {
 	MUX_SEL_FSYS00,
 	MUX_SEL_FSYS00,
 	MUX_SEL_FSYS01,
 	MUX_SEL_FSYS01,
+	MUX_SEL_FSYS02,
+	ENABLE_ACLK_FSYS00,
 	ENABLE_ACLK_FSYS01,
 	ENABLE_ACLK_FSYS01,
+	ENABLE_SCLK_FSYS01,
+	ENABLE_SCLK_FSYS02,
+	ENABLE_SCLK_FSYS04,
 };
 };
 
 
 static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
 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_SEL_FSYS00, 24, 1),
 
 
 	MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 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 = {
 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",
 	GATE(ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys0_200_user",
 		ENABLE_ACLK_FSYS01, 31, 0, 0),
 		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 = {
 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",
 CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1",
 	exynos7_clk_fsys1_init);
 	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
  * Common function which registers plls, muxes, dividers and gates
  * for each CMU. It also add CMU register list to register cache.
  * 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)
 			struct samsung_cmu_info *cmu)
 {
 {
 	void __iomem *reg_base;
 	void __iomem *reg_base;
 	struct samsung_clk_provider *ctx;
 	struct samsung_clk_provider *ctx;
 
 
 	reg_base = of_iomap(np, 0);
 	reg_base = of_iomap(np, 0);
-	if (!reg_base)
+	if (!reg_base) {
 		panic("%s: failed to map registers\n", __func__);
 		panic("%s: failed to map registers\n", __func__);
+		return NULL;
+	}
 
 
 	ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
 	ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
-	if (!ctx)
+	if (!ctx) {
 		panic("%s: unable to alllocate ctx\n", __func__);
 		panic("%s: unable to alllocate ctx\n", __func__);
+		return ctx;
+	}
 
 
 	if (cmu->pll_clks)
 	if (cmu->pll_clks)
 		samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_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);
 			cmu->nr_clk_regs);
 
 
 	samsung_clk_of_add_provider(np, ctx);
 	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,
 			struct samsung_pll_clock *pll_list,
 			unsigned int nr_clk, void __iomem *base);
 			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 *);
 			struct samsung_cmu_info *);
 
 
 extern unsigned long _get_rate(const char *clk_name);
 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_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)		+= clk-rz.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_R8A7740)		+= clk-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7779)		+= clk-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7779)		+= clk-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= 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_R8A7794)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o

+ 11 - 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)
 static void cpg_div6_clock_disable(struct clk_hw *hw)
 {
 {
 	struct div6_clock *clock = to_div6_clock(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)
 static int cpg_div6_clock_is_enabled(struct clk_hw *hw)

+ 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			0x000000e0
 #define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
 #define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
 #define CPG_FRQCRC_ZFC_SHIFT		8
 #define CPG_FRQCRC_ZFC_SHIFT		8
+#define CPG_ADSPCKCR			0x0000025c
+#define CPG_RCANCKCR			0x00000270
 
 
 /* -----------------------------------------------------------------------------
 /* -----------------------------------------------------------------------------
  * Z Clock
  * Z Clock
@@ -161,6 +163,88 @@ static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
 	return clk;
 	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
  * CPG Clock Data
  */
  */
@@ -263,6 +347,10 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
 		shift = 0;
 		shift = 0;
 	} else if (!strcmp(name, "z")) {
 	} else if (!strcmp(name, "z")) {
 		return cpg_z_clk_register(cpg);
 		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 {
 	} else {
 		return ERR_PTR(-EINVAL);
 		return ERR_PTR(-EINVAL);
 	}
 	}

+ 15 - 4
drivers/clk/st/clk-flexgen.c

@@ -138,16 +138,27 @@ static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct flexgen *flexgen = to_flexgen(hw);
 	struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
 	struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
 	struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
 	struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
-	unsigned long primary_div = 0;
+	unsigned long div = 0;
 	int ret = 0;
 	int ret = 0;
 
 
 	pdiv_hw->clk = hw->clk;
 	pdiv_hw->clk = hw->clk;
 	fdiv_hw->clk = hw->clk;
 	fdiv_hw->clk = hw->clk;
 
 
-	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;
 	return ret;
 }
 }

+ 1 - 0
drivers/clk/sunxi/Makefile

@@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-mod0.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun9i-core.o
 obj-y += clk-sun9i-core.o
+obj-y += clk-sun9i-mmc.o
 
 
 obj-$(CONFIG_MFD_SUN6I_PRCM) += \
 obj-$(CONFIG_MFD_SUN6I_PRCM) += \
 	clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
 	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,
 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,
 				       unsigned long *best_parent_rate,
 				       struct clk_hw **best_parent_p)
 				       struct clk_hw **best_parent_p)
 {
 {
@@ -156,9 +158,10 @@ static const struct clk_ops clk_factors_ops = {
 	.set_rate = clk_factors_set_rate,
 	.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 *clk;
 	struct clk_factors *factors;
 	struct clk_factors *factors;
@@ -168,11 +171,8 @@ struct clk * __init sunxi_factors_register(struct device_node *node,
 	struct clk_hw *mux_hw = NULL;
 	struct clk_hw *mux_hw = NULL;
 	const char *clk_name = node->name;
 	const char *clk_name = node->name;
 	const char *parents[FACTORS_MAX_PARENTS];
 	const char *parents[FACTORS_MAX_PARENTS];
-	void __iomem *reg;
 	int i = 0;
 	int i = 0;
 
 
-	reg = of_iomap(node, 0);
-
 	/* if we have a mux, we will have >1 parents */
 	/* if we have a mux, we will have >1 parents */
 	while (i < FACTORS_MAX_PARENTS &&
 	while (i < FACTORS_MAX_PARENTS &&
 	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
 	       (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;
 	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
 #endif

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

@@ -17,6 +17,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 
 
 #include "clk-factors.h"
 #include "clk-factors.h"
 
 
@@ -67,7 +68,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = {
 	.pwidth = 2,
 	.pwidth = 2,
 };
 };
 
 
-static const struct factors_data sun4i_a10_mod0_data __initconst = {
+static const struct factors_data sun4i_a10_mod0_data = {
 	.enable = 31,
 	.enable = 31,
 	.mux = 24,
 	.mux = 24,
 	.muxmask = BIT(1) | BIT(0),
 	.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)
 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);
 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 DEFINE_SPINLOCK(sun5i_a13_mbus_lock);
 
 
 static void __init sun5i_a13_mbus_setup(struct device_node *node)
 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 */
 	/* The MBUS clocks needs to be always enabled */
 	__clk_get(mbus);
 	__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);
 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 mmc_phase {
 	struct clk_hw		hw;
 	struct clk_hw		hw;
+	u8			offset;
 	void __iomem		*reg;
 	void __iomem		*reg;
-	struct mmc_phase_data	*data;
 	spinlock_t		*lock;
 	spinlock_t		*lock;
 };
 };
 
 
@@ -118,7 +195,7 @@ static int mmc_get_phase(struct clk_hw *hw)
 	u8 delay;
 	u8 delay;
 
 
 	value = readl(phase->reg);
 	value = readl(phase->reg);
-	delay = (value >> phase->data->offset) & 0x3;
+	delay = (value >> phase->offset) & 0x3;
 
 
 	if (!delay)
 	if (!delay)
 		return 180;
 		return 180;
@@ -206,8 +283,8 @@ static int mmc_set_phase(struct clk_hw *hw, int degrees)
 
 
 	spin_lock_irqsave(phase->lock, flags);
 	spin_lock_irqsave(phase->lock, flags);
 	value = readl(phase->reg);
 	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);
 	writel(value, phase->reg);
 	spin_unlock_irqrestore(phase->lock, flags);
 	spin_unlock_irqrestore(phase->lock, flags);
 
 
@@ -219,66 +296,97 @@ static const struct clk_ops mmc_clk_ops = {
 	.set_phase	= mmc_set_phase,
 	.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;
 		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;
 	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,
 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,
 				 unsigned long *best_parent_rate,
 				 struct clk_hw **best_parent_clk)
 				 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)
 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 */
 	/* The MBUS clocks needs to be always enabled */
 	__clk_get(mbus);
 	__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
  * PLL4 rate is calculated as follows
  * rate = (parent_rate * n >> p) / (m + 1);
  * 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
  * p and m are named div1 and div2 in Allwinner's SDK
  */
  */
 
 
 static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
 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 */
 	/* we were called to round the frequency, we can now return */
-	if (n == NULL)
+	if (n_ret == NULL)
 		return;
 		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 = {
 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)
 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);
 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)
 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 */
 	/* The GT bus clock needs to be always enabled */
 	__clk_get(gt);
 	__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)
 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);
 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)
 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);
 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)
 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);
 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/of_address.h>
 #include <linux/reset-controller.h>
 #include <linux/reset-controller.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/log2.h>
 
 
 #include "clk-factors.h"
 #include "clk-factors.h"
 
 
 static DEFINE_SPINLOCK(clk_lock);
 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 */
 /* Maximum number of parents our clocks have */
 #define SUNXI_MAX_PARENTS	5
 #define SUNXI_MAX_PARENTS	5
 
 
@@ -354,43 +564,6 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
 	*p = calcp;
 	*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
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
  */
@@ -413,6 +586,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
 	.kwidth = 2,
 	.kwidth = 2,
 	.mshift = 0,
 	.mshift = 0,
 	.mwidth = 2,
 	.mwidth = 2,
+	.n_start = 1,
 };
 };
 
 
 static struct clk_factors_config sun8i_a23_pll1_config = {
 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,
 static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
 						   const struct factors_data *data)
 						   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);
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
 
 	clk = clk_register_mux(NULL, clk_name, parents, i,
 	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,
 			       data->shift, SUNXI_MUX_GATE_WIDTH,
 			       0, &clk_lock);
 			       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 = {
 static const char *sun6i_critical_clocks[] __initdata = {
 	"cpu",
 	"cpu",
-	"ahb1_sdram",
 };
 };
 
 
 static void __init sun6i_init_clocks(struct device_node *node)
 static void __init sun6i_init_clocks(struct device_node *node)

+ 3 - 1
drivers/clk/ti/Makefile

@@ -3,8 +3,10 @@ obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o
 					  fixed-factor.o mux.o apll.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.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_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 clk-3xxx-legacy.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clk-common) clk-44xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clk-common) clk-44xx.o
 obj-$(CONFIG_SOC_OMAP5)			+= $(clk-common) clk-54xx.o
 obj-$(CONFIG_SOC_OMAP5)			+= $(clk-common) clk-54xx.o
 obj-$(CONFIG_SOC_DRA7XX)		+= $(clk-common) clk-7xx.o \
 obj-$(CONFIG_SOC_DRA7XX)		+= $(clk-common) clk-7xx.o \

+ 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_ES1,
 	OMAP3_SOC_OMAP3430_ES2_PLUS,
 	OMAP3_SOC_OMAP3430_ES2_PLUS,
 	OMAP3_SOC_OMAP3630,
 	OMAP3_SOC_OMAP3630,
-	OMAP3_SOC_TI81XX,
 };
 };
 
 
 static int __init omap3xxx_dt_clk_init(int soc_type)
 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, "core_ck")) / 1000000),
 		(clk_get_rate(clk_get_sys(NULL, "arm_fck")) / 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();
 		omap3_clk_lock_dpll5();
 
 
 	return 0;
 	return 0;
@@ -390,8 +389,3 @@ int __init am35xx_dt_clk_init(void)
 {
 {
 	return omap3xxx_dt_clk_init(OMAP3_SOC_AM35XX);
 	return omap3xxx_dt_clk_init(OMAP3_SOC_AM35XX);
 }
 }
-
-int __init ti81xx_dt_clk_init(void)
-{
-	return omap3xxx_dt_clk_init(OMAP3_SOC_TI81XX);
-}

+ 1 - 1
drivers/clk/ti/clk-44xx.c

@@ -12,7 +12,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/list.h>
-#include <linux/clk-private.h>
+#include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
 
 

+ 1 - 1
drivers/clk/ti/clk-54xx.c

@@ -12,7 +12,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/list.h>
-#include <linux/clk-private.h>
+#include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>

+ 1 - 1
drivers/clk/ti/clk-7xx.c

@@ -12,7 +12,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/list.h>
-#include <linux/clk-private.h>
+#include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
 
 

+ 53 - 0
drivers/clk/ti/clk-816x.c

@@ -0,0 +1,53 @@
+/*
+ * 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/list.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+
+static struct ti_dt_clk dm816x_clks[] = {
+	DT_CLK(NULL, "sys_clkin", "sys_clkin_ck"),
+	DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
+	DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
+	DT_CLK(NULL, "mpu_ck", "mpu_ck"),
+	DT_CLK(NULL, "timer1_fck", "timer1_fck"),
+	DT_CLK(NULL, "timer2_fck", "timer2_fck"),
+	DT_CLK(NULL, "timer3_fck", "timer3_fck"),
+	DT_CLK(NULL, "timer4_fck", "timer4_fck"),
+	DT_CLK(NULL, "timer5_fck", "timer5_fck"),
+	DT_CLK(NULL, "timer6_fck", "timer6_fck"),
+	DT_CLK(NULL, "timer7_fck", "timer7_fck"),
+	DT_CLK(NULL, "sysclk4_ck", "sysclk4_ck"),
+	DT_CLK(NULL, "sysclk5_ck", "sysclk5_ck"),
+	DT_CLK(NULL, "sysclk6_ck", "sysclk6_ck"),
+	DT_CLK(NULL, "sysclk10_ck", "sysclk10_ck"),
+	DT_CLK(NULL, "sysclk18_ck", "sysclk18_ck"),
+	DT_CLK(NULL, "sysclk24_ck", "sysclk24_ck"),
+	DT_CLK("4a100000.ethernet", "sysclk24_ck", "sysclk24_ck"),
+	{ .node_name = NULL },
+};
+
+static const char *enable_init_clks[] = {
+	"ddr_pll_clk1",
+	"ddr_pll_clk2",
+	"ddr_pll_clk3",
+};
+
+int __init ti81xx_dt_clk_init(void)
+{
+	ti_dt_clocks_register(dm816x_clks);
+	omap2_clk_disable_autoidle_all();
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	return 0;
+}

+ 125 - 0
drivers/clk/ti/clk.c

@@ -22,6 +22,8 @@
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/list.h>
 #include <linux/list.h>
 
 
+#include "clock.h"
+
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 
@@ -183,3 +185,126 @@ void ti_dt_clk_init_retry_clks(void)
 		retries--;
 		retries--;
 	}
 	}
 }
 }
+
+void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
+{
+	while (*patch) {
+		memcpy((*patch)->patch, *patch, sizeof(**patch));
+		patch++;
+	}
+}
+
+struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
+{
+	struct clk *clk;
+	struct ti_clk_fixed *fixed;
+	struct ti_clk_fixed_factor *fixed_factor;
+	struct clk_hw *clk_hw;
+
+	if (setup->clk)
+		return setup->clk;
+
+	switch (setup->type) {
+	case TI_CLK_FIXED:
+		fixed = setup->data;
+
+		clk = clk_register_fixed_rate(NULL, setup->name, NULL,
+					      CLK_IS_ROOT, fixed->frequency);
+		break;
+	case TI_CLK_MUX:
+		clk = ti_clk_register_mux(setup);
+		break;
+	case TI_CLK_DIVIDER:
+		clk = ti_clk_register_divider(setup);
+		break;
+	case TI_CLK_COMPOSITE:
+		clk = ti_clk_register_composite(setup);
+		break;
+	case TI_CLK_FIXED_FACTOR:
+		fixed_factor = setup->data;
+
+		clk = clk_register_fixed_factor(NULL, setup->name,
+						fixed_factor->parent,
+						0, fixed_factor->mult,
+						fixed_factor->div);
+		break;
+	case TI_CLK_GATE:
+		clk = ti_clk_register_gate(setup);
+		break;
+	case TI_CLK_DPLL:
+		clk = ti_clk_register_dpll(setup);
+		break;
+	default:
+		pr_err("bad type for %s!\n", setup->name);
+		clk = ERR_PTR(-EINVAL);
+	}
+
+	if (!IS_ERR(clk)) {
+		setup->clk = clk;
+		if (setup->clkdm_name) {
+			if (__clk_get_flags(clk) & CLK_IS_BASIC) {
+				pr_warn("can't setup clkdm for basic clk %s\n",
+					setup->name);
+			} else {
+				clk_hw = __clk_get_hw(clk);
+				to_clk_hw_omap(clk_hw)->clkdm_name =
+					setup->clkdm_name;
+				omap2_init_clk_clkdm(clk_hw);
+			}
+		}
+	}
+
+	return clk;
+}
+
+int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
+{
+	struct clk *clk;
+	bool retry;
+	struct ti_clk_alias *retry_clk;
+	struct ti_clk_alias *tmp;
+
+	while (clks->clk) {
+		clk = ti_clk_register_clk(clks->clk);
+		if (IS_ERR(clk)) {
+			if (PTR_ERR(clk) == -EAGAIN) {
+				list_add(&clks->link, &retry_list);
+			} else {
+				pr_err("register for %s failed: %ld\n",
+				       clks->clk->name, PTR_ERR(clk));
+				return PTR_ERR(clk);
+			}
+		} else {
+			clks->lk.clk = clk;
+			clkdev_add(&clks->lk);
+		}
+		clks++;
+	}
+
+	retry = true;
+
+	while (!list_empty(&retry_list) && retry) {
+		retry = false;
+		list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) {
+			pr_debug("retry-init: %s\n", retry_clk->clk->name);
+			clk = ti_clk_register_clk(retry_clk->clk);
+			if (IS_ERR(clk)) {
+				if (PTR_ERR(clk) == -EAGAIN) {
+					continue;
+				} else {
+					pr_err("register for %s failed: %ld\n",
+					       retry_clk->clk->name,
+					       PTR_ERR(clk));
+					return PTR_ERR(clk);
+				}
+			} else {
+				retry = true;
+				retry_clk->lk.clk = clk;
+				clkdev_add(&retry_clk->lk);
+				list_del(&retry_clk->link);
+			}
+		}
+	}
+
+	return 0;
+}

+ 172 - 0
drivers/clk/ti/clock.h

@@ -0,0 +1,172 @@
+/*
+ * TI Clock driver internal definitions
+ *
+ * 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.
+ */
+#ifndef __DRIVERS_CLK_TI_CLOCK__
+#define __DRIVERS_CLK_TI_CLOCK__
+
+enum {
+	TI_CLK_FIXED,
+	TI_CLK_MUX,
+	TI_CLK_DIVIDER,
+	TI_CLK_COMPOSITE,
+	TI_CLK_FIXED_FACTOR,
+	TI_CLK_GATE,
+	TI_CLK_DPLL,
+};
+
+/* Global flags */
+#define CLKF_INDEX_POWER_OF_TWO		(1 << 0)
+#define CLKF_INDEX_STARTS_AT_ONE	(1 << 1)
+#define CLKF_SET_RATE_PARENT		(1 << 2)
+#define CLKF_OMAP3			(1 << 3)
+#define CLKF_AM35XX			(1 << 4)
+
+/* Gate flags */
+#define CLKF_SET_BIT_TO_DISABLE		(1 << 5)
+#define CLKF_INTERFACE			(1 << 6)
+#define CLKF_SSI			(1 << 7)
+#define CLKF_DSS			(1 << 8)
+#define CLKF_HSOTGUSB			(1 << 9)
+#define CLKF_WAIT			(1 << 10)
+#define CLKF_NO_WAIT			(1 << 11)
+#define CLKF_HSDIV			(1 << 12)
+#define CLKF_CLKDM			(1 << 13)
+
+/* DPLL flags */
+#define CLKF_LOW_POWER_STOP		(1 << 5)
+#define CLKF_LOCK			(1 << 6)
+#define CLKF_LOW_POWER_BYPASS		(1 << 7)
+#define CLKF_PER			(1 << 8)
+#define CLKF_CORE			(1 << 9)
+#define CLKF_J_TYPE			(1 << 10)
+
+#define CLK(dev, con, ck)		\
+	{				\
+		.lk = {			\
+			.dev_id = dev,	\
+			.con_id = con,	\
+		},			\
+		.clk = ck,		\
+	}
+
+struct ti_clk {
+	const char *name;
+	const char *clkdm_name;
+	int type;
+	void *data;
+	struct ti_clk *patch;
+	struct clk *clk;
+};
+
+struct ti_clk_alias {
+	struct ti_clk *clk;
+	struct clk_lookup lk;
+	struct list_head link;
+};
+
+struct ti_clk_fixed {
+	u32 frequency;
+	u16 flags;
+};
+
+struct ti_clk_mux {
+	u8 bit_shift;
+	int num_parents;
+	u16 reg;
+	u8 module;
+	const char **parents;
+	u16 flags;
+};
+
+struct ti_clk_divider {
+	const char *parent;
+	u8 bit_shift;
+	u16 max_div;
+	u16 reg;
+	u8 module;
+	int *dividers;
+	int num_dividers;
+	u16 flags;
+};
+
+struct ti_clk_fixed_factor {
+	const char *parent;
+	u16 div;
+	u16 mult;
+	u16 flags;
+};
+
+struct ti_clk_gate {
+	const char *parent;
+	u8 bit_shift;
+	u16 reg;
+	u8 module;
+	u16 flags;
+};
+
+struct ti_clk_composite {
+	struct ti_clk_divider *divider;
+	struct ti_clk_mux *mux;
+	struct ti_clk_gate *gate;
+	u16 flags;
+};
+
+struct ti_clk_clkdm_gate {
+	const char *parent;
+	u16 flags;
+};
+
+struct ti_clk_dpll {
+	int num_parents;
+	u16 control_reg;
+	u16 idlest_reg;
+	u16 autoidle_reg;
+	u16 mult_div1_reg;
+	u8 module;
+	const char **parents;
+	u16 flags;
+	u8 modes;
+	u32 mult_mask;
+	u32 div1_mask;
+	u32 enable_mask;
+	u32 autoidle_mask;
+	u32 freqsel_mask;
+	u32 idlest_mask;
+	u32 dco_mask;
+	u32 sddiv_mask;
+	u16 max_multiplier;
+	u16 max_divider;
+	u8 min_divider;
+	u8 auto_recal_bit;
+	u8 recal_en_bit;
+	u8 recal_st_bit;
+};
+
+struct clk *ti_clk_register_gate(struct ti_clk *setup);
+struct clk *ti_clk_register_interface(struct ti_clk *setup);
+struct clk *ti_clk_register_mux(struct ti_clk *setup);
+struct clk *ti_clk_register_divider(struct ti_clk *setup);
+struct clk *ti_clk_register_composite(struct ti_clk *setup);
+struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+
+struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
+struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
+struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup);
+
+void ti_clk_patch_legacy_clks(struct ti_clk **patch);
+struct clk *ti_clk_register_clk(struct ti_clk *setup);
+int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
+
+#endif

+ 42 - 4
drivers/clk/ti/composite.c

@@ -23,6 +23,8 @@
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
 #include <linux/list.h>
 #include <linux/list.h>
 
 
+#include "clock.h"
+
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 
@@ -116,8 +118,44 @@ static inline struct clk_hw *_get_hw(struct clk_hw_omap_comp *clk, int idx)
 
 
 #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw)
 #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw)
 
 
-static void __init ti_clk_register_composite(struct clk_hw *hw,
-					     struct device_node *node)
+struct clk *ti_clk_register_composite(struct ti_clk *setup)
+{
+	struct ti_clk_composite *comp;
+	struct clk_hw *gate;
+	struct clk_hw *mux;
+	struct clk_hw *div;
+	int num_parents = 1;
+	const char **parent_names = NULL;
+	struct clk *clk;
+
+	comp = setup->data;
+
+	div = ti_clk_build_component_div(comp->divider);
+	gate = ti_clk_build_component_gate(comp->gate);
+	mux = ti_clk_build_component_mux(comp->mux);
+
+	if (div)
+		parent_names = &comp->divider->parent;
+
+	if (gate)
+		parent_names = &comp->gate->parent;
+
+	if (mux) {
+		num_parents = comp->mux->num_parents;
+		parent_names = comp->mux->parents;
+	}
+
+	clk = clk_register_composite(NULL, setup->name,
+				     parent_names, num_parents, mux,
+				     &ti_clk_mux_ops, div,
+				     &ti_composite_divider_ops, gate,
+				     &ti_composite_gate_ops, 0);
+
+	return clk;
+}
+
+static void __init _register_composite(struct clk_hw *hw,
+				       struct device_node *node)
 {
 {
 	struct clk *clk;
 	struct clk *clk;
 	struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw);
 	struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw);
@@ -136,7 +174,7 @@ static void __init ti_clk_register_composite(struct clk_hw *hw,
 			pr_debug("component %s not ready for %s, retry\n",
 			pr_debug("component %s not ready for %s, retry\n",
 				 cclk->comp_nodes[i]->name, node->name);
 				 cclk->comp_nodes[i]->name, node->name);
 			if (!ti_clk_retry_init(node, hw,
 			if (!ti_clk_retry_init(node, hw,
-					       ti_clk_register_composite))
+					       _register_composite))
 				return;
 				return;
 
 
 			goto cleanup;
 			goto cleanup;
@@ -216,7 +254,7 @@ static void __init of_ti_composite_clk_setup(struct device_node *node)
 	for (i = 0; i < num_clks; i++)
 	for (i = 0; i < num_clks; i++)
 		cclk->comp_nodes[i] = _get_component_node(node, i);
 		cclk->comp_nodes[i] = _get_component_node(node, i);
 
 
-	ti_clk_register_composite(&cclk->hw, node);
+	_register_composite(&cclk->hw, node);
 }
 }
 CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock",
 CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock",
 	       of_ti_composite_clk_setup);
 	       of_ti_composite_clk_setup);

+ 131 - 1
drivers/clk/ti/divider.c

@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
+#include "clock.h"
 
 
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
@@ -300,6 +301,134 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	return clk;
 	return clk;
 }
 }
 
 
+static struct clk_div_table *
+_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
+{
+	int valid_div = 0;
+	struct clk_div_table *table;
+	int i;
+	int div;
+	u32 val;
+	u8 flags;
+
+	if (!setup->num_dividers) {
+		/* Clk divider table not provided, determine min/max divs */
+		flags = setup->flags;
+
+		if (flags & CLKF_INDEX_STARTS_AT_ONE)
+			val = 1;
+		else
+			val = 0;
+
+		div = 1;
+
+		while (div < setup->max_div) {
+			if (flags & CLKF_INDEX_POWER_OF_TWO)
+				div <<= 1;
+			else
+				div++;
+			val++;
+		}
+
+		*width = fls(val);
+
+		return NULL;
+	}
+
+	for (i = 0; i < setup->num_dividers; i++)
+		if (setup->dividers[i])
+			valid_div++;
+
+	table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL);
+	if (!table)
+		return ERR_PTR(-ENOMEM);
+
+	valid_div = 0;
+	*width = 0;
+
+	for (i = 0; i < setup->num_dividers; i++)
+		if (setup->dividers[i]) {
+			table[valid_div].div = setup->dividers[i];
+			table[valid_div].val = i;
+			valid_div++;
+			*width = i;
+		}
+
+	*width = fls(*width);
+
+	return table;
+}
+
+struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
+{
+	struct clk_divider *div;
+	struct clk_omap_reg *reg;
+
+	if (!setup)
+		return NULL;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	reg = (struct clk_omap_reg *)&div->reg;
+	reg->index = setup->module;
+	reg->offset = setup->reg;
+
+	if (setup->flags & CLKF_INDEX_STARTS_AT_ONE)
+		div->flags |= CLK_DIVIDER_ONE_BASED;
+
+	if (setup->flags & CLKF_INDEX_POWER_OF_TWO)
+		div->flags |= CLK_DIVIDER_POWER_OF_TWO;
+
+	div->table = _get_div_table_from_setup(setup, &div->width);
+
+	div->shift = setup->bit_shift;
+
+	return &div->hw;
+}
+
+struct clk *ti_clk_register_divider(struct ti_clk *setup)
+{
+	struct ti_clk_divider *div;
+	struct clk_omap_reg *reg_setup;
+	u32 reg;
+	u8 width;
+	u32 flags = 0;
+	u8 div_flags = 0;
+	struct clk_div_table *table;
+	struct clk *clk;
+
+	div = setup->data;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	reg_setup->index = div->module;
+	reg_setup->offset = div->reg;
+
+	if (div->flags & CLKF_INDEX_STARTS_AT_ONE)
+		div_flags |= CLK_DIVIDER_ONE_BASED;
+
+	if (div->flags & CLKF_INDEX_POWER_OF_TWO)
+		div_flags |= CLK_DIVIDER_POWER_OF_TWO;
+
+	if (div->flags & CLKF_SET_RATE_PARENT)
+		flags |= CLK_SET_RATE_PARENT;
+
+	table = _get_div_table_from_setup(div, &width);
+	if (IS_ERR(table))
+		return (struct clk *)table;
+
+	clk = _register_divider(NULL, setup->name, div->parent,
+				flags, (void __iomem *)reg, div->bit_shift,
+				width, div_flags, table, NULL);
+
+	if (IS_ERR(clk))
+		kfree(table);
+
+	return clk;
+}
+
 static struct clk_div_table *
 static struct clk_div_table *
 __init ti_clk_get_div_table(struct device_node *node)
 __init ti_clk_get_div_table(struct device_node *node)
 {
 {
@@ -455,7 +584,8 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
 		goto cleanup;
 		goto cleanup;
 
 
 	clk = _register_divider(NULL, node->name, parent_name, flags, reg,
 	clk = _register_divider(NULL, node->name, parent_name, flags, reg,
-				shift, width, clk_divider_flags, table, NULL);
+				shift, width, clk_divider_flags, table,
+				NULL);
 
 
 	if (!IS_ERR(clk)) {
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);

+ 108 - 11
drivers/clk/ti/dpll.c

@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
+#include "clock.h"
 
 
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
@@ -130,7 +131,7 @@ static const struct clk_ops dpll_x2_ck_ops = {
 };
 };
 
 
 /**
 /**
- * ti_clk_register_dpll - low level registration of a DPLL clock
+ * _register_dpll - low level registration of a DPLL clock
  * @hw: hardware clock definition for the clock
  * @hw: hardware clock definition for the clock
  * @node: device node for the clock
  * @node: device node for the clock
  *
  *
@@ -138,8 +139,8 @@ static const struct clk_ops dpll_x2_ck_ops = {
  * clk-bypass is missing), the clock is added to retry list and
  * clk-bypass is missing), the clock is added to retry list and
  * the initialization is retried on later stage.
  * the initialization is retried on later stage.
  */
  */
-static void __init ti_clk_register_dpll(struct clk_hw *hw,
-					struct device_node *node)
+static void __init _register_dpll(struct clk_hw *hw,
+				  struct device_node *node)
 {
 {
 	struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
 	struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
 	struct dpll_data *dd = clk_hw->dpll_data;
 	struct dpll_data *dd = clk_hw->dpll_data;
@@ -151,7 +152,7 @@ static void __init ti_clk_register_dpll(struct clk_hw *hw,
 	if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
 	if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
 		pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
 		pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
 			 node->name);
 			 node->name);
-		if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll))
+		if (!ti_clk_retry_init(node, hw, _register_dpll))
 			return;
 			return;
 
 
 		goto cleanup;
 		goto cleanup;
@@ -175,20 +176,116 @@ cleanup:
 	kfree(clk_hw);
 	kfree(clk_hw);
 }
 }
 
 
+void __iomem *_get_reg(u8 module, u16 offset)
+{
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	reg_setup->index = module;
+	reg_setup->offset = offset;
+
+	return (void __iomem *)reg;
+}
+
+struct clk *ti_clk_register_dpll(struct ti_clk *setup)
+{
+	struct clk_hw_omap *clk_hw;
+	struct clk_init_data init = { NULL };
+	struct dpll_data *dd;
+	struct clk *clk;
+	struct ti_clk_dpll *dpll;
+	const struct clk_ops *ops = &omap3_dpll_ck_ops;
+	struct clk *clk_ref;
+	struct clk *clk_bypass;
+
+	dpll = setup->data;
+
+	if (dpll->num_parents < 2)
+		return ERR_PTR(-EINVAL);
+
+	clk_ref = clk_get_sys(NULL, dpll->parents[0]);
+	clk_bypass = clk_get_sys(NULL, dpll->parents[1]);
+
+	if (IS_ERR_OR_NULL(clk_ref) || IS_ERR_OR_NULL(clk_bypass))
+		return ERR_PTR(-EAGAIN);
+
+	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+	if (!dd || !clk_hw) {
+		clk = ERR_PTR(-ENOMEM);
+		goto cleanup;
+	}
+
+	clk_hw->dpll_data = dd;
+	clk_hw->ops = &clkhwops_omap3_dpll;
+	clk_hw->hw.init = &init;
+	clk_hw->flags = MEMMAP_ADDRESSING;
+
+	init.name = setup->name;
+	init.ops = ops;
+
+	init.num_parents = dpll->num_parents;
+	init.parent_names = dpll->parents;
+
+	dd->control_reg = _get_reg(dpll->module, dpll->control_reg);
+	dd->idlest_reg = _get_reg(dpll->module, dpll->idlest_reg);
+	dd->mult_div1_reg = _get_reg(dpll->module, dpll->mult_div1_reg);
+	dd->autoidle_reg = _get_reg(dpll->module, dpll->autoidle_reg);
+
+	dd->modes = dpll->modes;
+	dd->div1_mask = dpll->div1_mask;
+	dd->idlest_mask = dpll->idlest_mask;
+	dd->mult_mask = dpll->mult_mask;
+	dd->autoidle_mask = dpll->autoidle_mask;
+	dd->enable_mask = dpll->enable_mask;
+	dd->sddiv_mask = dpll->sddiv_mask;
+	dd->dco_mask = dpll->dco_mask;
+	dd->max_divider = dpll->max_divider;
+	dd->min_divider = dpll->min_divider;
+	dd->max_multiplier = dpll->max_multiplier;
+	dd->auto_recal_bit = dpll->auto_recal_bit;
+	dd->recal_en_bit = dpll->recal_en_bit;
+	dd->recal_st_bit = dpll->recal_st_bit;
+
+	dd->clk_ref = clk_ref;
+	dd->clk_bypass = clk_bypass;
+
+	if (dpll->flags & CLKF_CORE)
+		ops = &omap3_dpll_core_ck_ops;
+
+	if (dpll->flags & CLKF_PER)
+		ops = &omap3_dpll_per_ck_ops;
+
+	if (dpll->flags & CLKF_J_TYPE)
+		dd->flags |= DPLL_J_TYPE;
+
+	clk = clk_register(NULL, &clk_hw->hw);
+
+	if (!IS_ERR(clk))
+		return clk;
+
+cleanup:
+	kfree(dd);
+	kfree(clk_hw);
+	return clk;
+}
+
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
 	defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
 	defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
 	defined(CONFIG_SOC_AM43XX)
 	defined(CONFIG_SOC_AM43XX)
 /**
 /**
- * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
+ * _register_dpll_x2 - Registers a DPLLx2 clock
  * @node: device node for this clock
  * @node: device node for this clock
  * @ops: clk_ops for this clock
  * @ops: clk_ops for this clock
  * @hw_ops: clk_hw_ops for this clock
  * @hw_ops: clk_hw_ops for this clock
  *
  *
  * Initializes a DPLL x 2 clock from device tree data.
  * Initializes a DPLL x 2 clock from device tree data.
  */
  */
-static void ti_clk_register_dpll_x2(struct device_node *node,
-				    const struct clk_ops *ops,
-				    const struct clk_hw_omap_ops *hw_ops)
+static void _register_dpll_x2(struct device_node *node,
+			      const struct clk_ops *ops,
+			      const struct clk_hw_omap_ops *hw_ops)
 {
 {
 	struct clk *clk;
 	struct clk *clk;
 	struct clk_init_data init = { NULL };
 	struct clk_init_data init = { NULL };
@@ -318,7 +415,7 @@ static void __init of_ti_dpll_setup(struct device_node *node,
 	if (dpll_mode)
 	if (dpll_mode)
 		dd->modes = dpll_mode;
 		dd->modes = dpll_mode;
 
 
-	ti_clk_register_dpll(&clk_hw->hw, node);
+	_register_dpll(&clk_hw->hw, node);
 	return;
 	return;
 
 
 cleanup:
 cleanup:
@@ -332,7 +429,7 @@ cleanup:
 	defined(CONFIG_SOC_DRA7XX)
 	defined(CONFIG_SOC_DRA7XX)
 static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
 static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
 {
 {
-	ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
+	_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
 }
 }
 CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
 CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
 	       of_ti_omap4_dpll_x2_setup);
 	       of_ti_omap4_dpll_x2_setup);
@@ -341,7 +438,7 @@ CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
 static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
 {
 {
-	ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
+	_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
 }
 }
 CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
 CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
 	       of_ti_am3_dpll_x2_setup);
 	       of_ti_am3_dpll_x2_setup);

+ 410 - 0
drivers/clk/ti/fapll.c

@@ -0,0 +1,410 @@
+/*
+ * 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/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk/ti.h>
+#include <asm/div64.h>
+
+/* FAPLL Control Register PLL_CTRL */
+#define FAPLL_MAIN_LOCK		BIT(7)
+#define FAPLL_MAIN_PLLEN	BIT(3)
+#define FAPLL_MAIN_BP		BIT(2)
+#define FAPLL_MAIN_LOC_CTL	BIT(0)
+
+/* FAPLL powerdown register PWD */
+#define FAPLL_PWD_OFFSET	4
+
+#define MAX_FAPLL_OUTPUTS	7
+#define FAPLL_MAX_RETRIES	1000
+
+#define to_fapll(_hw)		container_of(_hw, struct fapll_data, hw)
+#define to_synth(_hw)		container_of(_hw, struct fapll_synth, hw)
+
+/* The bypass bit is inverted on the ddr_pll.. */
+#define fapll_is_ddr_pll(va)	(((u32)(va) & 0xffff) == 0x0440)
+
+/*
+ * The audio_pll_clk1 input is hard wired to the 27MHz bypass clock,
+ * and the audio_pll_clk1 synthesizer is hardwared to 32KiHz output.
+ */
+#define is_ddr_pll_clk1(va)	(((u32)(va) & 0xffff) == 0x044c)
+#define is_audio_pll_clk1(va)	(((u32)(va) & 0xffff) == 0x04a8)
+
+/* Synthesizer divider register */
+#define SYNTH_LDMDIV1		BIT(8)
+
+/* Synthesizer frequency register */
+#define SYNTH_LDFREQ		BIT(31)
+
+struct fapll_data {
+	struct clk_hw hw;
+	void __iomem *base;
+	const char *name;
+	struct clk *clk_ref;
+	struct clk *clk_bypass;
+	struct clk_onecell_data outputs;
+	bool bypass_bit_inverted;
+};
+
+struct fapll_synth {
+	struct clk_hw hw;
+	struct fapll_data *fd;
+	int index;
+	void __iomem *freq;
+	void __iomem *div;
+	const char *name;
+	struct clk *clk_pll;
+};
+
+static bool ti_fapll_clock_is_bypass(struct fapll_data *fd)
+{
+	u32 v = readl_relaxed(fd->base);
+
+	if (fd->bypass_bit_inverted)
+		return !(v & FAPLL_MAIN_BP);
+	else
+		return !!(v & FAPLL_MAIN_BP);
+}
+
+static int ti_fapll_enable(struct clk_hw *hw)
+{
+	struct fapll_data *fd = to_fapll(hw);
+	u32 v = readl_relaxed(fd->base);
+
+	v |= (1 << FAPLL_MAIN_PLLEN);
+	writel_relaxed(v, fd->base);
+
+	return 0;
+}
+
+static void ti_fapll_disable(struct clk_hw *hw)
+{
+	struct fapll_data *fd = to_fapll(hw);
+	u32 v = readl_relaxed(fd->base);
+
+	v &= ~(1 << FAPLL_MAIN_PLLEN);
+	writel_relaxed(v, fd->base);
+}
+
+static int ti_fapll_is_enabled(struct clk_hw *hw)
+{
+	struct fapll_data *fd = to_fapll(hw);
+	u32 v = readl_relaxed(fd->base);
+
+	return v & (1 << FAPLL_MAIN_PLLEN);
+}
+
+static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct fapll_data *fd = to_fapll(hw);
+	u32 fapll_n, fapll_p, v;
+	long long rate;
+
+	if (ti_fapll_clock_is_bypass(fd))
+		return parent_rate;
+
+	rate = parent_rate;
+
+	/* PLL pre-divider is P and multiplier is N */
+	v = readl_relaxed(fd->base);
+	fapll_p = (v >> 8) & 0xff;
+	if (fapll_p)
+		do_div(rate, fapll_p);
+	fapll_n = v >> 16;
+	if (fapll_n)
+		rate *= fapll_n;
+
+	return rate;
+}
+
+static u8 ti_fapll_get_parent(struct clk_hw *hw)
+{
+	struct fapll_data *fd = to_fapll(hw);
+
+	if (ti_fapll_clock_is_bypass(fd))
+		return 1;
+
+	return 0;
+}
+
+static struct clk_ops ti_fapll_ops = {
+	.enable = ti_fapll_enable,
+	.disable = ti_fapll_disable,
+	.is_enabled = ti_fapll_is_enabled,
+	.recalc_rate = ti_fapll_recalc_rate,
+	.get_parent = ti_fapll_get_parent,
+};
+
+static int ti_fapll_synth_enable(struct clk_hw *hw)
+{
+	struct fapll_synth *synth = to_synth(hw);
+	u32 v = readl_relaxed(synth->fd->base + FAPLL_PWD_OFFSET);
+
+	v &= ~(1 << synth->index);
+	writel_relaxed(v, synth->fd->base + FAPLL_PWD_OFFSET);
+
+	return 0;
+}
+
+static void ti_fapll_synth_disable(struct clk_hw *hw)
+{
+	struct fapll_synth *synth = to_synth(hw);
+	u32 v = readl_relaxed(synth->fd->base + FAPLL_PWD_OFFSET);
+
+	v |= 1 << synth->index;
+	writel_relaxed(v, synth->fd->base + FAPLL_PWD_OFFSET);
+}
+
+static int ti_fapll_synth_is_enabled(struct clk_hw *hw)
+{
+	struct fapll_synth *synth = to_synth(hw);
+	u32 v = readl_relaxed(synth->fd->base + FAPLL_PWD_OFFSET);
+
+	return !(v & (1 << synth->index));
+}
+
+/*
+ * See dm816x TRM chapter 1.10.3 Flying Adder PLL fore more info
+ */
+static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct fapll_synth *synth = to_synth(hw);
+	u32 synth_div_m;
+	long long rate;
+
+	/* The audio_pll_clk1 is hardwired to produce 32.768KiHz clock */
+	if (!synth->div)
+		return 32768;
+
+	/*
+	 * PLL in bypass sets the synths in bypass mode too. The PLL rate
+	 * can be also be set to 27MHz, so we can't use parent_rate to
+	 * check for bypass mode.
+	 */
+	if (ti_fapll_clock_is_bypass(synth->fd))
+		return parent_rate;
+
+	rate = parent_rate;
+
+	/*
+	 * Synth frequency integer and fractional divider.
+	 * Note that the phase output K is 8, so the result needs
+	 * to be multiplied by 8.
+	 */
+	if (synth->freq) {
+		u32 v, synth_int_div, synth_frac_div, synth_div_freq;
+
+		v = readl_relaxed(synth->freq);
+		synth_int_div = (v >> 24) & 0xf;
+		synth_frac_div = v & 0xffffff;
+		synth_div_freq = (synth_int_div * 10000000) + synth_frac_div;
+		rate *= 10000000;
+		do_div(rate, synth_div_freq);
+		rate *= 8;
+	}
+
+	/* Synth ost-divider M */
+	synth_div_m = readl_relaxed(synth->div) & 0xff;
+	do_div(rate, synth_div_m);
+
+	return rate;
+}
+
+static struct clk_ops ti_fapll_synt_ops = {
+	.enable = ti_fapll_synth_enable,
+	.disable = ti_fapll_synth_disable,
+	.is_enabled = ti_fapll_synth_is_enabled,
+	.recalc_rate = ti_fapll_synth_recalc_rate,
+};
+
+static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd,
+						void __iomem *freq,
+						void __iomem *div,
+						int index,
+						const char *name,
+						const char *parent,
+						struct clk *pll_clk)
+{
+	struct clk_init_data *init;
+	struct fapll_synth *synth;
+
+	init = kzalloc(sizeof(*init), GFP_KERNEL);
+	if (!init)
+		return ERR_PTR(-ENOMEM);
+
+	init->ops = &ti_fapll_synt_ops;
+	init->name = name;
+	init->parent_names = &parent;
+	init->num_parents = 1;
+
+	synth = kzalloc(sizeof(*synth), GFP_KERNEL);
+	if (!synth)
+		goto free;
+
+	synth->fd = fd;
+	synth->index = index;
+	synth->freq = freq;
+	synth->div = div;
+	synth->name = name;
+	synth->hw.init = init;
+	synth->clk_pll = pll_clk;
+
+	return clk_register(NULL, &synth->hw);
+
+free:
+	kfree(synth);
+	kfree(init);
+
+	return ERR_PTR(-ENOMEM);
+}
+
+static void __init ti_fapll_setup(struct device_node *node)
+{
+	struct fapll_data *fd;
+	struct clk_init_data *init = NULL;
+	const char *parent_name[2];
+	struct clk *pll_clk;
+	int i;
+
+	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+	if (!fd)
+		return;
+
+	fd->outputs.clks = kzalloc(sizeof(struct clk *) *
+				   MAX_FAPLL_OUTPUTS + 1,
+				   GFP_KERNEL);
+	if (!fd->outputs.clks)
+		goto free;
+
+	init = kzalloc(sizeof(*init), GFP_KERNEL);
+	if (!init)
+		goto free;
+
+	init->ops = &ti_fapll_ops;
+	init->name = node->name;
+
+	init->num_parents = of_clk_get_parent_count(node);
+	if (init->num_parents != 2) {
+		pr_err("%s must have two parents\n", node->name);
+		goto free;
+	}
+
+	parent_name[0] = of_clk_get_parent_name(node, 0);
+	parent_name[1] = of_clk_get_parent_name(node, 1);
+	init->parent_names = parent_name;
+
+	fd->clk_ref = of_clk_get(node, 0);
+	if (IS_ERR(fd->clk_ref)) {
+		pr_err("%s could not get clk_ref\n", node->name);
+		goto free;
+	}
+
+	fd->clk_bypass = of_clk_get(node, 1);
+	if (IS_ERR(fd->clk_bypass)) {
+		pr_err("%s could not get clk_bypass\n", node->name);
+		goto free;
+	}
+
+	fd->base = of_iomap(node, 0);
+	if (!fd->base) {
+		pr_err("%s could not get IO base\n", node->name);
+		goto free;
+	}
+
+	if (fapll_is_ddr_pll(fd->base))
+		fd->bypass_bit_inverted = true;
+
+	fd->name = node->name;
+	fd->hw.init = init;
+
+	/* Register the parent PLL */
+	pll_clk = clk_register(NULL, &fd->hw);
+	if (IS_ERR(pll_clk))
+		goto unmap;
+
+	fd->outputs.clks[0] = pll_clk;
+	fd->outputs.clk_num++;
+
+	/*
+	 * Set up the child synthesizers starting at index 1 as the
+	 * PLL output is at index 0. We need to check the clock-indices
+	 * for numbering in case there are holes in the synth mapping,
+	 * and then probe the synth register to see if it has a FREQ
+	 * register available.
+	 */
+	for (i = 0; i < MAX_FAPLL_OUTPUTS; i++) {
+		const char *output_name;
+		void __iomem *freq, *div;
+		struct clk *synth_clk;
+		int output_instance;
+		u32 v;
+
+		if (of_property_read_string_index(node, "clock-output-names",
+						  i, &output_name))
+			continue;
+
+		if (of_property_read_u32_index(node, "clock-indices", i,
+					       &output_instance))
+			output_instance = i;
+
+		freq = fd->base + (output_instance * 8);
+		div = freq + 4;
+
+		/* Check for hardwired audio_pll_clk1 */
+		if (is_audio_pll_clk1(freq)) {
+			freq = 0;
+			div = 0;
+		} else {
+			/* Does the synthesizer have a FREQ register? */
+			v = readl_relaxed(freq);
+			if (!v)
+				freq = 0;
+		}
+		synth_clk = ti_fapll_synth_setup(fd, freq, div, output_instance,
+						 output_name, node->name,
+						 pll_clk);
+		if (IS_ERR(synth_clk))
+			continue;
+
+		fd->outputs.clks[output_instance] = synth_clk;
+		fd->outputs.clk_num++;
+
+		clk_register_clkdev(synth_clk, output_name, NULL);
+	}
+
+	/* Register the child synthesizers as the FAPLL outputs */
+	of_clk_add_provider(node, of_clk_src_onecell_get, &fd->outputs);
+	/* Add clock alias for the outputs */
+
+	kfree(init);
+
+	return;
+
+unmap:
+	iounmap(fd->base);
+free:
+	if (fd->clk_bypass)
+		clk_put(fd->clk_bypass);
+	if (fd->clk_ref)
+		clk_put(fd->clk_ref);
+	kfree(fd->outputs.clks);
+	kfree(fd);
+	kfree(init);
+}
+
+CLK_OF_DECLARE(ti_fapll_clock, "ti,dm816-fapll-clock", ti_fapll_setup);

+ 131 - 30
drivers/clk/ti/gate.c

@@ -22,6 +22,8 @@
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
 
 
+#include "clock.h"
+
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 
 
 #undef pr_fmt
 #undef pr_fmt
@@ -90,63 +92,162 @@ static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
 	return ret;
 	return ret;
 }
 }
 
 
-static void __init _of_ti_gate_clk_setup(struct device_node *node,
-					 const struct clk_ops *ops,
-					 const struct clk_hw_omap_ops *hw_ops)
+static struct clk *_register_gate(struct device *dev, const char *name,
+				  const char *parent_name, unsigned long flags,
+				  void __iomem *reg, u8 bit_idx,
+				  u8 clk_gate_flags, const struct clk_ops *ops,
+				  const struct clk_hw_omap_ops *hw_ops)
 {
 {
-	struct clk *clk;
 	struct clk_init_data init = { NULL };
 	struct clk_init_data init = { NULL };
 	struct clk_hw_omap *clk_hw;
 	struct clk_hw_omap *clk_hw;
-	const char *clk_name = node->name;
-	const char *parent_name;
-	u32 val;
+	struct clk *clk;
 
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw)
 	if (!clk_hw)
-		return;
+		return ERR_PTR(-ENOMEM);
 
 
 	clk_hw->hw.init = &init;
 	clk_hw->hw.init = &init;
 
 
-	init.name = clk_name;
+	init.name = name;
 	init.ops = ops;
 	init.ops = ops;
 
 
-	if (ops != &omap_gate_clkdm_clk_ops) {
-		clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0);
-		if (!clk_hw->enable_reg)
-			goto cleanup;
+	clk_hw->enable_reg = reg;
+	clk_hw->enable_bit = bit_idx;
+	clk_hw->ops = hw_ops;
 
 
-		if (!of_property_read_u32(node, "ti,bit-shift", &val))
-			clk_hw->enable_bit = val;
+	clk_hw->flags = MEMMAP_ADDRESSING | clk_gate_flags;
+
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	init.flags = flags;
+
+	clk = clk_register(NULL, &clk_hw->hw);
+
+	if (IS_ERR(clk))
+		kfree(clk_hw);
+
+	return clk;
+}
+
+struct clk *ti_clk_register_gate(struct ti_clk *setup)
+{
+	const struct clk_ops *ops = &omap_gate_clk_ops;
+	const struct clk_hw_omap_ops *hw_ops = NULL;
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	u32 flags = 0;
+	u8 clk_gate_flags = 0;
+	struct ti_clk_gate *gate;
+
+	gate = setup->data;
+
+	if (gate->flags & CLKF_INTERFACE)
+		return ti_clk_register_interface(setup);
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	if (gate->flags & CLKF_SET_RATE_PARENT)
+		flags |= CLK_SET_RATE_PARENT;
+
+	if (gate->flags & CLKF_SET_BIT_TO_DISABLE)
+		clk_gate_flags |= INVERT_ENABLE;
+
+	if (gate->flags & CLKF_HSDIV) {
+		ops = &omap_gate_clk_hsdiv_restore_ops;
+		hw_ops = &clkhwops_wait;
 	}
 	}
 
 
-	clk_hw->ops = hw_ops;
+	if (gate->flags & CLKF_DSS)
+		hw_ops = &clkhwops_omap3430es2_dss_usbhost_wait;
+
+	if (gate->flags & CLKF_WAIT)
+		hw_ops = &clkhwops_wait;
+
+	if (gate->flags & CLKF_CLKDM)
+		ops = &omap_gate_clkdm_clk_ops;
+
+	if (gate->flags & CLKF_AM35XX)
+		hw_ops = &clkhwops_am35xx_ipss_module_wait;
+
+	reg_setup->index = gate->module;
+	reg_setup->offset = gate->reg;
+
+	return _register_gate(NULL, setup->name, gate->parent, flags,
+			      (void __iomem *)reg, gate->bit_shift,
+			      clk_gate_flags, ops, hw_ops);
+}
 
 
-	clk_hw->flags = MEMMAP_ADDRESSING;
+struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup)
+{
+	struct clk_hw_omap *gate;
+	struct clk_omap_reg *reg;
+	const struct clk_hw_omap_ops *ops = &clkhwops_wait;
+
+	if (!setup)
+		return NULL;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	reg = (struct clk_omap_reg *)&gate->enable_reg;
+	reg->index = setup->module;
+	reg->offset = setup->reg;
+
+	gate->enable_bit = setup->bit_shift;
+
+	if (setup->flags & CLKF_NO_WAIT)
+		ops = NULL;
+
+	if (setup->flags & CLKF_INTERFACE)
+		ops = &clkhwops_iclk_wait;
+
+	gate->ops = ops;
+	gate->flags = MEMMAP_ADDRESSING;
+
+	return &gate->hw;
+}
+
+static void __init _of_ti_gate_clk_setup(struct device_node *node,
+					 const struct clk_ops *ops,
+					 const struct clk_hw_omap_ops *hw_ops)
+{
+	struct clk *clk;
+	const char *parent_name;
+	void __iomem *reg = NULL;
+	u8 enable_bit = 0;
+	u32 val;
+	u32 flags = 0;
+	u8 clk_gate_flags = 0;
+
+	if (ops != &omap_gate_clkdm_clk_ops) {
+		reg = ti_clk_get_reg_addr(node, 0);
+		if (!reg)
+			return;
+
+		if (!of_property_read_u32(node, "ti,bit-shift", &val))
+			enable_bit = val;
+	}
 
 
 	if (of_clk_get_parent_count(node) != 1) {
 	if (of_clk_get_parent_count(node) != 1) {
-		pr_err("%s must have 1 parent\n", clk_name);
-		goto cleanup;
+		pr_err("%s must have 1 parent\n", node->name);
+		return;
 	}
 	}
 
 
 	parent_name = of_clk_get_parent_name(node, 0);
 	parent_name = of_clk_get_parent_name(node, 0);
-	init.parent_names = &parent_name;
-	init.num_parents = 1;
 
 
 	if (of_property_read_bool(node, "ti,set-rate-parent"))
 	if (of_property_read_bool(node, "ti,set-rate-parent"))
-		init.flags |= CLK_SET_RATE_PARENT;
+		flags |= CLK_SET_RATE_PARENT;
 
 
 	if (of_property_read_bool(node, "ti,set-bit-to-disable"))
 	if (of_property_read_bool(node, "ti,set-bit-to-disable"))
-		clk_hw->flags |= INVERT_ENABLE;
+		clk_gate_flags |= INVERT_ENABLE;
 
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = _register_gate(NULL, node->name, parent_name, flags, reg,
+			     enable_bit, clk_gate_flags, ops, hw_ops);
 
 
-	if (!IS_ERR(clk)) {
+	if (!IS_ERR(clk))
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
-		return;
-	}
-
-cleanup:
-	kfree(clk_hw);
 }
 }
 
 
 static void __init
 static void __init

+ 72 - 24
drivers/clk/ti/interface.c

@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
+#include "clock.h"
 
 
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
@@ -31,53 +32,100 @@ static const struct clk_ops ti_interface_clk_ops = {
 	.is_enabled	= &omap2_dflt_clk_is_enabled,
 	.is_enabled	= &omap2_dflt_clk_is_enabled,
 };
 };
 
 
-static void __init _of_ti_interface_clk_setup(struct device_node *node,
-					      const struct clk_hw_omap_ops *ops)
+static struct clk *_register_interface(struct device *dev, const char *name,
+				       const char *parent_name,
+				       void __iomem *reg, u8 bit_idx,
+				       const struct clk_hw_omap_ops *ops)
 {
 {
-	struct clk *clk;
 	struct clk_init_data init = { NULL };
 	struct clk_init_data init = { NULL };
 	struct clk_hw_omap *clk_hw;
 	struct clk_hw_omap *clk_hw;
-	const char *parent_name;
-	u32 val;
+	struct clk *clk;
 
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw)
 	if (!clk_hw)
-		return;
+		return ERR_PTR(-ENOMEM);
 
 
 	clk_hw->hw.init = &init;
 	clk_hw->hw.init = &init;
 	clk_hw->ops = ops;
 	clk_hw->ops = ops;
 	clk_hw->flags = MEMMAP_ADDRESSING;
 	clk_hw->flags = MEMMAP_ADDRESSING;
+	clk_hw->enable_reg = reg;
+	clk_hw->enable_bit = bit_idx;
 
 
-	clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0);
-	if (!clk_hw->enable_reg)
-		goto cleanup;
-
-	if (!of_property_read_u32(node, "ti,bit-shift", &val))
-		clk_hw->enable_bit = val;
-
-	init.name = node->name;
+	init.name = name;
 	init.ops = &ti_interface_clk_ops;
 	init.ops = &ti_interface_clk_ops;
 	init.flags = 0;
 	init.flags = 0;
 
 
-	parent_name = of_clk_get_parent_name(node, 0);
-	if (!parent_name) {
-		pr_err("%s must have a parent\n", node->name);
-		goto cleanup;
-	}
-
 	init.num_parents = 1;
 	init.num_parents = 1;
 	init.parent_names = &parent_name;
 	init.parent_names = &parent_name;
 
 
 	clk = clk_register(NULL, &clk_hw->hw);
 	clk = clk_register(NULL, &clk_hw->hw);
 
 
-	if (!IS_ERR(clk)) {
-		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	if (IS_ERR(clk))
+		kfree(clk_hw);
+	else
 		omap2_init_clk_hw_omap_clocks(clk);
 		omap2_init_clk_hw_omap_clocks(clk);
+
+	return clk;
+}
+
+struct clk *ti_clk_register_interface(struct ti_clk *setup)
+{
+	const struct clk_hw_omap_ops *ops = &clkhwops_iclk_wait;
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	struct ti_clk_gate *gate;
+
+	gate = setup->data;
+	reg_setup = (struct clk_omap_reg *)&reg;
+	reg_setup->index = gate->module;
+	reg_setup->offset = gate->reg;
+
+	if (gate->flags & CLKF_NO_WAIT)
+		ops = &clkhwops_iclk;
+
+	if (gate->flags & CLKF_HSOTGUSB)
+		ops = &clkhwops_omap3430es2_iclk_hsotgusb_wait;
+
+	if (gate->flags & CLKF_DSS)
+		ops = &clkhwops_omap3430es2_iclk_dss_usbhost_wait;
+
+	if (gate->flags & CLKF_SSI)
+		ops = &clkhwops_omap3430es2_iclk_ssi_wait;
+
+	if (gate->flags & CLKF_AM35XX)
+		ops = &clkhwops_am35xx_ipss_wait;
+
+	return _register_interface(NULL, setup->name, gate->parent,
+				   (void __iomem *)reg, gate->bit_shift, ops);
+}
+
+static void __init _of_ti_interface_clk_setup(struct device_node *node,
+					      const struct clk_hw_omap_ops *ops)
+{
+	struct clk *clk;
+	const char *parent_name;
+	void __iomem *reg;
+	u8 enable_bit = 0;
+	u32 val;
+
+	reg = ti_clk_get_reg_addr(node, 0);
+	if (!reg)
+		return;
+
+	if (!of_property_read_u32(node, "ti,bit-shift", &val))
+		enable_bit = val;
+
+	parent_name = of_clk_get_parent_name(node, 0);
+	if (!parent_name) {
+		pr_err("%s must have a parent\n", node->name);
 		return;
 		return;
 	}
 	}
 
 
-cleanup:
-	kfree(clk_hw);
+	clk = _register_interface(NULL, node->name, parent_name, reg,
+				  enable_bit, ops);
+
+	if (!IS_ERR(clk))
+		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 }
 }
 
 
 static void __init of_ti_interface_clk_setup(struct device_node *node)
 static void __init of_ti_interface_clk_setup(struct device_node *node)

+ 68 - 2
drivers/clk/ti/mux.c

@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/clk/ti.h>
 #include <linux/clk/ti.h>
+#include "clock.h"
 
 
 #undef pr_fmt
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
@@ -144,6 +145,39 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 	return clk;
 	return clk;
 }
 }
 
 
+struct clk *ti_clk_register_mux(struct ti_clk *setup)
+{
+	struct ti_clk_mux *mux;
+	u32 flags;
+	u8 mux_flags = 0;
+	struct clk_omap_reg *reg_setup;
+	u32 reg;
+	u32 mask;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	mux = setup->data;
+	flags = CLK_SET_RATE_NO_REPARENT;
+
+	mask = mux->num_parents;
+	if (!(mux->flags & CLKF_INDEX_STARTS_AT_ONE))
+		mask--;
+
+	mask = (1 << fls(mask)) - 1;
+	reg_setup->index = mux->module;
+	reg_setup->offset = mux->reg;
+
+	if (mux->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux_flags |= CLK_MUX_INDEX_ONE;
+
+	if (mux->flags & CLKF_SET_RATE_PARENT)
+		flags |= CLK_SET_RATE_PARENT;
+
+	return _register_mux(NULL, setup->name, mux->parents, mux->num_parents,
+			     flags, (void __iomem *)reg, mux->bit_shift, mask,
+			     mux_flags, NULL, NULL);
+}
+
 /**
 /**
  * of_mux_clk_setup - Setup function for simple mux rate clock
  * of_mux_clk_setup - Setup function for simple mux rate clock
  * @node: DT node for the clock
  * @node: DT node for the clock
@@ -194,8 +228,9 @@ static void of_mux_clk_setup(struct device_node *node)
 
 
 	mask = (1 << fls(mask)) - 1;
 	mask = (1 << fls(mask)) - 1;
 
 
-	clk = _register_mux(NULL, node->name, parent_names, num_parents, flags,
-			    reg, shift, mask, clk_mux_flags, NULL, NULL);
+	clk = _register_mux(NULL, node->name, parent_names, num_parents,
+			    flags, reg, shift, mask, clk_mux_flags, NULL,
+			    NULL);
 
 
 	if (!IS_ERR(clk))
 	if (!IS_ERR(clk))
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
@@ -205,6 +240,37 @@ cleanup:
 }
 }
 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup);
 CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup);
 
 
+struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup)
+{
+	struct clk_mux *mux;
+	struct clk_omap_reg *reg;
+	int num_parents;
+
+	if (!setup)
+		return NULL;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	reg = (struct clk_omap_reg *)&mux->reg;
+
+	mux->shift = setup->bit_shift;
+
+	reg->index = setup->module;
+	reg->offset = setup->reg;
+
+	if (setup->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux->flags |= CLK_MUX_INDEX_ONE;
+
+	num_parents = setup->num_parents;
+
+	mux->mask = num_parents - 1;
+	mux->mask = (1 << fls(mux->mask)) - 1;
+
+	return &mux->hw;
+}
+
 static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
 static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
 {
 {
 	struct clk_mux *mux;
 	struct clk_mux *mux;

+ 0 - 1
drivers/clk/ux500/clk-prcc.c

@@ -8,7 +8,6 @@
  */
  */
 
 
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
-#include <linux/clk-private.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/err.h>

Some files were not shown because too many files changed in this diff