[PATCH v12 4/7] regulator: p3h2x4x: Add driver for on-die regulators in NXP P3H2x4x i3c hub
Frank Li
Frank.li at oss.nxp.com
Wed Jun 17 07:50:24 PDT 2026
On Wed, Jun 17, 2026 at 11:17:43AM +0000, sashiko-bot at kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Concurrent regulator operations race on the shared device-level protection register, leading to silent hardware configuration failures.
> - [Medium] The driver module will not auto-load because it lacks a MODULE_ALIAS or platform_device_id table.
> - [Medium] If regmap_read or the unlock sequence fails in the guard constructor, the driver proceeds with the regulator operation on locked registers.
> - [Low] Typo in regulator config assignment assigns dev->of_node to itself instead of rcfg.of_node.
> --
>
> commit e68081b58005a2422d441a5611dac29f8cffe2f4
> Author: Aman Kumar Pandey <aman.kumarpandey at nxp.com>
>
> regulator: p3h2x4x: Add driver for on-die regulators in NXP P3H2x4x i3c hub
>
> The NXP P3H2x4x family integrates on-die regulators alongside I3C hub
> functionality. This driver registers the regulators using the MFD
> framework and exposes them via the regulator subsystem.
>
> > --- /dev/null
> > +++ b/drivers/regulator/p3h2840_i3c_hub_regulator.c
>
> [ ... ]
>
> > +static void p3h2x4x_reg_guard_enter(struct regulator_dev *rdev,
> > + struct p3h2x4x_reg_state *state)
> > +{
> > + state->restore = false;
> > +
> > + if (regmap_read(rdev->regmap,
> > + P3H2X4X_DEV_REG_PROTECTION_CODE,
> > + &state->orig))
> > + return;
>
> [Severity: Medium]
> If regmap_read() fails here, the function returns early and swallows the
> error since the guard constructor returns void. Will this cause the caller
> to proceed with regulator operations on locked hardware, potentially
> resulting in silent hardware configuration failures?
>
> If the device ACKs the transaction despite ignoring the write, wouldn't
> the driver incorrectly report success to the regulator core?
>
> > +
> > + if (state->orig != P3H2X4X_REGISTERS_UNLOCK_CODE) {
> > + regmap_write(rdev->regmap,
> > + P3H2X4X_DEV_REG_PROTECTION_CODE,
> > + P3H2X4X_REGISTERS_UNLOCK_CODE);
> > + state->restore = true;
> > + }
> > +}
> > +
> > +static void p3h2x4x_reg_guard_exit(struct regulator_dev *rdev,
> > + struct p3h2x4x_reg_state *state)
> > +{
> > + if (state->restore)
> > + regmap_write(rdev->regmap,
> > + P3H2X4X_DEV_REG_PROTECTION_CODE,
> > + state->orig);
> > +}
> > +
> > +DEFINE_LOCK_GUARD_1(p3h2x4x_reg, struct regulator_dev,
> > + p3h2x4x_reg_guard_enter(_T->lock, &_T->state),
> > + p3h2x4x_reg_guard_exit(_T->lock, &_T->state),
> > + struct p3h2x4x_reg_state state);
>
> [Severity: High]
> Does this guard provide mutual exclusion across the four different regulators
> on the same device?
>
> The regmap lock protects individual I/O operations, but since there is no
> device-level lock held across the unlock/modify/lock sequence, can concurrent
> operations on different regulators interleave?
Look like make sense, need use mutex to protect this sequency.
>
> For example, could one thread re-lock the device in p3h2x4x_reg_guard_exit()
> while another thread is just about to write its configuration, causing the
> hardware write to be silently ignored? Is a shared device-level mutex needed
> to serialize these sequences?
>
> [ ... ]
>
> > +static int p3h2x4x_regulator_probe(struct platform_device *pdev)
> > +{
> > + struct p3h2x4x_dev *p3h2x4x = dev_get_drvdata(pdev->dev.parent);
> > + struct p3h2x4x_regulator_dev *p3h2x4x_regulator;
> > + struct regulator_config rcfg = { };
> > + struct device *dev = &pdev->dev;
> > + struct regulator_dev *rdev;
> > + int i;
> > +
> > + p3h2x4x_regulator = devm_kzalloc(dev, sizeof(*p3h2x4x_regulator), GFP_KERNEL);
> > + if (!p3h2x4x_regulator)
> > + return -ENOMEM;
> > +
> > + platform_set_drvdata(pdev, p3h2x4x_regulator);
> > +
> > + p3h2x4x_regulator->regmap = p3h2x4x->regmap;
> > + device_set_of_node_from_dev(dev, dev->parent);
> > +
> > + rcfg.dev = dev;
> > + rcfg.dev->of_node = dev->of_node;
>
> [Severity: Low]
> Should this be rcfg.of_node = dev->of_node? Since rcfg.dev is assigned to dev
> on the previous line, this just assigns dev->of_node to itself.
Although it is small problem, look likes not necesary to set of_node here.
It'd better to fix it at next version.
Frank
>
> > + rcfg.regmap = p3h2x4x_regulator->regmap;
> > + rcfg.driver_data = p3h2x4x_regulator;
>
> [ ... ]
>
> > +static struct platform_driver p3h2x4x_regulator_driver = {
> > + .driver = {
> > + .name = "p3h2x4x-regulator",
> > + .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> > + },
> > + .probe = p3h2x4x_regulator_probe,
> > +};
> > +module_platform_driver(p3h2x4x_regulator_driver);
> > +
> > +MODULE_AUTHOR("Aman Kumar Pandey <aman.kumarpandey at nxp.com>");
> > +MODULE_AUTHOR("Vikash Bansal <vikash.bansal at nxp.com>");
> > +MODULE_AUTHOR("Lakshay Piplani <lakshay.piplani at nxp.com>");
> > +MODULE_DESCRIPTION("NXP P3H2X4X I3C HUB Regulator driver");
> > +MODULE_LICENSE("GPL");
>
> [Severity: Medium]
> Since the driver is registered as a platform driver with the name
> "p3h2x4x-regulator" but the module is compiled as
> "p3h2840_i3c_hub_regulator.ko", will this module fail to auto-load?
>
> Without a MODULE_ALIAS("platform:p3h2x4x-regulator") or an exported
> platform_device_id table, udev may not be able to load the module when the
> MFD core creates the child platform device.
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260617110355.1591844-1-lakshay.piplani@nxp.com?part=4
More information about the linux-i3c
mailing list