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:
parent
3c71648793
commit
7a721a2fee
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user