mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 13:03:25 +01:00
ACPI: OSL: Use a threaded interrupt handler for SCI
In the current arrangement, all of the acpi_ev_sci_xrupt_handler() code is run as an interrupt handler for the SCI, in interrupt context. Among other things, this causes it to run with local interrupts off which can be problematic if many GPEs are enabled and they are located in the I/O address space, for example (because in that case local interrupts will be off for the duration of all of the GPE hardware accesses carried out while handling an SCI combined and that may be quite a bit of time in extreme scenarios). However, there is no particular reason why the code in question really needs to run in interrupt context and in particular, it has no specific reason to run with local interrupts off. The only real requirement is to prevent multiple instences of it from running in parallel with each other, but that can be achieved regardless. For this reason, use request_threaded_irq() instead of request_irq() for the ACPI SCI and pass IRQF_ONESHOT to it in flags to indicate that the interrupt needs to be masked while its handling thread is running so as to prevent it from re-triggering while it is being handled (and in particular until the final handled/not handled outcome is determined). While at it, drop a redundant local variable from acpi_irq(). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mario Limonciello <mario.limonciello@amd.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
2cc14f52ae
commit
7a36b901a6
1 changed files with 3 additions and 6 deletions
|
@ -544,11 +544,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
|
|||
|
||||
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
||||
{
|
||||
u32 handled;
|
||||
|
||||
handled = (*acpi_irq_handler) (acpi_irq_context);
|
||||
|
||||
if (handled) {
|
||||
if ((*acpi_irq_handler)(acpi_irq_context)) {
|
||||
acpi_irq_handled++;
|
||||
return IRQ_HANDLED;
|
||||
} else {
|
||||
|
@ -582,7 +578,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
|
|||
|
||||
acpi_irq_handler = handler;
|
||||
acpi_irq_context = context;
|
||||
if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
|
||||
if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED | IRQF_ONESHOT,
|
||||
"acpi", acpi_irq)) {
|
||||
pr_err("SCI (IRQ%d) allocation failed\n", irq);
|
||||
acpi_irq_handler = NULL;
|
||||
return AE_NOT_ACQUIRED;
|
||||
|
|
Loading…
Reference in a new issue