Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mfd: axp20x: Generalise handling without interrupt

At the moment we allow the AXP15060 and the AXP806 PMICs to omit the
interrupt line to the SoC, and we skip registering the PEK (power key)
driver in this case, since that crashes when no IRQ is described in the
DT node.
The IRQ pin potentially not being connected to anything does affect more
PMICs, though, and the PEK driver is not the only one requiring an
interrupt: at least the AC power supply driver crashes in a similar
fashion.

Generalise the handling of AXP MFD devices when the platform tables
describe no interrupt, by allowing each device to specify an alternative
MFD list for this case. If no specific alternative is specified, we go
with the safe default of "just the regulators", which matches the current
situation.

This enables new devices using the AXP313a PMIC, but not connecting the
IRQ pin.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Link: https://lore.kernel.org/r/20230828213229.20332-1-andre.przywara@arm.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Andre Przywara and committed by
Lee Jones
b2cb2ae2 9a41c31e

+24 -20
+24 -20
drivers/mfd/axp20x.c
··· 1133 1133 struct device *dev = axp20x->dev; 1134 1134 const struct acpi_device_id *acpi_id; 1135 1135 const struct of_device_id *of_id; 1136 + const struct mfd_cell *cells_no_irq = NULL; 1137 + int nr_cells_no_irq = 0; 1136 1138 1137 1139 if (dev->of_node) { 1138 1140 of_id = of_match_device(dev->driver->of_match_table, dev); ··· 1209 1207 * if there is no interrupt line. 1210 1208 */ 1211 1209 if (of_property_read_bool(axp20x->dev->of_node, 1212 - "x-powers,self-working-mode") && 1213 - axp20x->irq > 0) { 1210 + "x-powers,self-working-mode")) { 1214 1211 axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells); 1215 1212 axp20x->cells = axp806_self_working_cells; 1216 1213 } else { 1217 1214 axp20x->nr_cells = ARRAY_SIZE(axp806_cells); 1218 1215 axp20x->cells = axp806_cells; 1219 1216 } 1217 + nr_cells_no_irq = ARRAY_SIZE(axp806_cells); 1218 + cells_no_irq = axp806_cells; 1220 1219 axp20x->regmap_cfg = &axp806_regmap_config; 1221 1220 axp20x->regmap_irq_chip = &axp806_regmap_irq_chip; 1222 1221 break; ··· 1241 1238 axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; 1242 1239 break; 1243 1240 case AXP15060_ID: 1244 - /* 1245 - * Don't register the power key part if there is no interrupt 1246 - * line. 1247 - * 1248 - * Since most use cases of AXP PMICs are Allwinner SOCs, board 1249 - * designers follow Allwinner's reference design and connects 1250 - * IRQ line to SOC, there's no need for those variants to deal 1251 - * with cases that IRQ isn't connected. However, AXP15660 is 1252 - * used by some other vendors' SOCs that didn't connect IRQ 1253 - * line, we need to deal with this case. 1254 - */ 1255 - if (axp20x->irq > 0) { 1256 - axp20x->nr_cells = ARRAY_SIZE(axp15060_cells); 1257 - axp20x->cells = axp15060_cells; 1258 - } else { 1259 - axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells); 1260 - axp20x->cells = axp_regulator_only_cells; 1261 - } 1241 + axp20x->nr_cells = ARRAY_SIZE(axp15060_cells); 1242 + axp20x->cells = axp15060_cells; 1262 1243 axp20x->regmap_cfg = &axp15060_regmap_config; 1263 1244 axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip; 1264 1245 break; ··· 1250 1263 dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); 1251 1264 return -EINVAL; 1252 1265 } 1266 + 1267 + /* 1268 + * Use an alternative cell array when no interrupt line is connected, 1269 + * since IRQs are required by some drivers. 1270 + * The default is the safe "regulator-only", as this works fine without 1271 + * an interrupt specified. 1272 + */ 1273 + if (axp20x->irq <= 0) { 1274 + if (cells_no_irq) { 1275 + axp20x->nr_cells = nr_cells_no_irq; 1276 + axp20x->cells = cells_no_irq; 1277 + } else { 1278 + axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells); 1279 + axp20x->cells = axp_regulator_only_cells; 1280 + } 1281 + } 1282 + 1253 1283 dev_info(dev, "AXP20x variant %s found\n", 1254 1284 axp20x_model_names[axp20x->variant]); 1255 1285