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.

genirq: Add irq_chip_(startup/shutdown)_parent()

As the MSI controller on SG2044 uses PLIC as the underlying interrupt
controller, it needs to call irq_enable() and irq_disable() to
startup/shutdown interrupts. Otherwise, the MSI interrupt can not be
startup correctly and will not respond any incoming interrupt.

Introduce irq_chip_startup_parent() and irq_chip_shutdown_parent() to allow
the interrupt controller to call the irq_startup()/irq_shutdown() callbacks
of the parent interrupt chip.

In case the irq_startup()/irq_shutdown() callbacks are not implemented for
the parent interrupt chip, this will fallback to irq_chip_enable_parent()
or irq_chip_disable_parent().

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Chen Wang <unicorn_wang@outlook.com> # Pioneerbox
Reviewed-by: Chen Wang <unicorn_wang@outlook.com>
Link: https://lore.kernel.org/all/20250813232835.43458-2-inochiama@gmail.com
Link: https://lore.kernel.org/lkml/20250722224513.22125-1-inochiama@gmail.com/

authored by

Inochi Amaoto and committed by
Thomas Gleixner
7a721a2f 3c716487

+39
+2
include/linux/irq.h
··· 669 669 extern int irq_chip_get_parent_state(struct irq_data *data, 670 670 enum irqchip_irq_state which, 671 671 bool *state); 672 + extern void irq_chip_shutdown_parent(struct irq_data *data); 673 + extern unsigned int irq_chip_startup_parent(struct irq_data *data); 672 674 extern void irq_chip_enable_parent(struct irq_data *data); 673 675 extern void irq_chip_disable_parent(struct irq_data *data); 674 676 extern void irq_chip_ack_parent(struct irq_data *data);
+37
kernel/irq/chip.c
··· 1260 1260 EXPORT_SYMBOL_GPL(irq_chip_get_parent_state); 1261 1261 1262 1262 /** 1263 + * irq_chip_shutdown_parent - Shutdown the parent interrupt 1264 + * @data: Pointer to interrupt specific data 1265 + * 1266 + * Invokes the irq_shutdown() callback of the parent if available or falls 1267 + * back to irq_chip_disable_parent(). 1268 + */ 1269 + void irq_chip_shutdown_parent(struct irq_data *data) 1270 + { 1271 + struct irq_data *parent = data->parent_data; 1272 + 1273 + if (parent->chip->irq_shutdown) 1274 + parent->chip->irq_shutdown(parent); 1275 + else 1276 + irq_chip_disable_parent(data); 1277 + } 1278 + EXPORT_SYMBOL_GPL(irq_chip_shutdown_parent); 1279 + 1280 + /** 1281 + * irq_chip_startup_parent - Startup the parent interrupt 1282 + * @data: Pointer to interrupt specific data 1283 + * 1284 + * Invokes the irq_startup() callback of the parent if available or falls 1285 + * back to irq_chip_enable_parent(). 1286 + */ 1287 + unsigned int irq_chip_startup_parent(struct irq_data *data) 1288 + { 1289 + struct irq_data *parent = data->parent_data; 1290 + 1291 + if (parent->chip->irq_startup) 1292 + return parent->chip->irq_startup(parent); 1293 + 1294 + irq_chip_enable_parent(data); 1295 + return 0; 1296 + } 1297 + EXPORT_SYMBOL_GPL(irq_chip_startup_parent); 1298 + 1299 + /** 1263 1300 * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if 1264 1301 * NULL) 1265 1302 * @data: Pointer to interrupt specific data