static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); ret = gdsc_toggle_logic(sc, true); if (ret) return ret; if (sc->pwrsts & PWRSTS_OFF) gdsc_force_mem_on(sc); /* * If clocks to this power domain were already on, they will take an * additional 4 clock cycles to re-enable after the power domain is * enabled. Delay to account for this. A delay is also needed to ensure * clocks are not enabled within 400ns of enabling power to the * memories. */ udelay(1); return 0; }
static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev) { int ret, i = 0, j = 0; struct gdsc *sc = domain_to_gdsc(domain); struct of_phandle_args clkspec; struct device_node *np = dev->of_node; if (!sc->clock_count) return 0; ret = pm_clk_create(dev); if (ret) { dev_dbg(dev, "pm_clk_create failed %d\n", ret); return ret; } sc->clks = devm_kcalloc(dev, sc->clock_count, sizeof(sc->clks), GFP_KERNEL); if (!sc->clks) return -ENOMEM; while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec)) { if (match(clkspec.args[0], sc->clocks, sc->clock_count)) { sc->clks[j] = of_clk_get_from_provider(&clkspec); pm_clk_add_clk(dev, sc->clks[j]); j++; } else if (clkspec.args[0] == sc->root_clock) sc->root_clk = of_clk_get_from_provider(&clkspec); i++; } return 0; };
static void gdsc_detach(struct generic_pm_domain *domain, struct device *dev) { struct gdsc *sc = domain_to_gdsc(domain); if (!sc->clock_count) return; pm_clk_destroy(dev); };
static int gdsc_disable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); if (sc->pwrsts & PWRSTS_OFF) gdsc_clear_mem_on(sc); return gdsc_toggle_logic(sc, false); }