static int system_clk_enable(struct clk *clk) { struct pmc_platdata *plat = dev_get_platdata(clk->dev); struct at91_pmc *pmc = plat->reg_base; u32 mask; if (clk->id > SYSTEM_MAX_ID) return -EINVAL; mask = BIT(clk->id); writel(mask, &pmc->scer); /** * For the programmable clocks the Ready status in the PMC * status register should be checked after enabling. * For other clocks this is unnecessary. */ if (!is_pck(clk->id)) return 0; while (!(readl(&pmc->sr) & mask)) ; return 0; }
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 int clk_system_is_prepared(struct clk_hw *hw) { struct clk_system *sys = to_clk_system(hw); struct at91_pmc *pmc = sys->pmc; if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id))) return 0; if (!is_pck(sys->id)) return 1; return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id)); }
static int clk_system_prepare(struct clk_hw *hw) { struct clk_system *sys = to_clk_system(hw); struct at91_pmc *pmc = sys->pmc; u32 mask = 1 << sys->id; pmc_write(pmc, AT91_PMC_SCER, mask); if (!is_pck(sys->id)) return 0; while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { if (sys->irq) { enable_irq(sys->irq); wait_event(sys->wait, pmc_read(pmc, AT91_PMC_SR) & mask); } else cpu_relax(); } return 0; }