Skip to content

Commit

Permalink
[AVR32] Make sure all genclocks have a parent
Browse files Browse the repository at this point in the history
Initialize the parent field of each generic clock by looking at the
PM registers. This means that the genclock operations can always
assume that the parent field is non-null, so they don't have to
check. Also remove a few unnecessary BUG_ON()s.

Extracted from a patch by David Brownell.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
  • Loading branch information
Haavard Skinnemoen committed Feb 16, 2007
1 parent 160f345 commit 7a5fe23
Showing 1 changed file with 73 additions and 16 deletions.
89 changes: 73 additions & 16 deletions arch/avr32/mach-at32ap/at32ap7000.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,6 @@ static void genclk_mode(struct clk *clk, int enabled)
{
u32 control;

BUG_ON(clk->index > 7);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (enabled)
control |= SM_BIT(CEN);
Expand All @@ -325,11 +323,6 @@ static unsigned long genclk_get_rate(struct clk *clk)
u32 control;
unsigned long div = 1;

BUG_ON(clk->index > 7);

if (!clk->parent)
return 0;

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (control & SM_BIT(DIVEN))
div = 2 * (SM_BFEXT(DIV, control) + 1);
Expand All @@ -342,11 +335,6 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
u32 control;
unsigned long parent_rate, actual_rate, div;

BUG_ON(clk->index > 7);

if (!clk->parent)
return 0;

parent_rate = clk->parent->get_rate(clk->parent);
control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);

Expand All @@ -373,11 +361,8 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
{
u32 control;

BUG_ON(clk->index > 7);

printk("clk %s: new parent %s (was %s)\n",
clk->name, parent->name,
clk->parent ? clk->parent->name : "(null)");
clk->name, parent->name, clk->parent->name);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);

Expand All @@ -399,6 +384,22 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
return 0;
}

static void __init genclk_init_parent(struct clk *clk)
{
u32 control;
struct clk *parent;

BUG_ON(clk->index > 7);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (control & SM_BIT(OSCSEL))
parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1;
else
parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0;

clk->parent = parent;
}

/* --------------------------------------------------------------------
* System peripherals
* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -872,6 +873,50 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
return pdev;
}

/* --------------------------------------------------------------------
* GCLK
* -------------------------------------------------------------------- */
static struct clk gclk0 = {
.name = "gclk0",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 0,
};
static struct clk gclk1 = {
.name = "gclk1",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 1,
};
static struct clk gclk2 = {
.name = "gclk2",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 2,
};
static struct clk gclk3 = {
.name = "gclk3",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 3,
};
static struct clk gclk4 = {
.name = "gclk4",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 4,
};

struct clk *at32_clock_list[] = {
&osc32k,
&osc0,
Expand Down Expand Up @@ -908,6 +953,11 @@ struct clk *at32_clock_list[] = {
&atmel_spi1_spi_clk,
&lcdc0_hclk,
&lcdc0_pixclk,
&gclk0,
&gclk1,
&gclk2,
&gclk3,
&gclk4,
};
unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);

Expand Down Expand Up @@ -936,6 +986,13 @@ void __init at32_clock_init(void)
if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
pll1.parent = &osc1;

genclk_init_parent(&gclk0);
genclk_init_parent(&gclk1);
genclk_init_parent(&gclk2);
genclk_init_parent(&gclk3);
genclk_init_parent(&gclk4);
genclk_init_parent(&lcdc0_pixclk);

/*
* Turn on all clocks that have at least one user already, and
* turn off everything else. We only do this for module
Expand Down

0 comments on commit 7a5fe23

Please sign in to comment.