RE: [PATCH 2/3] power: sequencing: Add Renesas RZ/G3L Power Ready driver

Biju Das <[email protected]> Tue, 28 Jul 2026 09:17:58 +0000
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm
Message-ID <TYCPR01MB11332A50145F29D93157A58BC86CB2@TYCPR01MB11332.jpnprd01.prod.outlook.com>
Hi Bartosz Golaszewski,

Thanks for the feedback.

> -----Original Message-----
> From: Bartosz Golaszewski <[email protected]>
> Sent: 28 July 2026 09:45
> Subject: Re: [PATCH 2/3] power: sequencing: Add Renesas RZ/G3L Power Ready driver
> 
> On Sat, 25 Jul 2026 14:34:29 +0200, Biju <[email protected]> said:
> > From: Biju Das <[email protected]>
> >
> > Add a power sequencing driver for the Renesas RZ/G3L PWRRDY module,
> > which signals power readiness for various IPs (USB, DSI, CSI etc.) on
> > the SoC. The driver binds as an auxiliary device to the parent SYSC
> > driver, using its regmap to toggle the SYS_PWRRDY_N register bits, and
> > exposes {usb,dsi,csi}-pwrrdy pwrseq targets.
> >
> > Signed-off-by: Biju Das <[email protected]>
> > ---
> >  drivers/power/sequencing/Kconfig              |   8 +
> >  drivers/power/sequencing/Makefile             |   1 +
> >  .../power/sequencing/pwrseq-renesas-pwrrdy.c  | 141
> > ++++++++++++++++++
> >  3 files changed, 150 insertions(+)
> >  create mode 100644 drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
> >
> > diff --git a/drivers/power/sequencing/Kconfig
> > b/drivers/power/sequencing/Kconfig
> > index 1c5f5820f5b7..245961cc8123 100644
> > --- a/drivers/power/sequencing/Kconfig
> > +++ b/drivers/power/sequencing/Kconfig
> > @@ -27,6 +27,14 @@ config POWER_SEQUENCING_QCOM_WCN
> >  	  this driver is needed for correct power control or else we'd risk not
> >  	  respecting the required delays between enabling Bluetooth and WLAN.
> >
> > +config POWER_SEQUENCING_RENESAS_PWRRDY
> > +	tristate "Renesas Power Ready sequencing driver"
> > +	depends on SYSC_RZ || COMPILE_TEST
> > +	help
> > +	  Say Y here to enable the power sequencing driver for the Renesas
> > +	  Power Ready signals. This driver handles the power ready signals
> > +	  required to power on the various IP's on RZ/G3L platform.
> > +
> >  config POWER_SEQUENCING_TH1520_GPU
> >  	tristate "T-HEAD TH1520 GPU power sequencing driver"
> >  	depends on (ARCH_THEAD && AUXILIARY_BUS) || COMPILE_TEST diff --git
> > a/drivers/power/sequencing/Makefile
> > b/drivers/power/sequencing/Makefile
> > index 0911d4618298..b33d08d82f43 100644
> > --- a/drivers/power/sequencing/Makefile
> > +++ b/drivers/power/sequencing/Makefile
> > @@ -4,5 +4,6 @@ obj-$(CONFIG_POWER_SEQUENCING)		+= pwrseq-core.o
> >  pwrseq-core-y				:= core.o
> >
> >  obj-$(CONFIG_POWER_SEQUENCING_QCOM_WCN)	+= pwrseq-qcom-wcn.o
> > +obj-$(CONFIG_POWER_SEQUENCING_RENESAS_PWRRDY) +=
> > +pwrseq-renesas-pwrrdy.o
> >  obj-$(CONFIG_POWER_SEQUENCING_TH1520_GPU) += pwrseq-thead-gpu.o
> >  obj-$(CONFIG_POWER_SEQUENCING_PCIE_M2)	+= pwrseq-pcie-m2.o
> > diff --git a/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
> > b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
> > new file mode 100644
> > index 000000000000..a3d187dd3247
> > --- /dev/null
> > +++ b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
> > @@ -0,0 +1,141 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Renesas RZ/G3L Power Ready driver
> > + *
> > + */
> > +
> > +#include <linux/auxiliary_bus.h>
> > +#include <linux/module.h>
> > +#include <linux/pwrseq/provider.h>
> > +#include <linux/regmap.h>
> > +
> > +#define SYS_PWRRDY_N		0xd70
> > +#define SYS_PWRRDY_N_USB_MASK	BIT(0)
> > +#define SYS_PWRRDY_N_DSI_MASK	BIT(1)
> > +#define SYS_PWRRDY_N_CSI_MASK	BIT(2)
> > +
> > +static int pwrseq_rzg3l_set_pwrrdy(struct pwrseq_device *pwrseq, u32
> > +mask, u32 val) {
> > +	struct regmap *regmap = pwrseq_device_get_drvdata(pwrseq);
> > +
> > +	return regmap_update_bits(regmap, SYS_PWRRDY_N, mask, val); }
> > +
> > +static int pwrseq_rzg3l_usb_pwrrdy_enable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 0); }
> > +
> > +static int pwrseq_rzg3l_usb_pwrrdy_disable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 1); }
> > +
> > +static const struct pwrseq_unit_data pwrseq_rzg3l_usb_pwrrdy_unit = {
> > +	.name = "usb-pwrrdy-power-sequence",
> > +	.enable = pwrseq_rzg3l_usb_pwrrdy_enable,
> > +	.disable = pwrseq_rzg3l_usb_pwrrdy_disable, };
> > +
> > +static int pwrseq_rzg3l_dsi_pwrrdy_enable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 0); }
> > +
> > +static int pwrseq_rzg3l_dsi_pwrrdy_disable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 1); }
> > +
> > +static const struct pwrseq_unit_data pwrseq_rzg3l_dsi_pwrrdy_unit = {
> > +	.name = "dsi-pwrrdy-sequence",
> > +	.enable = pwrseq_rzg3l_dsi_pwrrdy_enable,
> > +	.disable = pwrseq_rzg3l_dsi_pwrrdy_disable, };
> > +
> > +static int pwrseq_rzg3l_csi_pwrrdy_enable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 0); }
> > +
> > +static int pwrseq_rzg3l_csi_pwrrdy_disable(struct pwrseq_device
> > +*pwrseq) {
> > +	return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 1); }
> > +
> > +static const struct pwrseq_unit_data pwrseq_rzg3l_csi_pwrrdy_unit = {
> > +	.name = "csi-pwrrdy-power-sequence",
> > +	.enable = pwrseq_rzg3l_csi_pwrrdy_enable,
> > +	.disable = pwrseq_rzg3l_csi_pwrrdy_disable, };
> > +
> > +static const struct pwrseq_target_data pwrseq_rzg3l_usb_pwrrdy_target = {
> > +	.name = "usb-pwrrdy",
> > +	.unit = &pwrseq_rzg3l_usb_pwrrdy_unit, };
> > +
> > +static const struct pwrseq_target_data pwrseq_rzg3l_dsi_pwrrdy_target = {
> > +	.name = "dsi-pwrrdy",
> > +	.unit = &pwrseq_rzg3l_dsi_pwrrdy_unit, };
> > +
> > +static const struct pwrseq_target_data pwrseq_rzg3l_csi_pwrrdy_target = {
> > +	.name = "csi-pwrrdy",
> > +	.unit = &pwrseq_rzg3l_csi_pwrrdy_unit, };
> > +
> > +static const struct pwrseq_target_data *pwrseq_rzg3l_pwrrdy_targets[] = {
> > +	&pwrseq_rzg3l_usb_pwrrdy_target,
> > +	&pwrseq_rzg3l_dsi_pwrrdy_target,
> > +	&pwrseq_rzg3l_csi_pwrrdy_target,
> > +	NULL
> > +};
> > +
> > +static int pwrseq_rzg3l_pwrrdy_match(struct pwrseq_device *pwrseq,
> > +				     struct device *dev)
> > +{
> > +	return PWRSEQ_MATCH_OK;
> 
> When I see an always-tru match() callback, it always raises an alarm bell.
> Typically, I'd expect there to be some validation of the consumer happening.
> 
> Please at least provide an explanation of why it's ok.

Without the match function the driver is not probing.

sysc(driver) ->powerseq(driver) ->{DSI,CSI,USB}(driver)
there is no property that I can match here as the resource is a register on
the SYSC IP and powerseq driver is instantiated by the SYSC driver.

Maybe I can provide a comment here saying that??
"No DT property to match here, so it is OK always"


> 
> > +}
> > +
> > +static int pwrseq_rzg3l_pwrrdy_probe(struct auxiliary_device *adev,
> > +				     const struct auxiliary_device_id *id) {
> > +	struct device *dev = &adev->dev;
> > +	struct pwrseq_config config = {};
> > +	struct pwrseq_device *pwrseq;
> > +	struct regmap *regmap;
> > +
> > +	regmap = dev_get_regmap(adev->dev.parent, NULL);
> > +	if (!regmap)
> > +		return dev_err_probe(dev, -ENODEV, "Failed to retrieve parent
> > +regmap\n");

I will remove this in next version as regmap can be passed from

devm_auxiliary_device_create() and

config.drvdata = adev->dev.platform_data;

> > +
> > +	config.parent = dev;
> > +	config.owner = THIS_MODULE;
> > +	config.drvdata = regmap;
> > +	config.match = pwrseq_rzg3l_pwrrdy_match;
> > +	config.targets = pwrseq_rzg3l_pwrrdy_targets;
> 
> Add newline here.

OK.

> 
> It wouldn't also hurt to use a compound literal like so:
> 
> 	config = (struct pwrseq_config){
> 		.parent = dev,
> 		...
> 	};
> 

Agreed.

> > +	pwrseq = devm_pwrseq_device_register(dev, &config);
> > +	if (IS_ERR(pwrseq))
> > +		return dev_err_probe(dev, PTR_ERR(pwrseq), "Failed to register
> > +power sequencer\n");
> > +
> 
> I'd just return devm_pwrseq_device_register() here.


OK.

Cheers,
Biju