static void __init of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) { int num; int irq = 0; u32 id; struct clk *clk; const char *name; struct device_node *sysclknp; const char *parent_name; num = of_get_child_count(np); if (num > (SYSTEM_MAX_ID + 1)) return; for_each_child_of_node(np, sysclknp) { if (of_property_read_u32(sysclknp, "reg", &id)) continue; if (of_property_read_string(np, "clock-output-names", &name)) name = sysclknp->name; if (is_pck(id)) irq = irq_of_parse_and_map(sysclknp, 0); parent_name = of_clk_get_parent_name(sysclknp, 0); clk = at91_clk_register_system(pmc, name, parent_name, id, irq); if (IS_ERR(clk)) continue; of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); } }
static void __init at91sam9rl_pmc_setup(struct device_node *np) { const char *slck_name, *mainxtal_name; struct pmc_data *at91sam9rl_pmc; const char *parent_names[6]; struct regmap *regmap; struct clk_hw *hw; int i; i = of_property_match_string(np, "clock-names", "slow_clk"); if (i < 0) return; slck_name = of_clk_get_parent_name(np, i); i = of_property_match_string(np, "clock-names", "main_xtal"); if (i < 0) return; mainxtal_name = of_clk_get_parent_name(np, i); regmap = syscon_node_to_regmap(np); if (IS_ERR(regmap)) return; at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1, nck(at91sam9rl_systemck), nck(at91sam9rl_periphck), 0); if (!at91sam9rl_pmc) return; hw = at91_clk_register_rm9200_main(regmap, "mainck", mainxtal_name); if (IS_ERR(hw)) goto err_free; at91sam9rl_pmc->chws[PMC_MAIN] = hw; hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, &at91rm9200_pll_layout, &sam9rl_plla_characteristics); if (IS_ERR(hw)) goto err_free; hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck"); if (IS_ERR(hw)) goto err_free; at91sam9rl_pmc->chws[PMC_UTMI] = hw; parent_names[0] = slck_name; parent_names[1] = "mainck"; parent_names[2] = "pllack"; parent_names[3] = "utmick"; hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, &at91rm9200_master_layout, &sam9rl_mck_characteristics); if (IS_ERR(hw)) goto err_free; at91sam9rl_pmc->chws[PMC_MCK] = hw; parent_names[0] = slck_name; parent_names[1] = "mainck"; parent_names[2] = "pllack"; parent_names[3] = "utmick"; parent_names[4] = "masterck"; for (i = 0; i < 2; i++) { char name[6]; snprintf(name, sizeof(name), "prog%d", i); hw = at91_clk_register_programmable(regmap, name, parent_names, 5, i, &at91rm9200_programmable_layout); if (IS_ERR(hw)) goto err_free; } for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) { hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n, at91sam9rl_systemck[i].p, at91sam9rl_systemck[i].id); if (IS_ERR(hw)) goto err_free; at91sam9rl_pmc->shws[at91sam9rl_systemck[i].id] = hw; } for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) { hw = at91_clk_register_peripheral(regmap, at91sam9rl_periphck[i].n, "masterck", at91sam9rl_periphck[i].id); if (IS_ERR(hw)) goto err_free; at91sam9rl_pmc->phws[at91sam9rl_periphck[i].id] = hw; } of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9rl_pmc); return; err_free: pmc_data_free(at91sam9rl_pmc); }
static void __init sama5d4_pmc_setup(struct device_node *np) { struct clk_range range = CLK_RANGE(0, 0); const char *slck_name, *mainxtal_name; struct pmc_data *sama5d4_pmc; const char *parent_names[5]; struct regmap *regmap; struct clk *hw; int i; bool bypass; i = of_property_match_string(np, "clock-names", "slow_clk"); if (i < 0) return; slck_name = of_clk_get_parent_name(np, i); i = of_property_match_string(np, "clock-names", "main_xtal"); if (i < 0) return; mainxtal_name = of_clk_get_parent_name(np, i); regmap = syscon_node_to_regmap(np); if (IS_ERR(regmap)) return; sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1, nck(sama5d4_systemck), nck(sama5d4_periph32ck), 0); if (!sama5d4_pmc) return; hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, 100000000); if (IS_ERR(hw)) goto err_free; bypass = of_property_read_bool(np, "atmel,osc-bypass"); hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, bypass); if (IS_ERR(hw)) goto err_free; parent_names[0] = "main_rc_osc"; parent_names[1] = "main_osc"; hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2); if (IS_ERR(hw)) goto err_free; hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, &sama5d3_pll_layout, &plla_characteristics); if (IS_ERR(hw)) goto err_free; hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack"); if (IS_ERR(hw)) goto err_free; hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck"); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->chws[PMC_UTMI] = hw; parent_names[0] = slck_name; parent_names[1] = "mainck"; parent_names[2] = "plladivck"; parent_names[3] = "utmick"; hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, &at91sam9x5_master_layout, &mck_characteristics); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->chws[PMC_MCK] = hw; hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck"); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->chws[PMC_MCK2] = hw; parent_names[0] = "plladivck"; parent_names[1] = "utmick"; hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2); if (IS_ERR(hw)) goto err_free; parent_names[0] = "plladivck"; parent_names[1] = "utmick"; hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2); if (IS_ERR(hw)) goto err_free; parent_names[0] = slck_name; parent_names[1] = "mainck"; parent_names[2] = "plladivck"; parent_names[3] = "utmick"; parent_names[4] = "mck"; for (i = 0; i < 3; i++) { char *name; name = xasprintf("prog%d", i); hw = at91_clk_register_programmable(regmap, name, parent_names, 5, i, &at91sam9x5_programmable_layout); if (IS_ERR(hw)) goto err_free; } for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) { hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n, sama5d4_systemck[i].p, sama5d4_systemck[i].id); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->shws[sama5d4_systemck[i].id] = hw; } for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, sama5d4_periphck[i].n, "masterck", sama5d4_periphck[i].id, &range); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->phws[sama5d4_periphck[i].id] = hw; } for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, sama5d4_periph32ck[i].n, "h32mxck", sama5d4_periph32ck[i].id, &range); if (IS_ERR(hw)) goto err_free; sama5d4_pmc->phws[sama5d4_periph32ck[i].id] = hw; } of_clk_add_provider(np, of_clk_hw_pmc_get, sama5d4_pmc); return; err_free: pmc_data_free(sama5d4_pmc); }