Thread (19 messages) 19 messages, 3 authors, 2018-11-01
STALE2774d
Revisions (7)
  1. v8 [diff vs current]
  2. v8 current
  3. v8 [diff vs current]
  4. v8 [diff vs current]
  5. v8 [diff vs current]
  6. v9 [diff vs current]
  7. v9 [diff vs current]

[PATCH V8 5/5] firmware: imx: add SCU power domain driver

From: Ulf Hansson <hidden>
Date: 2018-10-29 11:43:19
Also in: linux-pm

[...]

}
+
+static struct imx_sc_pm_domain *
+imx_scu_add_pm_domain(struct device *dev, int idx,
+                     const struct imx_sc_pd_range *pd_ranges)
+{
+       struct imx_sc_pm_domain *sc_pd;
+       int ret;
+
+       sc_pd = devm_kzalloc(dev, sizeof(*sc_pd), GFP_KERNEL);
+       if (!sc_pd)
+               return ERR_PTR(-ENOMEM);
+
+       sc_pd->rsrc = pd_ranges->rsrc + idx;
+       sc_pd->pd.power_off = imx_sc_pd_power_off;
+       sc_pd->pd.power_on = imx_sc_pd_power_on;
So, this means you are going to register one genpd per device (one for
each uart, pwm etc), but there is actually a better option.

What you seems to be needing is a way to "power on/off" devices,
rather than the PM domain. Right? The PM domain, is managed internally
by the FW, no?

In any case, it looks like what you should do is to implement the
->attach|detach_dev() callback for the genpd and use the regular
of_genpd_add_provider_simple(). From within the ->attach_dev(), you
should get the OF node for the device that is being attached and then
parse the power-domain cell containing the "resource id" and store
that in the per device struct generic_pm_domain_data (we have void
pointer there for storing these kind of things).

Additionally, you need to implement the ->stop() and ->start()
callbacks of genpd, which is where you "power on/off" devices, rather
than using the above ->power_on|off() callbacks.

Please have a look a drivers/soc/ti/ti_sci_pm_domains.c. Apologize, I
should have pointed you towards that reference already in the earlier
version.
+
+       if (pd_ranges->postfix)
+               snprintf(sc_pd->name, sizeof(sc_pd->name),
+                        "%s%i", pd_ranges->name, idx);
+       else
+               snprintf(sc_pd->name, sizeof(sc_pd->name),
+                        "%s", pd_ranges->name);
+
+       sc_pd->pd.name = sc_pd->name;
+
+       if (sc_pd->rsrc >= IMX_SC_R_LAST) {
+               dev_warn(dev, "invalid pd %s rsrc id %d found",
+                        sc_pd->name, sc_pd->rsrc);
+
+               devm_kfree(dev, sc_pd);
+               return NULL;
+       }
+
+       ret = pm_genpd_init(&sc_pd->pd, NULL, true);
+       if (ret) {
+               dev_warn(dev, "failed to init pd %s rsrc id %d",
+                        sc_pd->name, sc_pd->rsrc);
+               devm_kfree(dev, sc_pd);
+               return NULL;
+       }
+
+       return sc_pd;
+}
[...]

Kind regards
Uffe
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help