From 8d7330cff8ff1c611db7e894ab0062248f1fd22c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 20 Oct 2013 15:42:02 +0800 Subject: clk: mux: fix the return value of get_parent If there're no parents on the clock mux node, it should return 0, not an errnor code. The orphan clock node is using get_parent() to get the index of its parents in__clk_init(). If the return value is negative, it'll be transformed to a u8 value (clk_mux_get_parent()). Then the orphan clock node tries to get its parent with the invalid index. It will only cause accessing memory beyond border. Signed-off-by: Haojian Zhuang --- drivers/clk/clk-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index cbfbb1b07793..5af146ac500c 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -51,7 +51,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) for (i = 0; i < num_parents; i++) if (mux->table[i] == val) return i; - return -EINVAL; + return 0; } if (val && (mux->flags & CLK_MUX_INDEX_BIT)) @@ -61,7 +61,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) val--; if (val >= num_parents) - return -EINVAL; + return 0; return val; } -- cgit v1.2.3 From 17a1a8fe4338d4bd267ca9c9b4729b0ff1c73879 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 20 Oct 2013 16:32:50 +0800 Subject: ARM: dts: fix incorrect clock mux setting of ldi Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/hi3620.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index 34221f717c88..7fea9cebe09c 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -378,19 +378,19 @@ compatible = "hisilicon,hi3620-clk-mux"; #clock-cells = <0>; hiword; - clocks = <&pll_peri &pll_usb &pll_hdmi>; + clocks = <&pll_peri &pll_hdmi &pll_usb>; clock-output-names = "rclk_ldi0"; hisilicon,clkmux-reg = <0x114 0x6000>; - hisilicon,clkmux-table = <0 0x6000>; + hisilicon,clkmux-table = <0 0x2000 0x4000>; }; refclk_ldi1: refclk@33 { compatible = "hisilicon,hi3620-clk-mux"; #clock-cells = <0>; hiword; - clocks = <&pll_peri &pll_usb &pll_hdmi>; + clocks = <&pll_peri &pll_hdmi &pll_usb>; clock-output-names = "rclk_ldi1"; hisilicon,clkmux-reg = <0x118 0xc000>; - hisilicon,clkmux-table = <0 0xc000>; + hisilicon,clkmux-table = <0 0x4000 0x8000>; }; clk_osc480mdiv40: osc480mdiv40 { compatible = "hisilicon,clk-fixed-factor"; -- cgit v1.2.3 From 1c16ddeb3574a51f508964ecd4a35e6b221fbde7 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 22 Oct 2013 16:50:38 +0800 Subject: clk: hi3xxx: fix the useless pointer in mux The code of parsing mux table was moved into a function. But the pointer is still *, not **. So it won't work right. Fix it by merging code into mux setup function. Signed-off-by: Haojian Zhuang --- drivers/clk/hisilicon/clk-hi3xxx.c | 57 +++++++++++++------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/drivers/clk/hisilicon/clk-hi3xxx.c b/drivers/clk/hisilicon/clk-hi3xxx.c index b14c11c0899a..a331a786e343 100644 --- a/drivers/clk/hisilicon/clk-hi3xxx.c +++ b/drivers/clk/hisilicon/clk-hi3xxx.c @@ -213,45 +213,14 @@ err_pclk: kfree(parent_names); } -static int __init hi3xxx_parse_mux(struct device_node *np, - u8 *num_parents, - u32 *table) -{ - int i, cnt, ret; - - /* get the count of items in mux */ - for (i = 0, cnt = 0; ; i++, cnt++) { - /* parent's #clock-cells property is always 0 */ - if (!of_parse_phandle(np, "clocks", i)) - break; - } - - for (i = 0; i < cnt; i++) { - if (!of_clk_get_parent_name(np, i)) - return -ENOENT; - } - *num_parents = cnt; - table = kzalloc(sizeof(u32 *) * cnt, GFP_KERNEL); - if (!table) - return -ENOMEM; - ret = of_property_read_u32_array(np, "hisilicon,clkmux-table", - table, cnt); - if (ret) - goto err; - return 0; -err: - kfree(table); - return ret; -} - static void __init hi3620_clkmux_setup(struct device_node *np) { struct clk *clk; const char *clk_name, **parent_names = NULL; u32 rdata[2], mask, *table = NULL; - u8 num_parents, shift, flag = 0; + u8 shift, flag = 0; void __iomem *reg, *base; - int i, ret; + int i, cnt, ret; base = hs_init_clocks(np); if (!base) @@ -266,20 +235,32 @@ static void __init hi3620_clkmux_setup(struct device_node *np) if (of_property_read_bool(np, "hiword")) flag = CLK_MUX_HIWORD_MASK; - ret = hi3xxx_parse_mux(np, &num_parents, table); - if (ret) + cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (cnt < 0) { + pr_err("failed to find clock parent\n"); + return; + } + + table = kzalloc(sizeof(u32) * cnt, GFP_KERNEL); + if (!table) + return; + ret = of_property_read_u32_array(np, "hisilicon,clkmux-table", + table, cnt); + if (ret) { + pr_err("failed on parsing %s's clkmux-table \n", clk_name); return; + } - parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL); + parent_names = kzalloc(sizeof(char *) * cnt, GFP_KERNEL); if (!parent_names) goto err; - for (i = 0; i < num_parents; i++) + for (i = 0; i < cnt; i++) parent_names[i] = of_clk_get_parent_name(np, i); reg = base + rdata[0]; shift = ffs(rdata[1]) - 1; mask = rdata[1] >> shift; - clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents, + clk = clk_register_mux_table(NULL, clk_name, parent_names, (u8)cnt, CLK_SET_RATE_PARENT, reg, shift, mask, flag, table, &hs_clk.lock); -- cgit v1.2.3 From ac0e022afe859456928bdbe2b8a545dca80e1c5b Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 22 Oct 2013 16:52:35 +0800 Subject: ARM: dts: fix value in mux table The clkmux-table is defined with original value of different mux setting. Since clk_mux_register_table() is used, the definition of mux table should be the vaule after shift operation. So fix this issue by the value after shift operation. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/hi3620.dtsi | 62 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index 7fea9cebe09c..ff0c5cd5c3c1 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -120,7 +120,7 @@ clock-output-names = "rclk_uart0"; /* reg_offset, enable_bits */ hisilicon,clkmux-reg = <0x100 0x80>; - hisilicon,clkmux-table = <0 0x80>; + hisilicon,clkmux-table = <0 1>; }; refclk_uart1: refclk@1 { compatible = "hisilicon,hi3620-clk-mux"; @@ -129,7 +129,7 @@ hiword; clock-output-names = "rclk_uart1"; hisilicon,clkmux-reg = <0x100 0x100>; - hisilicon,clkmux-table = <0 0x100>; + hisilicon,clkmux-table = <0 1>; }; refclk_uart2: refclk@2 { compatible = "hisilicon,hi3620-clk-mux"; @@ -138,7 +138,7 @@ hiword; clock-output-names = "rclk_uart2"; hisilicon,clkmux-reg = <0x100 0x200>; - hisilicon,clkmux-table = <0 0x200>; + hisilicon,clkmux-table = <0 1>; }; refclk_uart3: refclk@3 { compatible = "hisilicon,hi3620-clk-mux"; @@ -147,7 +147,7 @@ hiword; clock-output-names = "rclk_uart3"; hisilicon,clkmux-reg = <0x100 0x400>; - hisilicon,clkmux-table = <0 0x400>; + hisilicon,clkmux-table = <0 1>; }; refclk_uart4: refclk@4 { compatible = "hisilicon,hi3620-clk-mux"; @@ -156,7 +156,7 @@ hiword; clock-output-names = "rclk_uart4"; hisilicon,clkmux-reg = <0x100 0x800>; - hisilicon,clkmux-table = <0 0x800>; + hisilicon,clkmux-table = <0 1>; }; refclk_hsic: hsic { @@ -166,7 +166,7 @@ hiword; clock-output-names = "rclk_hsic"; hisilicon,clkmux-reg = <0x130 0x4>; - hisilicon,clkmux-table = <0 0x4>; + hisilicon,clkmux-table = <0 1>; }; clk_osc480m: clk_osc480m { @@ -193,7 +193,7 @@ hiword; clock-output-names = "rclk_spi0"; hisilicon,clkmux-reg = <0x100 0x1000>; - hisilicon,clkmux-table = <0 0x1000>; + hisilicon,clkmux-table = <0 1>; }; refclk_spi1: refclk@7 { compatible = "hisilicon,hi3620-clk-mux"; @@ -202,7 +202,7 @@ hiword; clock-output-names = "rclk_spi1"; hisilicon,clkmux-reg = <0x100 0x2000>; - hisilicon,clkmux-table = <0 0x2000>; + hisilicon,clkmux-table = <0 1>; }; refclk_spi2: refclk@8 { compatible = "hisilicon,hi3620-clk-mux"; @@ -211,7 +211,7 @@ hiword; clock-output-names = "rclk_spi2"; hisilicon,clkmux-reg = <0x100 0x4000>; - hisilicon,clkmux-table = <0 0x4000>; + hisilicon,clkmux-table = <0 1>; }; refclk_tcxo: refclk@11 { compatible = "hisilicon,clk-fixed-factor"; @@ -226,7 +226,7 @@ clocks = <&osc32k &timerclk01>; clock-output-names = "timer0_mux"; hisilicon,clkmux-reg = <0 0x18000>; - hisilicon,clkmux-table = <0 0x8000>; + hisilicon,clkmux-table = <0 1>; }; timer1_mux: timer1_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -234,7 +234,7 @@ clocks = <&osc32k &timerclk01>; clock-output-names = "timer1_mux"; hisilicon,clkmux-reg = <0 0x60000>; - hisilicon,clkmux-table = <0 0x20000>; + hisilicon,clkmux-table = <0 1>; }; timer2_mux: timer2_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -242,7 +242,7 @@ clocks = <&osc32k &timerclk23>; clock-output-names = "timer2_mux"; hisilicon,clkmux-reg = <0 0x180000>; - hisilicon,clkmux-table = <0 0x80000>; + hisilicon,clkmux-table = <0 1>; }; timer3_mux: timer3_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -250,7 +250,7 @@ clocks = <&osc32k &timerclk23>; clock-output-names = "timer3_mux"; hisilicon,clkmux-reg = <0 0x600000>; - hisilicon,clkmux-table = <0 0x200000>; + hisilicon,clkmux-table = <0 1>; }; timer4_mux: timer4_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -258,7 +258,7 @@ clocks = <&osc32k &timerclk45>; clock-output-names = "timer4_mux"; hisilicon,clkmux-reg = <0x18 0x3>; - hisilicon,clkmux-table = <0 0x1>; + hisilicon,clkmux-table = <0 1>; }; timer5_mux: timer5_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -266,7 +266,7 @@ clocks = <&osc32k &timerclk45>; clock-output-names = "timer5_mux"; hisilicon,clkmux-reg = <0x18 0xc>; - hisilicon,clkmux-table = <0 0x4>; + hisilicon,clkmux-table = <0 1>; }; timer6_mux: timer6_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -274,7 +274,7 @@ clocks = <&osc32k &timerclk67>; clock-output-names = "timer6_mux"; hisilicon,clkmux-reg = <0x18 0x30>; - hisilicon,clkmux-table = <0 0x10>; + hisilicon,clkmux-table = <0 1>; }; timer7_mux: timer7_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -282,7 +282,7 @@ clocks = <&osc32k &timerclk67>; clock-output-names = "timer7_mux"; hisilicon,clkmux-reg = <0x18 0xc0>; - hisilicon,clkmux-table = <0 0x40>; + hisilicon,clkmux-table = <0 1>; }; refclk_shareAXI: refclk@22 { compatible = "hisilicon,hi3620-clk-mux"; @@ -291,7 +291,7 @@ hiword; clock-output-names = "rclk_shareAXI"; hisilicon,clkmux-reg = <0x24 0x8000>; - hisilicon,clkmux-table = <0 0x8000>; + hisilicon,clkmux-table = <0 1>; }; refclk_mmc1: refclk@23 { compatible = "hisilicon,hi3620-clk-mux"; @@ -300,7 +300,7 @@ hiword; clock-output-names = "rclk_mmc1"; hisilicon,clkmux-reg = <0x108 0x200>; - hisilicon,clkmux-table = <0 0x200>; + hisilicon,clkmux-table = <0 1>; }; refclk_mmc2: refclk@24 { compatible = "hisilicon,hi3620-clk-mux"; @@ -309,7 +309,7 @@ hiword; clock-output-names = "rclk_mmc2"; hisilicon,clkmux-reg = <0x140 0x10>; - hisilicon,clkmux-table = <0 0x10>; + hisilicon,clkmux-table = <0 1>; }; refclk_mmc3: refclk@25 { compatible = "hisilicon,hi3620-clk-mux"; @@ -318,7 +318,7 @@ hiword; clock-output-names = "rclk_mmc3"; hisilicon,clkmux-reg = <0x140 0x200>; - hisilicon,clkmux-table = <0 0x200>; + hisilicon,clkmux-table = <0 1>; }; refclk_sd: refclk@26 { compatible = "hisilicon,hi3620-clk-mux"; @@ -327,7 +327,7 @@ hiword; clock-output-names = "rclk_sd"; hisilicon,clkmux-reg = <0x108 0x10>; - hisilicon,clkmux-table = <0 0x10>; + hisilicon,clkmux-table = <0 1>; }; refclk_mmc1_parent: refclk@27 { compatible = "hisilicon,hi3620-clk-mux"; @@ -336,7 +336,7 @@ clocks = <&osc26m &div_mmc1>; clock-output-names = "rclk_mmc1_parent"; hisilicon,clkmux-reg = <0x108 0x400>; - hisilicon,clkmux-table = <0 0x400>; + hisilicon,clkmux-table = <0 1>; }; refclk_venc: refclk@28 { compatible = "hisilicon,hi3620-clk-mux"; @@ -345,7 +345,7 @@ clocks = <&pll_peri &pll_usb>; clock-output-names = "rclk_venc"; hisilicon,clkmux-reg = <0x10c 0x800>; - hisilicon,clkmux-table = <0 0x800>; + hisilicon,clkmux-table = <0 1>; }; refclk_g2d: refclk@29 { compatible = "hisilicon,hi3620-clk-mux"; @@ -354,7 +354,7 @@ clocks = <&pll_peri &pll_usb>; clock-output-names = "rclk_g2d"; hisilicon,clkmux-reg = <0x10c 0x20>; - hisilicon,clkmux-table = <0 0x20>; + hisilicon,clkmux-table = <0 1>; }; refclk_vdec: refclk@30 { compatible = "hisilicon,hi3620-clk-mux"; @@ -363,7 +363,7 @@ clocks = <&pll_peri &pll_usb>; clock-output-names = "rclk_vdec"; hisilicon,clkmux-reg = <0x110 0x20>; - hisilicon,clkmux-table = <0 0x20>; + hisilicon,clkmux-table = <0 1>; }; refclk_vpp: refclk@31 { compatible = "hisilicon,hi3620-clk-mux"; @@ -372,7 +372,7 @@ clocks = <&pll_peri &pll_usb>; clock-output-names = "rclk_vpp"; hisilicon,clkmux-reg = <0x110 0x800>; - hisilicon,clkmux-table = <0 0x800>; + hisilicon,clkmux-table = <0 1>; }; refclk_ldi0: refclk@32 { compatible = "hisilicon,hi3620-clk-mux"; @@ -381,7 +381,7 @@ clocks = <&pll_peri &pll_hdmi &pll_usb>; clock-output-names = "rclk_ldi0"; hisilicon,clkmux-reg = <0x114 0x6000>; - hisilicon,clkmux-table = <0 0x2000 0x4000>; + hisilicon,clkmux-table = <0 1 2>; }; refclk_ldi1: refclk@33 { compatible = "hisilicon,hi3620-clk-mux"; @@ -390,7 +390,7 @@ clocks = <&pll_peri &pll_hdmi &pll_usb>; clock-output-names = "rclk_ldi1"; hisilicon,clkmux-reg = <0x118 0xc000>; - hisilicon,clkmux-table = <0 0x4000 0x8000>; + hisilicon,clkmux-table = <0 1 2>; }; clk_osc480mdiv40: osc480mdiv40 { compatible = "hisilicon,clk-fixed-factor"; @@ -663,7 +663,7 @@ hiword; clock-output-names = "pwm0_mux"; hisilicon,clkmux-reg = <0x104 0x400>; - hisilicon,clkmux-table = <0 0x400>; + hisilicon,clkmux-table = <0 1>; }; pwm1_mux: pwm1_mux { compatible = "hisilicon,hi3620-clk-mux"; @@ -672,7 +672,7 @@ hiword; clock-output-names = "pwm1_mux"; hisilicon,clkmux-reg = <0x104 0x800>; - hisilicon,clkmux-table = <0 0x800>; + hisilicon,clkmux-table = <0 1>; }; pwmclk0: clkgate@30 { compatible = "hisilicon,hi3620-clk-gate"; -- cgit v1.2.3