aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-02-16 07:14:33 -0500
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-02-16 07:14:33 -0500
commit7a5fe2387925405da0319330986184792ce48ad1 (patch)
treef9f3c3b4a20ff52ed63d3e83bb438136aaafa5db /arch/avr32/mach-at32ap
parent160f34531a71fdbbdb593a094273711ffb1257d7 (diff)
[AVR32] Make sure all genclocks have a parent
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>
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c89
1 files changed, 73 insertions, 16 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index c1e477ec7576..a5037aa102fb 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -310,8 +310,6 @@ static void genclk_mode(struct clk *clk, int enabled)
310{ 310{
311 u32 control; 311 u32 control;
312 312
313 BUG_ON(clk->index > 7);
314
315 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 313 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
316 if (enabled) 314 if (enabled)
317 control |= SM_BIT(CEN); 315 control |= SM_BIT(CEN);
@@ -325,11 +323,6 @@ static unsigned long genclk_get_rate(struct clk *clk)
325 u32 control; 323 u32 control;
326 unsigned long div = 1; 324 unsigned long div = 1;
327 325
328 BUG_ON(clk->index > 7);
329
330 if (!clk->parent)
331 return 0;
332
333 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 326 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
334 if (control & SM_BIT(DIVEN)) 327 if (control & SM_BIT(DIVEN))
335 div = 2 * (SM_BFEXT(DIV, control) + 1); 328 div = 2 * (SM_BFEXT(DIV, control) + 1);
@@ -342,11 +335,6 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
342 u32 control; 335 u32 control;
343 unsigned long parent_rate, actual_rate, div; 336 unsigned long parent_rate, actual_rate, div;
344 337
345 BUG_ON(clk->index > 7);
346
347 if (!clk->parent)
348 return 0;
349
350 parent_rate = clk->parent->get_rate(clk->parent); 338 parent_rate = clk->parent->get_rate(clk->parent);
351 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 339 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
352 340
@@ -373,11 +361,8 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
373{ 361{
374 u32 control; 362 u32 control;
375 363
376 BUG_ON(clk->index > 7);
377
378 printk("clk %s: new parent %s (was %s)\n", 364 printk("clk %s: new parent %s (was %s)\n",
379 clk->name, parent->name, 365 clk->name, parent->name, clk->parent->name);
380 clk->parent ? clk->parent->name : "(null)");
381 366
382 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 367 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
383 368
@@ -399,6 +384,22 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
399 return 0; 384 return 0;
400} 385}
401 386
387static void __init genclk_init_parent(struct clk *clk)
388{
389 u32 control;
390 struct clk *parent;
391
392 BUG_ON(clk->index > 7);
393
394 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
395 if (control & SM_BIT(OSCSEL))
396 parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1;
397 else
398 parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0;
399
400 clk->parent = parent;
401}
402
402/* -------------------------------------------------------------------- 403/* --------------------------------------------------------------------
403 * System peripherals 404 * System peripherals
404 * -------------------------------------------------------------------- */ 405 * -------------------------------------------------------------------- */
@@ -872,6 +873,50 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
872 return pdev; 873 return pdev;
873} 874}
874 875
876/* --------------------------------------------------------------------
877 * GCLK
878 * -------------------------------------------------------------------- */
879static struct clk gclk0 = {
880 .name = "gclk0",
881 .mode = genclk_mode,
882 .get_rate = genclk_get_rate,
883 .set_rate = genclk_set_rate,
884 .set_parent = genclk_set_parent,
885 .index = 0,
886};
887static struct clk gclk1 = {
888 .name = "gclk1",
889 .mode = genclk_mode,
890 .get_rate = genclk_get_rate,
891 .set_rate = genclk_set_rate,
892 .set_parent = genclk_set_parent,
893 .index = 1,
894};
895static struct clk gclk2 = {
896 .name = "gclk2",
897 .mode = genclk_mode,
898 .get_rate = genclk_get_rate,
899 .set_rate = genclk_set_rate,
900 .set_parent = genclk_set_parent,
901 .index = 2,
902};
903static struct clk gclk3 = {
904 .name = "gclk3",
905 .mode = genclk_mode,
906 .get_rate = genclk_get_rate,
907 .set_rate = genclk_set_rate,
908 .set_parent = genclk_set_parent,
909 .index = 3,
910};
911static struct clk gclk4 = {
912 .name = "gclk4",
913 .mode = genclk_mode,
914 .get_rate = genclk_get_rate,
915 .set_rate = genclk_set_rate,
916 .set_parent = genclk_set_parent,
917 .index = 4,
918};
919
875struct clk *at32_clock_list[] = { 920struct clk *at32_clock_list[] = {
876 &osc32k, 921 &osc32k,
877 &osc0, 922 &osc0,
@@ -908,6 +953,11 @@ struct clk *at32_clock_list[] = {
908 &atmel_spi1_spi_clk, 953 &atmel_spi1_spi_clk,
909 &lcdc0_hclk, 954 &lcdc0_hclk,
910 &lcdc0_pixclk, 955 &lcdc0_pixclk,
956 &gclk0,
957 &gclk1,
958 &gclk2,
959 &gclk3,
960 &gclk4,
911}; 961};
912unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); 962unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
913 963
@@ -936,6 +986,13 @@ void __init at32_clock_init(void)
936 if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC)) 986 if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
937 pll1.parent = &osc1; 987 pll1.parent = &osc1;
938 988
989 genclk_init_parent(&gclk0);
990 genclk_init_parent(&gclk1);
991 genclk_init_parent(&gclk2);
992 genclk_init_parent(&gclk3);
993 genclk_init_parent(&gclk4);
994 genclk_init_parent(&lcdc0_pixclk);
995
939 /* 996 /*
940 * Turn on all clocks that have at least one user already, and 997 * Turn on all clocks that have at least one user already, and
941 * turn off everything else. We only do this for module 998 * turn off everything else. We only do this for module