From: sashiko-bot@kernel.org
To: "Qianhui Xu" <xiaqinghuan@mail.ustc.edu.cn>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v9 2/2] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
Date: Mon, 09 Nov 2026 20:13:59 +0000 [thread overview]
Message-ID: <sashiko-outbox-205554@kernel.org> (raw)
In-Reply-To: <20261107015014.22374-3-xiaqinghuan@mail.ustc.edu.cn>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] regulator: wl2868c: preset LDOs enabled by wl2868c_probe()
when SYS_EN is 0
- [Medium] regulator: wl2868c: reset released before enabling vsys in
wl2868c_probe()
- [Medium] regulator: wl2868c: vin7-supply not enabled for I2C in
wl2868c_probe()
--
commit fa96a3434b8aa9642e9973857f62fda162d22f23
Author: Qianhui Xu <xiaqinghuan@mail.ustc.edu.cn>
regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver
This commit adds a regulator driver for the seven LDO outputs of the Will
Semiconductor WL2868C I2C camera power management IC.
> diff --git a/drivers/regulator/wl2868c-regulator.c b/drivers/regulator/wl2868c-regulator.c
> new file mode 100644
> index 0000000000000..64baeeacf378b
> --- /dev/null
> +++ b/drivers/regulator/wl2868c-regulator.c
> @@ -0,0 +1,246 @@
[ ... ]
> +static int wl2868c_enable(struct regulator_dev *rdev)
> +{
> + struct wl2868c *chip = rdev_get_drvdata(rdev);
> + unsigned int bits = rdev->desc->enable_mask;
> + unsigned int ldos;
> + int ret;
> +
> + guard(mutex)(&chip->lock);
> +
> + /*
> + * The enable register is written as a whole on purpose. SYS_EN gates
> + * every output of the chip, and the per-LDO bits may be preset by the
> + * firmware while SYS_EN is still clear: setting only SYS_EN and our own
> + * bit would then bring the preset LDOs up as well. Writing the register
> + * with the bits of the LDOs consumers have enabled, and only those,
> + * keeps the other outputs off. chip->enabled was seeded from the
> + * register in probe(), so an output the firmware left on is carried
> + * over instead of being cleared by the first enable.
> + */
> + ldos = (chip->enabled | bits) & WL2868C_LDO_ENABLE_MASK;
> + ret = regmap_write(chip->regmap, WL2868C_LDO_ENABLE,
> + WL2868C_SYS_ENABLE | ldos);
> + if (ret)
> + return ret;
> +
> + chip->enabled = ldos;
> +
> + return 0;
> +}
[ ... ]
> +static int wl2868c_is_enabled(struct regulator_dev *rdev)
> +{
> + unsigned int mask = WL2868C_SYS_ENABLE | rdev->desc->enable_mask;
> + unsigned int value;
> + int ret;
> +
> + ret = regmap_read(rdev->regmap, WL2868C_LDO_ENABLE, &value);
> + if (ret)
> + return ret;
> +
> + return (value & mask) == mask;
> +}
[ ... ]
> +static const struct regulator_desc wl2868c_regulators[] = {
> + WL2868C_LDO(1, "vin12", 496000, 128, 0x03, 0x7f, BIT(0)),
> + WL2868C_LDO(2, "vin12", 496000, 128, 0x04, 0x7f, BIT(1)),
> + WL2868C_LDO(3, "vin34", 1504000, 256, 0x05, 0xff, BIT(2)),
> + WL2868C_LDO(4, "vin34", 1504000, 256, 0x06, 0xff, BIT(3)),
> + WL2868C_LDO(5, "vin5", 1504000, 256, 0x07, 0xff, BIT(4)),
> + WL2868C_LDO(6, "vin6", 1504000, 256, 0x08, 0xff, BIT(5)),
> + WL2868C_LDO(7, "vin7", 1504000, 256, 0x09, 0xff, BIT(6)),
> +};
[ ... ]
> +static int wl2868c_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + struct regulator_config config = { .dev = dev };
> + struct regulator_dev *rdev;
> + struct gpio_desc *reset;
> + struct wl2868c *chip;
> + unsigned int id, value;
> + int ret, i;
> +
> + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
> + if (!chip)
> + return -ENOMEM;
> +
> + mutex_init(&chip->lock);
> + config.driver_data = chip;
> +
> + reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(reset))
> + return dev_err_probe(dev, PTR_ERR(reset), "Failed to get reset GPIO\n");
> +
> + if (reset) {
> + ret = devm_add_action_or_reset(dev, wl2868c_reset, reset);
> + if (ret)
> + return ret;
> + fsleep(1000);
> + }
[Severity: Medium]
Does wl2868c_probe() release the reset line and wait 1 ms before enabling
the vsys power supply below?
If vsys is initially off, the reset deassertion and 1 ms startup delay
happen while the chip is unpowered, and the subsequent device ID read runs
immediately after devm_regulator_get_enable() with no startup delay.
Because devres unwinds in reverse order, unbind or probe failure will also
disable vsys before wl2868c_reset() asserts reset.
> + chip->regmap = devm_regmap_init_i2c(client, &wl2868c_regmap_config);
> + config.regmap = chip->regmap;
> + if (IS_ERR(config.regmap))
> + return dev_err_probe(dev, PTR_ERR(config.regmap),
> + "Failed to create regmap\n");
> +
> + /*
> + * The I2C interface is powered from the higher of VIN7 and VSYS, so the
> + * system supply has to be up before the device can answer at all. It
> + * stays enabled for as long as the driver is bound.
> + */
> + ret = devm_regulator_get_enable(dev, "vsys");
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to enable the system supply\n");
> +
> + ret = regmap_read(config.regmap, WL2868C_DEVICE_ID, &id);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read device ID\n");
> + if (id != WL2868C_DEVICE_ID_VALUE)
> + return dev_err_probe(dev, -ENODEV, "Unexpected device ID: %#x\n", id);
[Severity: Medium]
What happens on boards that power the control logic and I2C interface from
vin7-supply without vsys-supply?
The devicetree binding allows supplying either vin7-supply or vsys-supply,
but wl2868c_probe() only enables vsys and leaves vin7 attached solely as
the input supply of ldo7. When vsys-supply is omitted,
devm_regulator_get_enable() falls back to a dummy regulator while
vin7-supply stays disabled during the initial register reads and whenever
ldo7 is off, leaving the chip unpowered on the I2C bus.
> + /*
> + * Seed the tracked set with the outputs the firmware left enabled, so
> + * that the first enable() or disable() of any output preserves them.
> + * The regulator core reads the state back through is_enabled(), which
> + * does not look at this set.
> + */
> + ret = regmap_read(config.regmap, WL2868C_LDO_ENABLE, &value);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read the enable register\n");
> +
> + chip->enabled = value & WL2868C_LDO_ENABLE_MASK;
[Severity: Medium]
Doesn't seeding chip->enabled without checking whether bit 7 (sys_en) is
set in value defeat the protection against preset LDO bits in
wl2868c_enable()?
When bit 7 is clear at probe time, any preset per-LDO bits in value are
copied into chip->enabled even though all outputs are off and
wl2868c_is_enabled() reports them as disabled. The first wl2868c_enable()
call for any single output then writes chip->enabled | bits together with
bit 7, turning on all of the preset outputs and leaving them stuck on
even after consumers disable their regulators.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261107015014.22374-1-xiaqinghuan@mail.ustc.edu.cn?part=2
prev parent reply other threads:[~2026-11-09 20:14 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 11:42 [PATCH v8 0/2] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
2026-11-06 11:42 ` [PATCH v8 1/2] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
2026-11-06 17:12 ` Conor Dooley
2026-11-06 11:42 ` [PATCH v8 2/2] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
2026-11-07 1:50 ` [PATCH v9 0/2] regulator: add the Will Semiconductor WL2868C camera PMIC Qianhui Xu
2026-11-07 1:50 ` [PATCH v9 1/2] regulator: dt-bindings: willsemi,wl2868c: add the " Qianhui Xu
2026-11-09 14:54 ` Rob Herring (Arm)
2026-11-07 1:50 ` [PATCH v9 2/2] regulator: willsemi,wl2868c: add the WL2868C camera PMIC driver Qianhui Xu
2026-11-09 20:13 ` sashiko-bot [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-205554@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=xiaqinghuan@mail.ustc.edu.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.