Re: [PATCH v2 4/6] pmdomain: renesas: Add R-Car X5H MDLC driver
Ulf Hansson <[email protected]>
| Newsgroups | org.kernel.vger.linux-renesas-soc,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-clk,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <CAPx+jO9aajD9eFTEUdAFOO-wC5NduaYhbDmYw5DHeFj92Fmd9A@mail.gmail.com> |
On Wed, Jul 15, 2026 at 11:11 AM Geert Uytterhoeven <[email protected]> wrote: > > Hi Ulf, > > On Tue, 14 Jul 2026 at 14:04, Ulf Hansson <[email protected]> wrote: > > On Wed, Jul 8, 2026 at 12:15 PM Geert Uytterhoeven > > <[email protected]> wrote: > > > > > > Add a minimal Module Controller driver for the R-Car X5H (R8A78000) SoC. > > > For now this just supports the always-on power domains, and dummy clocks > > > and resets for the serial console (which is enabled by the boot loader). > > > > > > Signed-off-by: Geert Uytterhoeven <[email protected]> > > > > --- /dev/null > > > +++ b/drivers/pmdomain/renesas/r8a78000-mdlc.c > > > > +static struct generic_pm_domain *r8a78000_genpd_xlate( > > > + const struct of_phandle_args *spec, void *data) > > > +{ > > > + struct r8a78000_mdlc_priv *priv = container_of(data, > > > + struct r8a78000_mdlc_priv, genpd_data); > > > + struct device *dev = priv->dev; > > > + u32 id; > > > + > > > + if (spec->args_count != 2) > > > + return ERR_PTR(-EINVAL); > > > + > > > + id = spec->args[0]; > > > + > > > + if (id >= R8A78000_MDLC_PD_AON) { > > > + dev_dbg(dev, > > > + "Mapping HW power domain 0x%x to always-on domain\n", > > > + id); > > > + return r8a78000_genpd_always_on; > > > > This looks odd, but perhaps it's just a temporary mapping that you > > intend to change later, no? > > The hardware has multiple always-on domains, but on the software side, > using only one is sufficient. When needed, it can be changed later. > Other domains will be added later, in the else branch. I see, perhaps add a comment about this in the code, to make this more clear? > > > > + } > > > + > > > + dev_err(dev, "Unknown power domain 0x%x\n", id); > > > + return ERR_PTR(-ENOENT); > > > +} > > > > +static int r8a78000_genpd_always_on_singleton(struct device *dev) > > > +{ > > > + struct generic_pm_domain *genpd; > > > + int ret; > > > + > > > + guard(mutex)(&r8a78000_mdlc_lock); > > > + > > > + if (r8a78000_genpd_always_on) > > > + return 0; > > > + > > > > I guess the mutex is used to protect the global > > r8a78000_genpd_always_on, but it looks like that isn't really needed > > based upon how things are being called during the probe. > > Why would it not be needed? There are multiple instances of the MDLC > device, but only one instance of the always-on domain. Aha, I see. Thanks for clarifying! > > > > + genpd = kzalloc_obj(*genpd); > > > + if (!genpd) > > > + return -ENOMEM; > > > + > > > + genpd->name = "always-on"; > > > + genpd->attach_dev = r8a78000_mdlc_attach_dev; > > > + > > > + ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false); > > > + if (ret) { > > > + kfree(genpd); > > > + return dev_err_probe(dev, ret, > > > + "Failed to create always-on domain\n"); > > > + } > > > + > > > + r8a78000_genpd_always_on = genpd; > > > + return 0; > > > +} > > > + > > > +static int r8a78000_mdlc_probe(struct platform_device *pdev) > > > +{ > > > + struct device *dev = &pdev->dev; > > > + struct device_node *np = dev->of_node; > > > + struct r8a78000_mdlc_priv *priv; > > > + const struct mdlc_info *info; > > > + struct resource *res; > > > + int ret; > > > + > > > + ret = r8a78000_genpd_always_on_singleton(dev); > > > + if (ret) > > > + return ret; > > > + > > > + info = of_device_get_match_data(dev); > > > + if (!info) > > > + return -ENODEV; > > > + > > > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > > > + if (!priv) > > > + return -ENOMEM; > > > + > > > + priv->dev = dev; > > > + priv->np = np; > > > + > > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > > + if (!res) > > > + return -ENODEV; > > > + > > > + for (; info->base; info++) { > > > + if (info->base == res->start) > > > + break; > > > + } > > > + > > > + if (!info->base) { > > > + dev_dbg(dev, "Unsupported MDLC instance 0x%pa\n", &res->start); > > > + return -ENODEV; > > > + } > > > + > > > + priv->mod_map = info->mod_map; > > > + > > > + scoped_guard(mutex, &r8a78000_mdlc_lock) { > > > + hlist_add_head(&priv->link, &r8a78000_mdlc_list); > > > + } > > > + > > > + ret = devm_add_action_or_reset(dev, r8a78000_mdlc_unlink, priv); > > > + if (ret) > > > + return dev_err_probe(dev, ret, "failed to add action\n"); > > > + > > > + /* Note that no actual domains are registered, just need translation */ > > > + priv->genpd_data.xlate = r8a78000_genpd_xlate; > > > + ret = of_genpd_add_provider_onecell(np, &priv->genpd_data); > > > + if (ret) > > > + return dev_err_probe(dev, ret, > > > + "Failed to register genpd provider\n"); > > > + > > > + ret = devm_add_action_or_reset(dev, r8a78000_genpd_del_provider, np); > > > + if (ret) > > > + return dev_err_probe(dev, ret, > > > + "failed to add unregister action\n"); > > > + > > > + priv->rcdev.ops = &r8a78000_mdlc_reset_ops; > > > + priv->rcdev.of_node = np; > > > + priv->rcdev.of_reset_n_cells = 1; > > > + priv->rcdev.of_xlate = r8a78000_mdlc_reset_xlate; > > > + > > > + ret = devm_reset_controller_register(dev, &priv->rcdev); > > > + if (ret) > > > + return dev_err_probe(dev, ret, > > > + "Failed to register reset controller\n"); > > > + > > > > In some of the error paths above it looks like we end up leaking the > > data allocated for r8a78000_genpd_always_on. Perhaps clean up that > > somewhere here. > > That is intentional: the always-on domain is shared by all MDLC > instances. If one MDLC fails to probe, the MDLC instances that did > succeed still need the always-on domain. Okay, so perhaps we should add a reference counting of it, to make sure we don't leak the data? > > > > > > + return 0; > > > +} > > > > [...] > > > > In regards to the merge strategy, I intend to pick patch 2 (shared via > > the immutable dt branch) and $subject patch. Please let me know if > > there are any issues with that. > > That is fine, thanks! Great, thanks! Kind regards Uffe