void __init of_at91sam9x5_clk_main_setup(struct device_node *np, struct at91_pmc *pmc) { struct clk *clk; const char *parent_names[2]; int num_parents; unsigned int irq; const char *name = np->name; int i; num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); if (num_parents <= 0 || num_parents > 2) return; for (i = 0; i < num_parents; ++i) { parent_names[i] = of_clk_get_parent_name(np, i); if (!parent_names[i]) return; } of_property_read_string(np, "clock-output-names", &name); irq = irq_of_parse_and_map(np, 0); if (!irq) return; clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names, num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); }
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); }