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).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUuuT0AAoJEDqPOy9afJhJTCIP/iZ2AtnG/5mbYR8i7FzfSR8y
 gm+vpTvKAhIkWxj1DNUMtSTRBvfxO8xpnsXJ4BibIhmtO8yJbYI8LIEycIJ4TcWC
 4s0MDQsaMGVEfSI8K+OoFsXI+WzU1j28le2yYE6oHVuLe7gdLnpx6sheNdnL0XxX
 sv8HoI/pTFpw0jI20EZUcX/pEELGWlAZN9NCpW74cbVl/wusvV20CYG5n879Sg8n
 Zl26wXusys83+0mFgs6+Kvpeuxo78XXveTSvB+aJ5VEWDfm10kE5bqyo6iOL0rpI
 luGIMf6Uufq6+1Hzp8whgE59FOvugNjay3OR+pz7P+gWk1Ea5c9qXpBtg3gEtjF9
 JoMpjPSXAnGgjhJsuZhO4+z23OhpB+FcuC1x6EcL0i6iqpzbNpJTYa8eNMOOt8FR
 h3YCzr32IHZ6a2YutCuEdof8d9GZ5I2r8G9p8ezv7CJEBHIrLVTyu3xELwN9Ijuj
 p83716w0NU2avN2N6nF2sAF26UJhG/GbmQWkOSnj2cmeDI5xxnClJD/3etgtIaIj
 RA/WLVfUscszR52IZ2V56KKTrRJkNz04Zsx803yNZKXkNIrJ+I04xBAvQETKk24f
 fImY65mkJWC8iAErEKHYZi8WxdHAu5xRYwL34HvIfpDAsHvqHNZBltYTee6HuM2k
 wbD42D8XsOoBfZwg07RF
 =B+t3
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2015-01-18 15:29:11 +12:00
commit 12ba8571ab
7 changed files with 69 additions and 28 deletions

View File

@ -70,6 +70,7 @@ struct clk_sam9x5_slow {
#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
static struct clk *slow_clk;
static int clk_slow_osc_prepare(struct clk_hw *hw) static int clk_slow_osc_prepare(struct clk_hw *hw)
{ {
@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
clk = clk_register(NULL, &slowck->hw); clk = clk_register(NULL, &slowck->hw);
if (IS_ERR(clk)) if (IS_ERR(clk))
kfree(slowck); kfree(slowck);
else
slow_clk = clk;
return clk; return clk;
} }
@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
clk = clk_register(NULL, &slowck->hw); clk = clk_register(NULL, &slowck->hw);
if (IS_ERR(clk)) if (IS_ERR(clk))
kfree(slowck); kfree(slowck);
else
slow_clk = clk;
return clk; return clk;
} }
@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
of_clk_add_provider(np, of_clk_src_simple_get, clk); of_clk_add_provider(np, of_clk_src_simple_get, clk);
} }
/*
* FIXME: All slow clk users are not properly claiming it (get + prepare +
* enable) before using it.
* If all users properly claiming this clock decide that they don't need it
* anymore (or are removed), it is disabled while faulty users are still
* requiring it, and the system hangs.
* Prevent this clock from being disabled until all users are properly
* requesting it.
* Once this is done we should remove this function and the slow_clk variable.
*/
static int __init of_at91_clk_slow_retain(void)
{
if (!slow_clk)
return 0;
__clk_get(slow_clk);
clk_prepare_enable(slow_clk);
return 0;
}
arch_initcall(of_at91_clk_slow_retain);

View File

@ -285,7 +285,6 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = {
{ "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, { "pbridge", "perif", 15, CLK_IGNORE_UNUSED },
{ "sdio", "perif", 16, CLK_IGNORE_UNUSED }, { "sdio", "perif", 16, CLK_IGNORE_UNUSED },
{ "nfc", "perif", 18 }, { "nfc", "perif", 18 },
{ "smemc", "perif", 19 },
{ "pcie", "perif", 22 }, { "pcie", "perif", 22 },
}; };

View File

@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = {
{} {}
}; };
static struct platform_driver ppc_corenet_clk_driver __initdata = { static struct platform_driver ppc_corenet_clk_driver = {
.driver = { .driver = {
.name = "ppc_corenet_clock", .name = "ppc_corenet_clock",
.of_match_table = ppc_clk_ids, .of_match_table = ppc_clk_ids,

View File

@ -1366,7 +1366,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
new_rate = clk->ops->determine_rate(clk->hw, rate, new_rate = clk->ops->determine_rate(clk->hw, rate,
&best_parent_rate, &best_parent_rate,
&parent_hw); &parent_hw);
parent = parent_hw->clk; parent = parent_hw ? parent_hw->clk : 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);

View File

@ -124,10 +124,11 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
{ {
const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
unsigned long alt_prate, alt_div; unsigned long alt_prate, alt_div;
unsigned long flags;
alt_prate = clk_get_rate(cpuclk->alt_parent); alt_prate = clk_get_rate(cpuclk->alt_parent);
spin_lock(cpuclk->lock); spin_lock_irqsave(cpuclk->lock, flags);
/* /*
* If the old parent clock speed is less than the clock speed * If the old parent clock speed is less than the clock speed
@ -164,7 +165,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
cpuclk->reg_base + reg_data->core_reg); cpuclk->reg_base + reg_data->core_reg);
} }
spin_unlock(cpuclk->lock); spin_unlock_irqrestore(cpuclk->lock, flags);
return 0; return 0;
} }
@ -173,6 +174,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
{ {
const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
const struct rockchip_cpuclk_rate_table *rate; const struct rockchip_cpuclk_rate_table *rate;
unsigned long flags;
rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
if (!rate) { if (!rate) {
@ -181,7 +183,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
return -EINVAL; return -EINVAL;
} }
spin_lock(cpuclk->lock); spin_lock_irqsave(cpuclk->lock, flags);
if (ndata->old_rate < ndata->new_rate) if (ndata->old_rate < ndata->new_rate)
rockchip_cpuclk_set_dividers(cpuclk, rate); rockchip_cpuclk_set_dividers(cpuclk, rate);
@ -201,7 +203,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
if (ndata->old_rate > ndata->new_rate) if (ndata->old_rate > ndata->new_rate)
rockchip_cpuclk_set_dividers(cpuclk, rate); rockchip_cpuclk_set_dividers(cpuclk, rate);
spin_unlock(cpuclk->lock); spin_unlock_irqrestore(cpuclk->lock, flags);
return 0; return 0;
} }

View File

@ -210,6 +210,17 @@ PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" };
PNAME(mux_mac_p) = { "gpll", "dpll" }; PNAME(mux_mac_p) = { "gpll", "dpll" };
PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" };
static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = {
[apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates),
[dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
RK2928_MODE_CON, 4, 4, 0, NULL),
[cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8),
RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
[gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
};
static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
[apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates),
@ -427,11 +438,11 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
/* hclk_peri gates */ /* hclk_peri gates */
GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS),
GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS),
GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS),
GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS),
GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS),
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
@ -592,7 +603,8 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(5), 14, GFLAGS),
GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
@ -680,7 +692,8 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(7), 3, GFLAGS),
GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
@ -735,8 +748,8 @@ static void __init rk3188_common_clk_init(struct device_node *np)
static void __init rk3066a_clk_init(struct device_node *np) static void __init rk3066a_clk_init(struct device_node *np)
{ {
rk3188_common_clk_init(np); rk3188_common_clk_init(np);
rockchip_clk_register_plls(rk3188_pll_clks, rockchip_clk_register_plls(rk3066_pll_clks,
ARRAY_SIZE(rk3188_pll_clks), ARRAY_SIZE(rk3066_pll_clks),
RK3066_GRF_SOC_STATUS); RK3066_GRF_SOC_STATUS);
rockchip_clk_register_branches(rk3066a_clk_branches, rockchip_clk_register_branches(rk3066a_clk_branches,
ARRAY_SIZE(rk3066a_clk_branches)); ARRAY_SIZE(rk3066a_clk_branches));

View File

@ -145,20 +145,20 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = {
} }
static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3),
}; };
static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {