[PATCH 2/2] mfd: qcom-pm8008: support PMICs with no interrupt line
From: Oleg Keri <hidden>
Date: 2026-09-08 13:08:03
Also in:
linux-arm-msm, lkml
Subsystem:
arm/qualcomm mailing list, multifunction devices (mfd), the rest · Maintainers:
Lee Jones, Linus Torvalds
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 <redacted> --- 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