Skip to content

Commit

Permalink
Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturqu…
Browse files Browse the repository at this point in the history
…ette/linux

Pull clk common framework fixes from Mike Turquette:
 "This contains three NULL pointer fixes and two device regression
  fixups.

  Two NULL pointer dereferences were in the common clk core due to lack
  of sanity checking and the third NPD was in the mxs-specific clock
  code due to incorrect use of __initdata.

  The device regressions were the result of improper data: a wrong
  string name for matching DT data broke the SPEAr ethernet controller
  and another string matching problem in the mxs clock data resulted in
  a broken MMC controller."

* tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturquette/linux:
  clk: mxs: fix clock lookup after freeing init memory
  clk: mxs: fix ref_io clock definition
  clk: Check parent for NULL in clk_change_rate
  clk: Allow late cache allocation for clk->parents
  clk: SPEAr600: Fix ethernet clock name for DT based probing
  • Loading branch information
Linus Torvalds committed Jun 27, 2012
2 parents 6b44695 + d03ac61 commit e04fb02
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
26 changes: 17 additions & 9 deletions drivers/clk/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk)
{
struct clk *child;
unsigned long old_rate;
unsigned long best_parent_rate = 0;
struct hlist_node *tmp;

old_rate = clk->rate;

if (clk->parent)
best_parent_rate = clk->parent->rate;

if (clk->ops->set_rate)
clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate);
clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);

if (clk->ops->recalc_rate)
clk->rate = clk->ops->recalc_rate(clk->hw,
clk->parent->rate);
clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate);
else
clk->rate = clk->parent->rate;
clk->rate = best_parent_rate;

if (clk->notifier_count && old_rate != clk->rate)
__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
Expand Down Expand Up @@ -999,7 +1002,7 @@ static struct clk *__clk_init_parent(struct clk *clk)

if (!clk->parents)
clk->parents =
kmalloc((sizeof(struct clk*) * clk->num_parents),
kzalloc((sizeof(struct clk*) * clk->num_parents),
GFP_KERNEL);

if (!clk->parents)
Expand Down Expand Up @@ -1065,9 +1068,13 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
old_parent = clk->parent;

/* find index of new parent clock using cached parent ptrs */
for (i = 0; i < clk->num_parents; i++)
if (clk->parents[i] == parent)
break;
if (clk->parents)
for (i = 0; i < clk->num_parents; i++)
if (clk->parents[i] == parent)
break;
else
clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
GFP_KERNEL);

/*
* find index of new parent clock using string name comparison
Expand All @@ -1076,7 +1083,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
if (i == clk->num_parents)
for (i = 0; i < clk->num_parents; i++)
if (!strcmp(clk->parent_names[i], parent->name)) {
clk->parents[i] = __clk_lookup(parent->name);
if (clk->parents)
clk->parents[i] = __clk_lookup(parent->name);
break;
}

Expand Down
12 changes: 6 additions & 6 deletions drivers/clk/mxs/clk-imx23.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static void __init clk_misc_init(void)
__mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
}

static struct clk_lookup uart_lookups[] __initdata = {
static struct clk_lookup uart_lookups[] = {
{ .dev_id = "duart", },
{ .dev_id = "mxs-auart.0", },
{ .dev_id = "mxs-auart.1", },
Expand All @@ -80,31 +80,31 @@ static struct clk_lookup uart_lookups[] __initdata = {
{ .dev_id = "80070000.serial", },
};

static struct clk_lookup hbus_lookups[] __initdata = {
static struct clk_lookup hbus_lookups[] = {
{ .dev_id = "imx23-dma-apbh", },
{ .dev_id = "80004000.dma-apbh", },
};

static struct clk_lookup xbus_lookups[] __initdata = {
static struct clk_lookup xbus_lookups[] = {
{ .dev_id = "duart", .con_id = "apb_pclk"},
{ .dev_id = "80070000.serial", .con_id = "apb_pclk"},
{ .dev_id = "imx23-dma-apbx", },
{ .dev_id = "80024000.dma-apbx", },
};

static struct clk_lookup ssp_lookups[] __initdata = {
static struct clk_lookup ssp_lookups[] = {
{ .dev_id = "imx23-mmc.0", },
{ .dev_id = "imx23-mmc.1", },
{ .dev_id = "80010000.ssp", },
{ .dev_id = "80034000.ssp", },
};

static struct clk_lookup lcdif_lookups[] __initdata = {
static struct clk_lookup lcdif_lookups[] = {
{ .dev_id = "imx23-fb", },
{ .dev_id = "80030000.lcdif", },
};

static struct clk_lookup gpmi_lookups[] __initdata = {
static struct clk_lookup gpmi_lookups[] = {
{ .dev_id = "imx23-gpmi-nand", },
{ .dev_id = "8000c000.gpmi", },
};
Expand Down
32 changes: 16 additions & 16 deletions drivers/clk/mxs/clk-imx28.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static void __init clk_misc_init(void)
writel_relaxed(val, FRAC0);
}

static struct clk_lookup uart_lookups[] __initdata = {
static struct clk_lookup uart_lookups[] = {
{ .dev_id = "duart", },
{ .dev_id = "mxs-auart.0", },
{ .dev_id = "mxs-auart.1", },
Expand All @@ -135,71 +135,71 @@ static struct clk_lookup uart_lookups[] __initdata = {
{ .dev_id = "80074000.serial", },
};

static struct clk_lookup hbus_lookups[] __initdata = {
static struct clk_lookup hbus_lookups[] = {
{ .dev_id = "imx28-dma-apbh", },
{ .dev_id = "80004000.dma-apbh", },
};

static struct clk_lookup xbus_lookups[] __initdata = {
static struct clk_lookup xbus_lookups[] = {
{ .dev_id = "duart", .con_id = "apb_pclk"},
{ .dev_id = "80074000.serial", .con_id = "apb_pclk"},
{ .dev_id = "imx28-dma-apbx", },
{ .dev_id = "80024000.dma-apbx", },
};

static struct clk_lookup ssp0_lookups[] __initdata = {
static struct clk_lookup ssp0_lookups[] = {
{ .dev_id = "imx28-mmc.0", },
{ .dev_id = "80010000.ssp", },
};

static struct clk_lookup ssp1_lookups[] __initdata = {
static struct clk_lookup ssp1_lookups[] = {
{ .dev_id = "imx28-mmc.1", },
{ .dev_id = "80012000.ssp", },
};

static struct clk_lookup ssp2_lookups[] __initdata = {
static struct clk_lookup ssp2_lookups[] = {
{ .dev_id = "imx28-mmc.2", },
{ .dev_id = "80014000.ssp", },
};

static struct clk_lookup ssp3_lookups[] __initdata = {
static struct clk_lookup ssp3_lookups[] = {
{ .dev_id = "imx28-mmc.3", },
{ .dev_id = "80016000.ssp", },
};

static struct clk_lookup lcdif_lookups[] __initdata = {
static struct clk_lookup lcdif_lookups[] = {
{ .dev_id = "imx28-fb", },
{ .dev_id = "80030000.lcdif", },
};

static struct clk_lookup gpmi_lookups[] __initdata = {
static struct clk_lookup gpmi_lookups[] = {
{ .dev_id = "imx28-gpmi-nand", },
{ .dev_id = "8000c000.gpmi", },
};

static struct clk_lookup fec_lookups[] __initdata = {
static struct clk_lookup fec_lookups[] = {
{ .dev_id = "imx28-fec.0", },
{ .dev_id = "imx28-fec.1", },
{ .dev_id = "800f0000.ethernet", },
{ .dev_id = "800f4000.ethernet", },
};

static struct clk_lookup can0_lookups[] __initdata = {
static struct clk_lookup can0_lookups[] = {
{ .dev_id = "flexcan.0", },
{ .dev_id = "80032000.can", },
};

static struct clk_lookup can1_lookups[] __initdata = {
static struct clk_lookup can1_lookups[] = {
{ .dev_id = "flexcan.1", },
{ .dev_id = "80034000.can", },
};

static struct clk_lookup saif0_lookups[] __initdata = {
static struct clk_lookup saif0_lookups[] = {
{ .dev_id = "mxs-saif.0", },
{ .dev_id = "80042000.saif", },
};

static struct clk_lookup saif1_lookups[] __initdata = {
static struct clk_lookup saif1_lookups[] = {
{ .dev_id = "mxs-saif.1", },
{ .dev_id = "80046000.saif", },
};
Expand Down Expand Up @@ -245,8 +245,8 @@ int __init mx28_clocks_init(void)
clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2);
clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3);
clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2);
clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3);
clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
Expand Down
2 changes: 1 addition & 1 deletion drivers/clk/spear/spear6xx_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void __init spear6xx_clk_init(void)

clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
GMAC_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "gmac");
clk_register_clkdev(clk, NULL, "e0800000.ethernet");

clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
I2C_CLK_ENB, 0, &_lock);
Expand Down

0 comments on commit e04fb02

Please sign in to comment.