Re: [PATCH 2/2] mfd: qcom-pm8008: support PMICs with no interrupt line

From: Lee Jones

Date: Tue Sep 22 2026 - 06:19:52 EST


On Tue, 08 Sep 2026, Oleg Keri wrote:

> The interrupt is only needed for the temperature alarm and the two GPIOs.
> Where the pin is not routed the regulators are still perfectly usable, but
> probe fails: client->irq is 0 and request_threaded_irq() rejects it.
>
> Skip the IRQ chip in that case and register the regulator cell alone. The
> temperature alarm cannot be registered without a domain either, because
> its IORESOURCE_IRQ would be handed to the platform device as a raw number
> rather than being mapped, and the GPIO cell needs the domain for the same
> reason.
>
> Signed-off-by: Oleg Keri <okerixx@xxxxxxxxx>

What on earth is going on here:

https://lore.kernel.org/r/20260907-glymur_camss-v2-5-75f7982dc983@xxxxxxxxxxxxxxxx

> ---
> drivers/mfd/qcom-pm8008.c | 63 +++++++++++++++++++++++++--------------
> 1 file changed, 40 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
> index 60204cc9a2dc..b51a9657ee56 100644
> --- a/drivers/mfd/qcom-pm8008.c
> +++ b/drivers/mfd/qcom-pm8008.c
> @@ -183,6 +183,10 @@ static const struct mfd_cell pm8008_cells[] = {
> MFD_CELL_NAME("pm8008-gpio"),
> };
>
> +static const struct mfd_cell pm8008_regulator_cells[] = {
> + MFD_CELL_NAME("pm8008-regulator"),
> +};
> +
> static void devm_irq_domain_fwnode_release(void *data)
> {
> struct fwnode_handle *fwnode = data;
> @@ -195,9 +199,12 @@ static int pm8008_probe(struct i2c_client *client)
> struct regmap_irq_chip_data *irq_data;
> struct device *dev = &client->dev;
> struct regmap *regmap, *regmap2;
> + const struct mfd_cell *cells;
> struct fwnode_handle *fwnode;
> + struct irq_domain *domain;
> struct i2c_client *dummy;
> struct gpio_desc *reset;
> + int num_cells;
> char *name;
> int ret;
>
> @@ -231,33 +238,43 @@ static int pm8008_probe(struct i2c_client *client)
> */
> usleep_range(1000, 2000);
>
> - name = devm_kasprintf(dev, GFP_KERNEL, "%pOF-internal", dev->of_node);
> - if (!name)
> - return -ENOMEM;
> -
> - name = strreplace(name, '/', ':');
> -
> - fwnode = irq_domain_alloc_named_fwnode(name);
> - if (!fwnode)
> - return -ENOMEM;
> -
> - ret = devm_add_action_or_reset(dev, devm_irq_domain_fwnode_release, fwnode);
> - if (ret)
> - return ret;
> -
> - ret = devm_regmap_add_irq_chip_fwnode(dev, fwnode, regmap, client->irq,
> - IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data);
> - if (ret) {
> - dev_err(dev, "failed to add IRQ chip: %d\n", ret);
> - return ret;
> + if (client->irq > 0) {
> + name = devm_kasprintf(dev, GFP_KERNEL, "%pOF-internal", dev->of_node);
> + if (!name)
> + return -ENOMEM;
> +
> + name = strreplace(name, '/', ':');
> +
> + fwnode = irq_domain_alloc_named_fwnode(name);
> + if (!fwnode)
> + return -ENOMEM;
> +
> + ret = devm_add_action_or_reset(dev, devm_irq_domain_fwnode_release, fwnode);
> + if (ret)
> + return ret;
> +
> + ret = devm_regmap_add_irq_chip_fwnode(dev, fwnode, regmap,
> + client->irq, IRQF_SHARED, 0,
> + &pm8008_irq_chip, &irq_data);
> + if (ret) {
> + dev_err(dev, "failed to add IRQ chip: %d\n", ret);
> + return ret;
> + }
> +
> + domain = regmap_irq_get_domain(irq_data);
> + cells = pm8008_cells;
> + num_cells = ARRAY_SIZE(pm8008_cells);
> + } else {
> + domain = NULL;
> + cells = pm8008_regulator_cells;
> + num_cells = ARRAY_SIZE(pm8008_regulator_cells);
> }
>
> /* Needed by GPIO driver. */
> - dev_set_drvdata(dev, regmap_irq_get_domain(irq_data));
> + dev_set_drvdata(dev, domain);
>
> - return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, pm8008_cells,
> - ARRAY_SIZE(pm8008_cells), NULL, 0,
> - regmap_irq_get_domain(irq_data));
> + return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells,
> + num_cells, NULL, 0, domain);
> }
>
> static const struct of_device_id pm8008_match[] = {
> --
> 2.55.0
>

--
Lee Jones