summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-09-11 15:24:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-09-11 15:24:21 -0700
commit114f73092b5d1bbea2554a6a784f5ebb53d47bdb (patch)
treee99dba314e3855036cd5eb214d1dbd6b91528636
parent0fb234ce373a331a21c1d33cffef28e53cee4ddb (diff)
parentf3e6ef13e24c9f26dca0d35de57fcdf04f78e378 (diff)
Merge tag 'regulator-fix-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fixes from Mark Brown: "One fix for pf1550 which checked for errors on multiple regulators but always notified via one of them regardless of which one had the problem, plus one device ID addition in the fan53555 DT bindings" * tag 'regulator-fix-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: regulator: pf1550: fix which regulator is notified regulator: dt-bindings: fan53555: add tcs,tcs4526
-rw-r--r--Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml1
-rw-r--r--drivers/regulator/pf1550-regulator.c82
2 files changed, 41 insertions, 42 deletions
diff --git a/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml b/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml
index 9a18891f721e..b35b8f365b0f 100644
--- a/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml
+++ b/Documentation/devicetree/bindings/regulator/fcs,fan53555.yaml
@@ -23,6 +23,7 @@ properties:
- silergy,syr827
- silergy,syr828
- tcs,tcs4525
+ - tcs,tcs4526
- items:
- const: rockchip,rk8601
- const: rockchip,rk8600
diff --git a/drivers/regulator/pf1550-regulator.c b/drivers/regulator/pf1550-regulator.c
index 610eac9bb9cb..ceee553a84b2 100644
--- a/drivers/regulator/pf1550-regulator.c
+++ b/drivers/regulator/pf1550-regulator.c
@@ -283,63 +283,61 @@ static struct pf1550_desc pf1550_regulators[] = {
PF_LDO1(PF1550, "ldo3", LDO3, 0x1f, pf1550_ldo13_volts),
};
+/*
+ * The _LS interrupts indicate an over-current event. The _HS
+ * interrupts, which are more accurate and can detect catastrophic
+ * faults, issue an error event. The current limit FAULT interrupt is
+ * similar to the _HS.
+ */
+static const struct pf1550_regulator_irq {
+ unsigned int event;
+ u8 id;
+} pf1550_regulator_irqs[] = {
+ [PF1550_PMIC_IRQ_SW1_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW1 },
+ [PF1550_PMIC_IRQ_SW2_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW2 },
+ [PF1550_PMIC_IRQ_SW3_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW3 },
+ [PF1550_PMIC_IRQ_SW1_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW1 },
+ [PF1550_PMIC_IRQ_SW2_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW2 },
+ [PF1550_PMIC_IRQ_SW3_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW3 },
+ [PF1550_PMIC_IRQ_LDO1_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO1 },
+ [PF1550_PMIC_IRQ_LDO2_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO2 },
+ [PF1550_PMIC_IRQ_LDO3_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO3 },
+};
+
static irqreturn_t pf1550_regulator_irq_handler(int irq, void *data)
{
+ const struct pf1550_regulator_irq *map;
struct pf1550_regulator_info *info = data;
struct device *dev = info->dev;
struct platform_device *pdev = to_platform_device(dev);
int i, irq_type = -1;
- unsigned int event;
for (i = 0; i < PF1550_REGULATOR_IRQ_NR; i++)
if (irq == platform_get_irq(pdev, i))
irq_type = i;
- switch (irq_type) {
- /* The _LS interrupts indicate over-current event. The _HS interrupts
- * which are more accurate and can detect catastrophic faults, issue
- * an error event. The current limit FAULT interrupt is similar to the
- * _HS'
- */
- case PF1550_PMIC_IRQ_SW1_LS:
- case PF1550_PMIC_IRQ_SW2_LS:
- case PF1550_PMIC_IRQ_SW3_LS:
- event = REGULATOR_EVENT_OVER_CURRENT_WARN;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_SW1_HS:
- case PF1550_PMIC_IRQ_SW2_HS:
- case PF1550_PMIC_IRQ_SW3_HS:
- event = REGULATOR_EVENT_OVER_CURRENT;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_LDO1_FAULT:
- case PF1550_PMIC_IRQ_LDO2_FAULT:
- case PF1550_PMIC_IRQ_LDO3_FAULT:
- event = REGULATOR_EVENT_OVER_CURRENT;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "LDO3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_TEMP_110:
- case PF1550_PMIC_IRQ_TEMP_125:
- event = REGULATOR_EVENT_OVER_TEMP;
+ /* The die temperature concerns every rail. */
+ if (irq_type == PF1550_PMIC_IRQ_TEMP_110 ||
+ irq_type == PF1550_PMIC_IRQ_TEMP_125) {
for (i = 0; i < PF1550_MAX_REGULATOR; i++)
regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- default:
- dev_err(dev, "regulator interrupt: irq %d occurred\n",
- irq_type);
+ REGULATOR_EVENT_OVER_TEMP,
+ NULL);
+ return IRQ_HANDLED;
+ }
+
+ if (irq_type < 0 || irq_type >= (int)ARRAY_SIZE(pf1550_regulator_irqs)) {
+ dev_err(dev, "regulator interrupt: irq %d occurred\n", irq_type);
+ return IRQ_HANDLED;
}
+ map = &pf1550_regulator_irqs[irq_type];
+
+ for (i = 0; i < PF1550_MAX_REGULATOR; i++)
+ if (rdev_get_id(info->rdevs[i]) == map->id)
+ regulator_notifier_call_chain(info->rdevs[i],
+ map->event, NULL);
+
return IRQ_HANDLED;
}