@@ -144,6 +144,7 @@ struct rzg2l_pll5_mux_dsi_div_param {
* @num_resets: Number of Module Resets in info->resets[]
* @last_dt_core_clk: ID of the last Core Clock exported to DT
* @info: Pointer to platform data
+ * @genpd: PM domain
* @mux_dsi_div_params: pll5 mux and dsi div parameters
*/
struct rzg2l_cpg_priv {
@@ -160,6 +161,8 @@ struct rzg2l_cpg_priv {
const struct rzg2l_cpg_info *info;
+ struct generic_pm_domain genpd;
+
struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params;
};
@@ -1797,39 +1800,14 @@ static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
return devm_reset_controller_register(priv->dev, &priv->rcdev);
}
-/**
- * struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure
- * @onecell_data: cell data
- * @domains: generic PM domains
- */
-struct rzg2l_cpg_pm_domains {
- struct genpd_onecell_data onecell_data;
- struct generic_pm_domain *domains[];
-};
-
-/**
- * struct rzg2l_cpg_pd - RZ/G2L power domain data structure
- * @genpd: generic PM domain
- * @priv: pointer to CPG private data structure
- * @conf: CPG PM domain configuration info
- * @id: RZ/G2L power domain ID
- */
-struct rzg2l_cpg_pd {
- struct generic_pm_domain genpd;
- struct rzg2l_cpg_priv *priv;
- struct rzg2l_cpg_pm_domain_conf conf;
- u16 id;
-};
-
-static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_pd *pd,
+static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_priv *priv,
const struct of_phandle_args *clkspec)
{
- if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2)
+ if (clkspec->np != priv->genpd.dev.of_node || clkspec->args_count != 2)
return false;
switch (clkspec->args[0]) {
case CPG_MOD: {
- struct rzg2l_cpg_priv *priv = pd->priv;
const struct rzg2l_cpg_info *info = priv->info;
unsigned int id = clkspec->args[1];
@@ -1854,7 +1832,7 @@ static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_pd *pd,
static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device *dev)
{
- struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
+ struct rzg2l_cpg_priv *priv = container_of(domain, struct rzg2l_cpg_priv, genpd);
struct device_node *np = dev->of_node;
struct of_phandle_args clkspec;
bool once = true;
@@ -1863,7 +1841,7 @@ static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device
int error;
for (i = 0; !of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec); i++) {
- if (!rzg2l_cpg_is_pm_clk(pd, &clkspec)) {
+ if (!rzg2l_cpg_is_pm_clk(priv, &clkspec)) {
of_node_put(clkspec.np);
continue;
}
@@ -1908,183 +1886,31 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device
}
static void rzg2l_cpg_genpd_remove(void *data)
-{
- struct genpd_onecell_data *celldata = data;
-
- for (unsigned int i = 0; i < celldata->num_domains; i++)
- pm_genpd_remove(celldata->domains[i]);
-}
-
-static void rzg2l_cpg_genpd_remove_simple(void *data)
{
pm_genpd_remove(data);
}
-static int rzg2l_cpg_power_on(struct generic_pm_domain *domain)
-{
- struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
- struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;
- struct rzg2l_cpg_priv *priv = pd->priv;
-
- /* Set MSTOP. */
- if (mstop.mask)
- writel(mstop.mask << 16, priv->base + mstop.off);
-
- return 0;
-}
-
-static int rzg2l_cpg_power_off(struct generic_pm_domain *domain)
-{
- struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
- struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;
- struct rzg2l_cpg_priv *priv = pd->priv;
-
- /* Set MSTOP. */
- if (mstop.mask)
- writel(mstop.mask | (mstop.mask << 16), priv->base + mstop.off);
-
- return 0;
-}
-
-static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd)
-{
- bool always_on = !!(pd->genpd.flags & GENPD_FLAG_ALWAYS_ON);
- struct dev_power_governor *governor;
- int ret;
-
- if (always_on)
- governor = &pm_domain_always_on_gov;
- else
- governor = &simple_qos_governor;
-
- pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
- pd->genpd.attach_dev = rzg2l_cpg_attach_dev;
- pd->genpd.detach_dev = rzg2l_cpg_detach_dev;
- pd->genpd.power_on = rzg2l_cpg_power_on;
- pd->genpd.power_off = rzg2l_cpg_power_off;
-
- ret = pm_genpd_init(&pd->genpd, governor, !always_on);
- if (ret)
- return ret;
-
- if (always_on)
- ret = rzg2l_cpg_power_on(&pd->genpd);
-
- return ret;
-}
-
static int __init rzg2l_cpg_add_clk_domain(struct rzg2l_cpg_priv *priv)
{
struct device *dev = priv->dev;
struct device_node *np = dev->of_node;
- struct rzg2l_cpg_pd *pd;
+ struct generic_pm_domain *genpd = &priv->genpd;
int ret;
- pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
- if (!pd)
- return -ENOMEM;
-
- pd->genpd.name = np->name;
- pd->genpd.flags = GENPD_FLAG_ALWAYS_ON;
- pd->priv = priv;
- ret = rzg2l_cpg_pd_setup(pd);
+ genpd->name = np->name;
+ genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+ GENPD_FLAG_ACTIVE_WAKEUP;
+ genpd->attach_dev = rzg2l_cpg_attach_dev;
+ genpd->detach_dev = rzg2l_cpg_detach_dev;
+ ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
if (ret)
return ret;
- ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove_simple, &pd->genpd);
+ ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd);
if (ret)
return ret;
- return of_genpd_add_provider_simple(np, &pd->genpd);
-}
-
-static struct generic_pm_domain *
-rzg2l_cpg_pm_domain_xlate(const struct of_phandle_args *spec, void *data)
-{
- struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
- struct genpd_onecell_data *genpd = data;
-
- if (spec->args_count != 1)
- return ERR_PTR(-EINVAL);
-
- for (unsigned int i = 0; i < genpd->num_domains; i++) {
- struct rzg2l_cpg_pd *pd = container_of(genpd->domains[i], struct rzg2l_cpg_pd,
- genpd);
-
- if (pd->id == spec->args[0]) {
- domain = &pd->genpd;
- break;
- }
- }
-
- return domain;
-}
-
-static int __init rzg2l_cpg_add_pm_domains(struct rzg2l_cpg_priv *priv)
-{
- const struct rzg2l_cpg_info *info = priv->info;
- struct device *dev = priv->dev;
- struct device_node *np = dev->of_node;
- struct rzg2l_cpg_pm_domains *domains;
- struct generic_pm_domain *parent;
- u32 ncells;
- int ret;
-
- ret = of_property_read_u32(np, "#power-domain-cells", &ncells);
- if (ret)
- return ret;
-
- /* For backward compatibility. */
- if (!ncells)
- return rzg2l_cpg_add_clk_domain(priv);
-
- domains = devm_kzalloc(dev, struct_size(domains, domains, info->num_pm_domains),
- GFP_KERNEL);
- if (!domains)
- return -ENOMEM;
-
- domains->onecell_data.domains = domains->domains;
- domains->onecell_data.num_domains = info->num_pm_domains;
- domains->onecell_data.xlate = rzg2l_cpg_pm_domain_xlate;
-
- ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, &domains->onecell_data);
- if (ret)
- return ret;
-
- for (unsigned int i = 0; i < info->num_pm_domains; i++) {
- struct rzg2l_cpg_pd *pd;
-
- pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
- if (!pd)
- return -ENOMEM;
-
- pd->genpd.name = info->pm_domains[i].name;
- pd->genpd.flags = info->pm_domains[i].genpd_flags;
- pd->conf = info->pm_domains[i].conf;
- pd->id = info->pm_domains[i].id;
- pd->priv = priv;
-
- ret = rzg2l_cpg_pd_setup(pd);
- if (ret)
- return ret;
-
- domains->domains[i] = &pd->genpd;
- /* Parent should be on the very first entry of info->pm_domains[]. */
- if (!i) {
- parent = &pd->genpd;
- continue;
- }
-
- ret = pm_genpd_add_subdomain(parent, &pd->genpd);
- if (ret)
- return ret;
- }
-
- ret = of_genpd_add_provider_onecell(np, &domains->onecell_data);
- if (ret)
- return ret;
-
- return 0;
+ return of_genpd_add_provider_simple(np, genpd);
}
static int __init rzg2l_cpg_probe(struct platform_device *pdev)
@@ -2147,7 +1973,7 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
if (error)
return error;
- error = rzg2l_cpg_add_pm_domains(priv);
+ error = rzg2l_cpg_add_clk_domain(priv);
if (error)
return error;
@@ -259,51 +259,6 @@ struct rzg2l_reset {
#define DEF_RST(_id, _off, _bit) \
DEF_RST_MON(_id, _off, _bit, -1)
-/**
- * struct rzg2l_cpg_reg_conf - RZ/G2L register configuration data structure
- * @off: register offset
- * @mask: register mask
- */
-struct rzg2l_cpg_reg_conf {
- u16 off;
- u16 mask;
-};
-
-#define DEF_REG_CONF(_off, _mask) ((struct rzg2l_cpg_reg_conf) { .off = (_off), .mask = (_mask) })
-
-/**
- * struct rzg2l_cpg_pm_domain_conf - PM domain configuration data structure
- * @mstop: MSTOP register configuration
- */
-struct rzg2l_cpg_pm_domain_conf {
- struct rzg2l_cpg_reg_conf mstop;
-};
-
-/**
- * struct rzg2l_cpg_pm_domain_init_data - PM domain init data
- * @name: PM domain name
- * @conf: PM domain configuration
- * @genpd_flags: genpd flags (see GENPD_FLAG_*)
- * @id: PM domain ID (similar to the ones defined in
- * include/dt-bindings/clock/<soc-id>-cpg.h)
- */
-struct rzg2l_cpg_pm_domain_init_data {
- const char * const name;
- struct rzg2l_cpg_pm_domain_conf conf;
- u32 genpd_flags;
- u16 id;
-};
-
-#define DEF_PD(_name, _id, _mstop_conf, _flags) \
- { \
- .name = (_name), \
- .id = (_id), \
- .conf = { \
- .mstop = (_mstop_conf), \
- }, \
- .genpd_flags = (_flags), \
- }
-
/**
* struct rzg2l_cpg_info - SoC-specific CPG Description
*
@@ -322,8 +277,6 @@ struct rzg2l_cpg_pm_domain_init_data {
* @crit_mod_clks: Array with Module Clock IDs of critical clocks that
* should not be disabled without a knowledgeable driver
* @num_crit_mod_clks: Number of entries in crit_mod_clks[]
- * @pm_domains: PM domains init data array
- * @num_pm_domains: Number of PM domains
* @has_clk_mon_regs: Flag indicating whether the SoC has CLK_MON registers
*/
struct rzg2l_cpg_info {
@@ -350,10 +303,6 @@ struct rzg2l_cpg_info {
const unsigned int *crit_mod_clks;
unsigned int num_crit_mod_clks;
- /* Power domain. */
- const struct rzg2l_cpg_pm_domain_init_data *pm_domains;
- unsigned int num_pm_domains;
-
bool has_clk_mon_regs;
};