Commit 12ba8571ab6b232f5facef6b1dd28c5ebc2b530a
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux
Pull clock driver fixes from Mike Turquette: "Small number of fixes for clock drivers and a single null pointer dereference fix in the framework core code. The driver fixes vary from fixing section mismatch warnings to preventing machines from hanging (and preventing developers from crying)" * tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mike.turquette/linux: clk: fix possible null pointer dereference Revert "clk: ppc-corenet: Fix Section mismatch warning" clk: rockchip: fix deadlock possibility in cpuclk clk: berlin: bg2q: remove non-exist "smemc" gate clock clk: at91: keep slow clk enabled to prevent system hang clk: rockchip: fix rk3288 cpuclk core dividers clk: rockchip: fix rk3066 pll lock bit location clk: rockchip: Fix clock gate for rk3188 hclk_emem_peri clk: rockchip: add CLK_IGNORE_UNUSED flag to fix rk3066/rk3188 USB Host
Showing 7 changed files Side-by-side Diff
drivers/clk/at91/clk-slow.c
... | ... | @@ -70,6 +70,7 @@ |
70 | 70 | |
71 | 71 | #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) |
72 | 72 | |
73 | +static struct clk *slow_clk; | |
73 | 74 | |
74 | 75 | static int clk_slow_osc_prepare(struct clk_hw *hw) |
75 | 76 | { |
... | ... | @@ -357,6 +358,8 @@ |
357 | 358 | clk = clk_register(NULL, &slowck->hw); |
358 | 359 | if (IS_ERR(clk)) |
359 | 360 | kfree(slowck); |
361 | + else | |
362 | + slow_clk = clk; | |
360 | 363 | |
361 | 364 | return clk; |
362 | 365 | } |
... | ... | @@ -433,6 +436,8 @@ |
433 | 436 | clk = clk_register(NULL, &slowck->hw); |
434 | 437 | if (IS_ERR(clk)) |
435 | 438 | kfree(slowck); |
439 | + else | |
440 | + slow_clk = clk; | |
436 | 441 | |
437 | 442 | return clk; |
438 | 443 | } |
... | ... | @@ -465,4 +470,26 @@ |
465 | 470 | |
466 | 471 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
467 | 472 | } |
473 | + | |
474 | +/* | |
475 | + * FIXME: All slow clk users are not properly claiming it (get + prepare + | |
476 | + * enable) before using it. | |
477 | + * If all users properly claiming this clock decide that they don't need it | |
478 | + * anymore (or are removed), it is disabled while faulty users are still | |
479 | + * requiring it, and the system hangs. | |
480 | + * Prevent this clock from being disabled until all users are properly | |
481 | + * requesting it. | |
482 | + * Once this is done we should remove this function and the slow_clk variable. | |
483 | + */ | |
484 | +static int __init of_at91_clk_slow_retain(void) | |
485 | +{ | |
486 | + if (!slow_clk) | |
487 | + return 0; | |
488 | + | |
489 | + __clk_get(slow_clk); | |
490 | + clk_prepare_enable(slow_clk); | |
491 | + | |
492 | + return 0; | |
493 | +} | |
494 | +arch_initcall(of_at91_clk_slow_retain); |
drivers/clk/berlin/bg2q.c
drivers/clk/clk-ppc-corenet.c
drivers/clk/clk.c
... | ... | @@ -1366,7 +1366,7 @@ |
1366 | 1366 | new_rate = clk->ops->determine_rate(clk->hw, rate, |
1367 | 1367 | &best_parent_rate, |
1368 | 1368 | &parent_hw); |
1369 | - parent = parent_hw->clk; | |
1369 | + parent = parent_hw ? parent_hw->clk : NULL; | |
1370 | 1370 | } else if (clk->ops->round_rate) { |
1371 | 1371 | new_rate = clk->ops->round_rate(clk->hw, rate, |
1372 | 1372 | &best_parent_rate); |
drivers/clk/rockchip/clk-cpu.c
... | ... | @@ -124,10 +124,11 @@ |
124 | 124 | { |
125 | 125 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; |
126 | 126 | unsigned long alt_prate, alt_div; |
127 | + unsigned long flags; | |
127 | 128 | |
128 | 129 | alt_prate = clk_get_rate(cpuclk->alt_parent); |
129 | 130 | |
130 | - spin_lock(cpuclk->lock); | |
131 | + spin_lock_irqsave(cpuclk->lock, flags); | |
131 | 132 | |
132 | 133 | /* |
133 | 134 | * If the old parent clock speed is less than the clock speed |
... | ... | @@ -164,7 +165,7 @@ |
164 | 165 | cpuclk->reg_base + reg_data->core_reg); |
165 | 166 | } |
166 | 167 | |
167 | - spin_unlock(cpuclk->lock); | |
168 | + spin_unlock_irqrestore(cpuclk->lock, flags); | |
168 | 169 | return 0; |
169 | 170 | } |
170 | 171 | |
... | ... | @@ -173,6 +174,7 @@ |
173 | 174 | { |
174 | 175 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; |
175 | 176 | const struct rockchip_cpuclk_rate_table *rate; |
177 | + unsigned long flags; | |
176 | 178 | |
177 | 179 | rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); |
178 | 180 | if (!rate) { |
... | ... | @@ -181,7 +183,7 @@ |
181 | 183 | return -EINVAL; |
182 | 184 | } |
183 | 185 | |
184 | - spin_lock(cpuclk->lock); | |
186 | + spin_lock_irqsave(cpuclk->lock, flags); | |
185 | 187 | |
186 | 188 | if (ndata->old_rate < ndata->new_rate) |
187 | 189 | rockchip_cpuclk_set_dividers(cpuclk, rate); |
... | ... | @@ -201,7 +203,7 @@ |
201 | 203 | if (ndata->old_rate > ndata->new_rate) |
202 | 204 | rockchip_cpuclk_set_dividers(cpuclk, rate); |
203 | 205 | |
204 | - spin_unlock(cpuclk->lock); | |
206 | + spin_unlock_irqrestore(cpuclk->lock, flags); | |
205 | 207 | return 0; |
206 | 208 | } |
207 | 209 |
drivers/clk/rockchip/clk-rk3188.c
... | ... | @@ -210,6 +210,17 @@ |
210 | 210 | PNAME(mux_mac_p) = { "gpll", "dpll" }; |
211 | 211 | PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; |
212 | 212 | |
213 | +static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = { | |
214 | + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), | |
215 | + RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates), | |
216 | + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), | |
217 | + RK2928_MODE_CON, 4, 4, 0, NULL), | |
218 | + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), | |
219 | + RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), | |
220 | + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), | |
221 | + RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), | |
222 | +}; | |
223 | + | |
213 | 224 | static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { |
214 | 225 | [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), |
215 | 226 | RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), |
216 | 227 | |
... | ... | @@ -427,11 +438,11 @@ |
427 | 438 | /* hclk_peri gates */ |
428 | 439 | GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), |
429 | 440 | GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), |
430 | - GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), | |
441 | + GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS), | |
431 | 442 | GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), |
432 | 443 | GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), |
433 | - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), | |
434 | - GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), | |
444 | + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS), | |
445 | + GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), | |
435 | 446 | GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), |
436 | 447 | GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), |
437 | 448 | GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), |
... | ... | @@ -592,7 +603,8 @@ |
592 | 603 | GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), |
593 | 604 | GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), |
594 | 605 | |
595 | - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), | |
606 | + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, | |
607 | + RK2928_CLKGATE_CON(5), 14, GFLAGS), | |
596 | 608 | |
597 | 609 | GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), |
598 | 610 | |
... | ... | @@ -680,7 +692,8 @@ |
680 | 692 | GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), |
681 | 693 | GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), |
682 | 694 | |
683 | - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), | |
695 | + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, | |
696 | + RK2928_CLKGATE_CON(7), 3, GFLAGS), | |
684 | 697 | GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), |
685 | 698 | |
686 | 699 | GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), |
... | ... | @@ -735,8 +748,8 @@ |
735 | 748 | static void __init rk3066a_clk_init(struct device_node *np) |
736 | 749 | { |
737 | 750 | rk3188_common_clk_init(np); |
738 | - rockchip_clk_register_plls(rk3188_pll_clks, | |
739 | - ARRAY_SIZE(rk3188_pll_clks), | |
751 | + rockchip_clk_register_plls(rk3066_pll_clks, | |
752 | + ARRAY_SIZE(rk3066_pll_clks), | |
740 | 753 | RK3066_GRF_SOC_STATUS); |
741 | 754 | rockchip_clk_register_branches(rk3066a_clk_branches, |
742 | 755 | ARRAY_SIZE(rk3066a_clk_branches)); |
drivers/clk/rockchip/clk-rk3288.c
... | ... | @@ -145,20 +145,20 @@ |
145 | 145 | } |
146 | 146 | |
147 | 147 | static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { |
148 | - RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), | |
149 | - RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), | |
150 | - RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), | |
151 | - RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), | |
152 | - RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), | |
153 | - RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), | |
154 | - RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), | |
155 | - RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), | |
156 | - RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), | |
157 | - RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), | |
158 | - RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), | |
159 | - RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), | |
160 | - RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), | |
161 | - RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), | |
148 | + RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3), | |
149 | + RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3), | |
150 | + RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3), | |
151 | + RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3), | |
152 | + RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3), | |
153 | + RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3), | |
154 | + RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3), | |
155 | + RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3), | |
156 | + RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3), | |
157 | + RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3), | |
158 | + RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3), | |
159 | + RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3), | |
160 | + RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3), | |
161 | + RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3), | |
162 | 162 | }; |
163 | 163 | |
164 | 164 | static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { |