Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12ba8571 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 901b2082 c7662fc5
Loading
Loading
Loading
Loading
+27 −0
Original line number Original line Diff line number Diff line
@@ -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);
+0 −1
Original line number Original line Diff line number Diff line
@@ -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 },
};
};


+1 −1
Original line number Original line Diff line number Diff line
@@ -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,
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+6 −4
Original line number Original line Diff line number Diff line
@@ -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;
}
}


Loading