[PATCH 2/2] mfd: qcom-pm8008: support PMICs with no interrupt line
From: Oleg Keri
Date: Tue Sep 08 2026 - 09:57:54 EST
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>
---
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