summaryrefslogtreecommitdiff
path: root/target/linux/sunxi
diff options
context:
space:
mode:
authorwigyori <wigyori@3c298f89-4303-0410-b956-a3cf2f4a3e73>2014-01-04 09:47:50 +0000
committerwigyori <wigyori@3c298f89-4303-0410-b956-a3cf2f4a3e73>2014-01-04 09:47:50 +0000
commit24f866e1f93b3e77021edd4fc1ec313353f2b735 (patch)
treef9c170557d310d8bb94364a6fd24eabcd178a77d /target/linux/sunxi
parent13b222d757237eb7772eb7cf8433306ffd6b8ccd (diff)
sunxi: refresh clock framework
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39186 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/sunxi')
-rw-r--r--target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch (renamed from target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch)0
-rw-r--r--target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch33
-rw-r--r--target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch31
-rw-r--r--target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch136
-rw-r--r--target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch198
-rw-r--r--target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch135
-rw-r--r--target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch11
-rw-r--r--target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch149
-rw-r--r--target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch74
-rw-r--r--target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch73
-rw-r--r--target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch63
-rw-r--r--target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch118
-rw-r--r--target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch102
-rw-r--r--target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch69
-rw-r--r--target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch108
-rw-r--r--target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch67
16 files changed, 1367 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch b/target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch
index c949eeb69f..c949eeb69f 100644
--- a/target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch
+++ b/target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch
diff --git a/target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch b/target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch
new file mode 100644
index 0000000000..4dba064375
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch
@@ -0,0 +1,33 @@
+From 04609953e11377c0705b0aba5c25ebdcbb9e4aa7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:47:20 -0300
+Subject: [PATCH] clk: sunxi: factors: fix off-by-one masks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The previous code would generate one bit too long masks, and was
+needlessly complicated. This patch replaces it by simpler code that can
+generate the masks correctly.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 88523f9..5687ac9 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -40,7 +40,7 @@ struct clk_factors {
+
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+-#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
++#define SETMASK(len, pos) (((1U << (len)) - 1) << (pos))
+ #define CLRMASK(len, pos) (~(SETMASK(len, pos)))
+ #define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
+
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch b/target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch
new file mode 100644
index 0000000000..a1323ea02d
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch
@@ -0,0 +1,31 @@
+From 29aef2f23ca8c91bce0a356fd5f120404389125a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:50:46 -0300
+Subject: [PATCH] clk: sunxi: factors: clear variables before using them
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Random bits may get into our factors if we don't clear n, k, m and p.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 5687ac9..f05207a 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -88,7 +88,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+- u8 n, k, m, p;
++ u8 n = 0, k = 0, m = 0, p = 0;
+ u32 reg;
+ struct clk_factors *factors = to_clk_factors(hw);
+ struct clk_factors_config *config = factors->config;
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch
new file mode 100644
index 0000000000..fbd30c65e7
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch
@@ -0,0 +1,136 @@
+From 8cf7164b32f2ce228b0c8116fd712484f67c65b5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Wed, 4 Sep 2013 21:28:49 -0300
+Subject: [PATCH] ARM: sun7i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks available on A20 to its device
+tree. This list was created by looking at AW's code release.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 0af287e..0596e82 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -174,6 +174,111 @@
+ "apb1_uart2", "apb1_uart3", "apb1_uart4",
+ "apb1_uart5", "apb1_uart6", "apb1_uart7";
+ };
++
++ nand: nand@01c20080 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20080 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ms: ms@01c20084 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20084 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc0: mmc0@01c20088 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20088 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc1: mmc1@01c2008c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2008c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc2: mmc2@01c20090 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20090 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc3: mmc3@01c20094 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20094 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ts: ts@01c20098 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20098 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ss: ss@01c2009c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2009c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi0: spi0@01c200a0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi1: spi1@01c200a4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi2: spi2@01c200a8 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a8 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ pata: pata@01c200ac {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200ac 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir0: ir0@01c200b0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir1: ir1@01c200b4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi3: spi3@01c200d4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200d4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
+ };
+
+ soc@01c00000 {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch
new file mode 100644
index 0000000000..63fbdd1c70
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch
@@ -0,0 +1,198 @@
+From 0ae543fe8ae8b9ea7166c39b00e977506eccdf4b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Wed, 4 Sep 2013 21:21:16 -0300
+Subject: [PATCH] ARM: sun5i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks available on A10 and A13. The list
+has been constructed by looking at the Allwinner code release for A10S
+and A13.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 77 +++++++++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/sun5i-a13.dtsi | 77 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 154 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 86e06e4..82b5ce6 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -173,6 +173,83 @@
+ "apb1_i2c2", "apb1_uart0", "apb1_uart1",
+ "apb1_uart2", "apb1_uart3";
+ };
++
++ nand: nand@01c20080 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20080 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ms: ms@01c20084 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20084 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc0: mmc0@01c20088 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20088 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc1: mmc1@01c2008c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2008c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc2: mmc2@01c20090 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20090 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ts: ts@01c20098 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20098 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ss: ss@01c2009c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2009c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi0: spi0@01c200a0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi1: spi1@01c200a4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi2: spi2@01c200a8 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a8 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir0: ir0@01c200b0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
+ };
+
+ soc@01c00000 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index cded3c7..938e6d3 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -170,6 +170,83 @@
+ clock-output-names = "apb1_i2c0", "apb1_i2c1",
+ "apb1_i2c2", "apb1_uart1", "apb1_uart3";
+ };
++
++ nand: nand@01c20080 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20080 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ms: ms@01c20084 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20084 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc0: mmc0@01c20088 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20088 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc1: mmc1@01c2008c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2008c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc2: mmc2@01c20090 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20090 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ts: ts@01c20098 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20098 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ss: ss@01c2009c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2009c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi0: spi0@01c200a0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi1: spi1@01c200a4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi2: spi2@01c200a8 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a8 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir0: ir0@01c200b0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
+ };
+
+ soc@01c00000 {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch
new file mode 100644
index 0000000000..d72335bbad
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch
@@ -0,0 +1,135 @@
+From 5f554ea6757748c2fc45228030a20e08f6053ff7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Tue, 21 May 2013 21:28:32 -0300
+Subject: [PATCH] ARM: sun4i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks present on sun4i to its device tree
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index ebacb5d..2828427e 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -184,6 +184,111 @@
+ "apb1_uart4", "apb1_uart5", "apb1_uart6",
+ "apb1_uart7";
+ };
++
++ nand: nand@01c20080 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20080 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ms: ms@01c20084 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20084 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc0: mmc0@01c20088 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20088 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc1: mmc1@01c2008c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2008c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc2: mmc2@01c20090 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20090 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ mmc3: mmc3@01c20094 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20094 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ts: ts@01c20098 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c20098 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ss: ss@01c2009c {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c2009c 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi0: spi0@01c200a0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi1: spi1@01c200a4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi2: spi2@01c200a8 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200a8 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ pata: pata@01c200ac {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200ac 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir0: ir0@01c200b0 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b0 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ ir1: ir1@01c200b4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200b4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
++
++ spi3: spi3@01c200d4 {
++ #clock-cells = <0>;
++ compatible = "allwinner,sun4i-mod0-clk";
++ reg = <0x01c200d4 0x4>;
++ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++ };
+ };
+
+ soc@01c00000 {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch b/target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch
new file mode 100644
index 0000000000..7ef6ea25d2
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch
@@ -0,0 +1,11 @@
+diff -ruN old/arch/arm/mach-sunxi/sunxi.c new/arch/arm/mach-sunxi/sunxi.c
+--- old/arch/arm/mach-sunxi/sunxi.c 2014-01-04 01:57:31.000000000 +0100
++++ new/arch/arm/mach-sunxi/sunxi.c 2014-01-04 01:11:47.000000000 +0100
+@@ -10,6 +10,7 @@
+ * warranty of any kind, whether express or implied.
+ */
+
++#include <linux/clk-provider.h>
+ #include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
diff --git a/target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch b/target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch
new file mode 100644
index 0000000000..ad5935c89f
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch
@@ -0,0 +1,149 @@
+From 11e7ff129807394d87c937b880bb58972dc91fc0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 28 Nov 2013 09:00:47 -0300
+Subject: [PATCH] fixup! clk: sunxi: add PLL5 and PLL6 support
+
+---
+ drivers/clk/sunxi/clk-sunxi.c | 83 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 69 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index d2b8d3c..3ce33b8 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -807,10 +807,11 @@ struct divs_data {
+ struct clk_div_table *table; /* is it a table based divisor? */
+ u8 shift; /* otherwise it's a normal divisor with this shift */
+ u8 pow; /* is it power-of-two based? */
++ u8 gate; /* is it independently gateable? */
+ } div[SUNXI_DIVS_MAX_QTY];
+ };
+
+-static struct clk_div_table pll6_sata_table[] = {
++static struct clk_div_table pll6_sata_tbl[] = {
+ { .val = 0, .div = 6, },
+ { .val = 1, .div = 12, },
+ { .val = 2, .div = 18, },
+@@ -829,7 +830,7 @@ struct divs_data {
+ static const struct divs_data pll6_divs_data __initconst = {
+ .factors = &sun4i_pll5_data,
+ .div = {
+- { .shift = 0, .table = pll6_sata_table }, /* M, SATA */
++ { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
+ { .fixed = 2 }, /* P, other */
+ }
+ };
+@@ -852,6 +853,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ const char *parent = node->name;
+ const char *clk_name;
+ struct clk **clks, *pclk;
++ struct clk_hw *gate_hw, *rate_hw;
++ const struct clk_ops *rate_ops;
++ struct clk_gate *gate = NULL;
++ struct clk_fixed_factor *fix_factor;
++ struct clk_divider *divider;
+ void *reg;
+ int i = 0;
+ int flags, clkflags;
+@@ -866,10 +872,9 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ return;
+
+ clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
+- if (!clks) {
+- kfree(clk_data);
+- return;
+- }
++ if (!clks)
++ goto free_clkdata;
++
+ clk_data->clks = clks;
+
+ /* It's not a good idea to have automatic reparenting changing
+@@ -881,19 +886,60 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ i, &clk_name) != 0)
+ break;
+
++ gate_hw = NULL;
++ rate_hw = NULL;
++ rate_ops = NULL;
++
++ /* If this leaf clock can be gated, create a gate */
++ if (data->div[i].gate) {
++ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
++ if (!gate)
++ goto free_clks;
++
++ gate->reg = reg;
++ gate->bit_idx = data->div[i].gate;
++ gate->lock = &clk_lock;
++
++ gate_hw = &gate->hw;
++ }
++
++ /* Leaves can be fixed or configurable divisors */
+ if (data->div[i].fixed) {
+- clks[i] = clk_register_fixed_factor(NULL, clk_name,
+- parent, clkflags,
+- 1, data->div[i].fixed);
++ fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
++ if (!fix_factor)
++ goto free_gate;
++
++ fix_factor->mult = 1;
++ fix_factor->div = data->div[i].fixed;
++
++ rate_hw = &fix_factor->hw;
++ rate_ops = &clk_fixed_factor_ops;
+ } else {
++ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
++ if (!divider)
++ goto free_gate;
++
+ flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
+- clks[i] = clk_register_divider_table(NULL, clk_name,
+- parent, clkflags, reg,
+- data->div[i].shift,
+- SUNXI_DIVISOR_WIDTH, flags,
+- data->div[i].table, &clk_lock);
++
++ divider->reg = reg;
++ divider->shift = data->div[i].shift;
++ divider->width = SUNXI_DIVISOR_WIDTH;
++ divider->flags = flags;
++ divider->lock = &clk_lock;
++ divider->table = data->div[i].table;
++
++ rate_hw = &divider->hw;
++ rate_ops = &clk_divider_ops;
+ }
+
++ /* Wrap the (potential) gate and the divisor on a composite
++ * clock to unify them */
++ clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
++ NULL, NULL,
++ rate_hw, rate_ops,
++ gate_hw, &clk_gate_ops,
++ clkflags);
++
+ WARN_ON(IS_ERR(clk_data->clks[i]));
+ clk_register_clkdev(clks[i], clk_name, NULL);
+ }
+@@ -905,6 +951,15 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ clk_data->clk_num = i;
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++ return;
++
++free_gate:
++ kfree(gate);
++free_clks:
++ kfree(clks);
++free_clkdata:
++ kfree(clk_data);
+ }
+
+
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch b/target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch
new file mode 100644
index 0000000000..0b4697a605
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch
@@ -0,0 +1,74 @@
+From de7bfadd1022613ab2c7eeca124bb1e4a6f4c072 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:43:33 -0300
+Subject: [PATCH] clk: composite: .determine_rate support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds .determine_rate support to the composite clock. It will
+use the .determine_rate callback from the rate component if available,
+and fall back on the mux component otherwise. This allows composite
+clocks to enjoy the benefits of automatic clock reparenting.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/clk-composite.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
+index a33f46f..753d0b7 100644
+--- a/drivers/clk/clk-composite.c
++++ b/drivers/clk/clk-composite.c
+@@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+ return rate_ops->recalc_rate(rate_hw, parent_rate);
+ }
+
++static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p)
++{
++ struct clk_composite *composite = to_clk_composite(hw);
++ const struct clk_ops *rate_ops = composite->rate_ops;
++ const struct clk_ops *mux_ops = composite->mux_ops;
++ struct clk_hw *rate_hw = composite->rate_hw;
++ struct clk_hw *mux_hw = composite->mux_hw;
++
++ if (rate_hw && rate_ops && rate_ops->determine_rate) {
++ rate_hw->clk = hw->clk;
++ return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
++ best_parent_p);
++ } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
++ mux_hw->clk = hw->clk;
++ return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
++ best_parent_p);
++ } else {
++ pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
++ return 0;
++ }
++}
++
+ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+ {
+@@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
+ composite->mux_ops = mux_ops;
+ clk_composite_ops->get_parent = clk_composite_get_parent;
+ clk_composite_ops->set_parent = clk_composite_set_parent;
++ if (mux_ops->determine_rate)
++ clk_composite_ops->determine_rate = clk_composite_determine_rate;
+ }
+
+ if (rate_hw && rate_ops) {
+@@ -170,6 +196,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
+ composite->rate_hw = rate_hw;
+ composite->rate_ops = rate_ops;
+ clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
++ if (rate_ops->determine_rate)
++ clk_composite_ops->determine_rate = clk_composite_determine_rate;
+ }
+
+ if (gate_hw && gate_ops) {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch b/target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch
new file mode 100644
index 0000000000..1ed5754b50
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch
@@ -0,0 +1,73 @@
+From 679e8db359d0c1994e88f3a4a2aa0697ce001ad4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:52:41 -0300
+Subject: [PATCH] clk: sunxi: factors: automatic reparenting support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit implements .determine_rate, so that our factor clocks can be
+reparented when needed.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 9e23264..3806d97 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ return rate;
+ }
+
++static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p)
++{
++ 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 = clk_factors_round_rate(hw, rate, &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_p = best_parent;
++ *best_parent_rate = best;
++
++ return best_child_rate;
++}
++
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ }
+
+ const struct clk_ops clk_factors_ops = {
++ .determine_rate = clk_factors_determine_rate,
+ .recalc_rate = clk_factors_recalc_rate,
+ .round_rate = clk_factors_round_rate,
+ .set_rate = clk_factors_set_rate,
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch b/target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch
new file mode 100644
index 0000000000..951eaffa3d
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch
@@ -0,0 +1,63 @@
+From 75d3fa72634a4943f0f03146916094b6f4908552 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sun, 8 Sep 2013 18:14:52 -0300
+Subject: [PATCH] clk: sunxi: unify APB1 clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit unifies the APB1 mux with the APB1 clock, using the new
+factors infrastructure.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt | 1 -
+ drivers/clk/sunxi/clk-sunxi.c | 6 +-----
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index 46d8433..e840cb2 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -27,7 +27,6 @@ Required properties:
+ "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
+ "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
+ "allwinner,sun4i-apb1-clk" - for the APB1 clock
+- "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
+ "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
+ "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
+ "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 06c4f01..0ecaa18 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -400,6 +400,7 @@ struct factors_data {
+ };
+
+ static const struct factors_data sun4i_apb1_data __initconst = {
++ .mux = 24,
+ .table = &sun4i_apb1_config,
+ .getter = sun4i_get_apb1_factors,
+ };
+@@ -511,10 +512,6 @@ struct mux_data {
+ .shift = 12,
+ };
+
+-static const struct mux_data sun4i_apb1_mux_data __initconst = {
+- .shift = 24,
+-};
+-
+ static void __init sunxi_mux_clk_setup(struct device_node *node,
+ struct mux_data *data)
+ {
+@@ -869,7 +866,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ /* Matches for mux clocks */
+ static const struct of_device_id clk_mux_match[] __initconst = {
+ {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
+- {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
+ {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
+ {}
+ };
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch b/target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch
new file mode 100644
index 0000000000..7652391cf3
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch
@@ -0,0 +1,118 @@
+From f3443f6d43a69a520ae1e636d69a71c4a6bee21e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sun, 8 Sep 2013 18:12:28 -0300
+Subject: [PATCH] ARM: sunxi: dt: unify APB1 clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With the new factors infrastructure in place, we can unify apb1 and
+apb1_mux as a single clock now.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 9 +--------
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +--------
+ arch/arm/boot/dts/sun5i-a13.dtsi | 9 +--------
+ arch/arm/boot/dts/sun7i-a20.dtsi | 9 +--------
+ 4 files changed, 4 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 2828427e..4dccdb0 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -158,18 +158,11 @@
+ "apb0_ir1", "apb0_keypad";
+ };
+
+- apb1_mux: apb1_mux@01c20058 {
+- #clock-cells = <0>;
+- compatible = "allwinner,sun4i-apb1-mux-clk";
+- reg = <0x01c20058 0x4>;
+- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+- };
+-
+ apb1: apb1@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-apb1-clk";
+ reg = <0x01c20058 0x4>;
+- clocks = <&apb1_mux>;
++ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ };
+
+ apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 60bd3f7..9cb1b14 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -150,18 +150,11 @@
+ "apb0_ir", "apb0_keypad";
+ };
+
+- apb1_mux: apb1_mux@01c20058 {
+- #clock-cells = <0>;
+- compatible = "allwinner,sun4i-apb1-mux-clk";
+- reg = <0x01c20058 0x4>;
+- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+- };
+-
+ apb1: apb1@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-apb1-clk";
+ reg = <0x01c20058 0x4>;
+- clocks = <&apb1_mux>;
++ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ };
+
+ apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 3e616a0..6b74dd0 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -148,18 +148,11 @@
+ clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
+ };
+
+- apb1_mux: apb1_mux@01c20058 {
+- #clock-cells = <0>;
+- compatible = "allwinner,sun4i-apb1-mux-clk";
+- reg = <0x01c20058 0x4>;
+- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+- };
+-
+ apb1: apb1@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-apb1-clk";
+ reg = <0x01c20058 0x4>;
+- clocks = <&apb1_mux>;
++ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ };
+
+ apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 0bf5d07..55d3e14 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -148,18 +148,11 @@
+ "apb0_iis2", "apb0_keypad";
+ };
+
+- apb1_mux: apb1_mux@01c20058 {
+- #clock-cells = <0>;
+- compatible = "allwinner,sun4i-apb1-mux-clk";
+- reg = <0x01c20058 0x4>;
+- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+- };
+-
+ apb1: apb1@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-apb1-clk";
+ reg = <0x01c20058 0x4>;
+- clocks = <&apb1_mux>;
++ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+ };
+
+ apb1_gates: apb1_gates@01c2006c {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch b/target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch
new file mode 100644
index 0000000000..3446b37c4d
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch
@@ -0,0 +1,102 @@
+From 147a46beeb49c6baabb85126d570f330a2ba7cad Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:48:40 -0300
+Subject: [PATCH] clk: sunxi: Implement muxable AHB clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to change the AHB clock parent, this commit
+adds support for it on the driver.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt | 1 +
+ drivers/clk/sunxi/clk-sunxi.c | 37 +++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index e840cb2..941bd93 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -15,6 +15,7 @@ Required properties:
+ "allwinner,sun4i-axi-clk" - for the AXI clock
+ "allwinner,sun4i-axi-gates-clk" - for the AXI gates
+ "allwinner,sun4i-ahb-clk" - for the AHB clock
++ "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
+ "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
+ "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
+ "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 0ecaa18..360d705 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -240,7 +240,32 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
+ *n = DIV_ROUND_UP(div, (*k+1));
+ }
+
++/**
++ * sun5i_get_ahb_factors() - calculates p factor for AHB
++ * AHB rate is calculated as follows
++ * rate = parent_rate >> p
++ */
+
++static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
++ u8 *n, u8 *k, u8 *m, u8 *p)
++{
++ u8 div;
++
++ /* This clock can only divide, so we will never achieve a higher
++ * rate than the parent's */
++ if (*freq > parent_rate)
++ *freq = parent_rate;
++
++ /* Normalize value to a parent multiple */
++ div = *freq / parent_rate;
++ *freq = parent_rate * div;
++
++ /* we were called to round the frequency, we can now return */
++ if (n == NULL)
++ return;
++
++ *p = div;
++}
+
+ /**
+ * sun4i_get_apb1_factors() - calculates m, p factors for APB1
+@@ -366,6 +391,11 @@ struct factors_data {
+ .kwidth = 2,
+ };
+
++static struct clk_factors_config sun5i_a13_ahb_config = {
++ .pshift = 4,
++ .pwidth = 2,
++};
++
+ static struct clk_factors_config sun4i_apb1_config = {
+ .mshift = 0,
+ .mwidth = 5,
+@@ -399,6 +429,12 @@ struct factors_data {
+ .getter = sun4i_get_pll5_factors,
+ };
+
++static const struct factors_data sun5i_a13_ahb_data __initconst = {
++ .mux = 6,
++ .table = &sun5i_a13_ahb_config,
++ .getter = sun5i_a13_get_ahb_factors,
++};
++
+ static const struct factors_data sun4i_apb1_data __initconst = {
+ .mux = 24,
+ .table = &sun4i_apb1_config,
+@@ -842,6 +878,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ static const struct of_device_id clk_factors_match[] __initconst = {
+ {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
+ {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
++ {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
+ {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+ {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
+ {}
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch b/target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch
new file mode 100644
index 0000000000..3d48a608de
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch
@@ -0,0 +1,69 @@
+From 051f43def45e53d93b9998728e398a68c4948114 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:44:03 -0300
+Subject: [PATCH] ARM: sunxi: dt: Update AHB clock to be muxable on sun[57]i
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to select the parent clock for AHB. This
+commit implements the required changes on the device trees.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++--
+ arch/arm/boot/dts/sun5i-a13.dtsi | 4 ++--
+ arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 9cb1b14..83e183c 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -115,9 +115,9 @@
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+- compatible = "allwinner,sun4i-ahb-clk";
++ compatible = "allwinner,sun5i-a13-ahb-clk";
+ reg = <0x01c20054 0x4>;
+- clocks = <&axi>;
++ clocks = <&axi>, <&cpu>, <&pll6 1>;
+ };
+
+ ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 6b74dd0..0bb4300 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -115,9 +115,9 @@
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+- compatible = "allwinner,sun4i-ahb-clk";
++ compatible = "allwinner,sun5i-a13-ahb-clk";
+ reg = <0x01c20054 0x4>;
+- clocks = <&axi>;
++ clocks = <&axi>, <&cpu>, <&pll6 1>;
+ };
+
+ ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 55d3e14..63757c5 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -105,9 +105,9 @@
+
+ ahb: ahb@01c20054 {
+ #clock-cells = <0>;
+- compatible = "allwinner,sun4i-ahb-clk";
++ compatible = "allwinner,sun5i-a13-ahb-clk";
+ reg = <0x01c20054 0x4>;
+- clocks = <&axi>;
++ clocks = <&axi>, <&pll6 1>, <&pll6 2>;
+ };
+
+ ahb_gates: ahb_gates@01c20060 {
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch b/target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch
new file mode 100644
index 0000000000..296e0e478d
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch
@@ -0,0 +1,108 @@
+From be0804513a506de96925f9ed1aa8dc1facd4c180 Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Fri, 6 Sep 2013 14:59:57 +0200
+Subject: [PATCH] clk: sunxi: declare OF clock provider
+
+Common clock framework allows to register clock providers to get called
+on of_clk_init() by using CLK_OF_DECLARE. This converts sunxi clock
+providers to make use of it and get rid of the mach specific clk init
+call. As sunxi has a bunch of independent clk provider nodes, we hook
+current clock init to board compatible to make it called once.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ arch/arm/mach-sunxi/sunxi.c | 4 +---
+ drivers/clk/sunxi/clk-sunxi.c | 11 ++++++-----
+ include/linux/clk/sunxi.h | 22 ----------------------
+ 3 files changed, 7 insertions(+), 30 deletions(-)
+ delete mode 100644 include/linux/clk/sunxi.h
+
+diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
+index e79fb34..e5a6975 100644
+--- a/arch/arm/mach-sunxi/sunxi.c
++++ b/arch/arm/mach-sunxi/sunxi.c
+@@ -20,8 +20,6 @@
+ #include <linux/io.h>
+ #include <linux/reboot.h>
+
+-#include <linux/clk/sunxi.h>
+-
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/system_misc.h>
+@@ -118,7 +116,7 @@ static void sunxi_setup_restart(void)
+
+ static void __init sunxi_timer_init(void)
+ {
+- sunxi_init_clocks();
++ of_clk_init(NULL);
+ clocksource_of_init();
+ }
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 34ee69f..9bbd035 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -16,7 +16,6 @@
+
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+-#include <linux/clk/sunxi.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+
+@@ -617,11 +616,8 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
+ }
+ }
+
+-void __init sunxi_init_clocks(void)
++static void __init sunxi_init_clocks(struct device_node *np)
+ {
+- /* Register all the simple and basic clocks on DT */
+- of_clk_init(NULL);
+-
+ /* Register factor clocks */
+ of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
+
+@@ -634,3 +630,8 @@ void __init sunxi_init_clocks(void)
+ /* Register gate clocks */
+ of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
+ }
++CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
++CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
++CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sunxi_init_clocks);
++CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sunxi_init_clocks);
++CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sunxi_init_clocks);
+diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
+deleted file mode 100644
+index e074fdd..0000000
+--- a/include/linux/clk/sunxi.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/*
+- * Copyright 2012 Maxime Ripard
+- *
+- * Maxime Ripard <maxime.ripard@free-electrons.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; 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.
+- */
+-
+-#ifndef __LINUX_CLK_SUNXI_H_
+-#define __LINUX_CLK_SUNXI_H_
+-
+-void __init sunxi_init_clocks(void);
+-
+-#endif
+--
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch b/target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch
new file mode 100644
index 0000000000..50536d1a1e
--- /dev/null
+++ b/target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch
@@ -0,0 +1,67 @@
+From d1bcc34ce6cb7601ce27f3090aee0e8a3e8076e3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:54:42 -0300
+Subject: [PATCH] clk: sunxi: protect core clocks from accidental shutdown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some important clocks may get disabled as a side effect of another clock
+being disabled, because they have no consumers. This patch implements a
+mechanism so those clocks can be claimed by the driver and therefore
+remain enabled at all times.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 9bbd035..8fc1375 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -616,6 +616,31 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
+ }
+ }
+
++/**
++ * System clock protection
++ *
++ * By enabling these critical clocks, we prevent their accidental gating
++ * by the framework
++ */
++static void __init sunxi_clock_protect(void)
++{
++ struct clk *clk;
++
++ /* memory bus clock - sun5i+ */
++ clk = clk_get(NULL, "mbus");
++ if (!IS_ERR(clk)) {
++ clk_prepare_enable(clk);
++ clk_put(clk);
++ }
++
++ /* DDR clock - sun4i+ */
++ clk = clk_get(NULL, "pll5_ddr");
++ if (!IS_ERR(clk)) {
++ clk_prepare_enable(clk);
++ clk_put(clk);
++ }
++}
++
+ static void __init sunxi_init_clocks(struct device_node *np)
+ {
+ /* Register factor clocks */
+@@ -629,6 +654,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
+
+ /* Register gate clocks */
+ of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
++
++ /* Enable core system clocks */
++ sunxi_clock_protect();
+ }
+ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
+ CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
+--
+1.8.5.1
+