1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-12 01:20:14 +00:00

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/
This commit is contained in:
Inochi Amaoto 2025-08-14 07:28:31 +08:00 committed by Thomas Gleixner
parent 3c71648793
commit 7a721a2fee
2 changed files with 39 additions and 0 deletions

View File

@ -669,6 +669,8 @@ extern int irq_chip_set_parent_state(struct irq_data *data,
extern int irq_chip_get_parent_state(struct irq_data *data,
enum irqchip_irq_state which,
bool *state);
extern void irq_chip_shutdown_parent(struct irq_data *data);
extern unsigned int irq_chip_startup_parent(struct irq_data *data);
extern void irq_chip_enable_parent(struct irq_data *data);
extern void irq_chip_disable_parent(struct irq_data *data);
extern void irq_chip_ack_parent(struct irq_data *data);

View File

@ -1259,6 +1259,43 @@ int irq_chip_get_parent_state(struct irq_data *data,
}
EXPORT_SYMBOL_GPL(irq_chip_get_parent_state);
/**
* irq_chip_shutdown_parent - Shutdown the parent interrupt
* @data: Pointer to interrupt specific data
*
* Invokes the irq_shutdown() callback of the parent if available or falls
* back to irq_chip_disable_parent().
*/
void irq_chip_shutdown_parent(struct irq_data *data)
{
struct irq_data *parent = data->parent_data;
if (parent->chip->irq_shutdown)
parent->chip->irq_shutdown(parent);
else
irq_chip_disable_parent(data);
}
EXPORT_SYMBOL_GPL(irq_chip_shutdown_parent);
/**
* irq_chip_startup_parent - Startup the parent interrupt
* @data: Pointer to interrupt specific data
*
* Invokes the irq_startup() callback of the parent if available or falls
* back to irq_chip_enable_parent().
*/
unsigned int irq_chip_startup_parent(struct irq_data *data)
{
struct irq_data *parent = data->parent_data;
if (parent->chip->irq_startup)
return parent->chip->irq_startup(parent);
irq_chip_enable_parent(data);
return 0;
}
EXPORT_SYMBOL_GPL(irq_chip_startup_parent);
/**
* irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
* NULL)