diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 51c782600e0260054ffab6121a0afbcede078de0..435ae723a238590b74c7ce6743394d90b2c675ab 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -174,6 +174,7 @@ extern void clear_IO_APIC(void); extern void restore_boot_irq_mode(void); extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin); extern void print_IO_APICs(void); +extern void ioapic_sync_hardware_data(int irq); #else /* !CONFIG_X86_IO_APIC */ #define IO_APIC_IRQ(x) 0 diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 00da6cf6b07dcb5551a0b2c5faeea60d0fb07307..d256e0b57e94035f88561b7824a6b61b0ef5843b 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1202,6 +1202,31 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) } EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); +/* + * The function is only provided for Drivers to keep the data value in + * memory consistent with the value of the register, and these drivers + * must use it carefully. + * + * The correct step should be: + * Change register ---> ioapic_sync_hardware_data ---> request_irq + */ +void ioapic_sync_hardware_data(int irq) +{ + struct IO_APIC_route_entry entry; + struct mp_chip_data *data; + struct irq_pin_list *pin_list; + + data = irq_get_chip_data(irq); + for_each_irq_pin(pin_list, data->irq_2_pin) { + entry = ioapic_read_entry(pin_list->apic, pin_list->pin); + data->entry.trigger = entry.trigger; + data->entry.polarity = entry.polarity; + pr_debug("irq[%d] update trigger[%d] polarity[%d]\n", + irq, entry.trigger, entry.polarity); + } +} +EXPORT_SYMBOL(ioapic_sync_hardware_data); + static struct irq_chip ioapic_chip, ioapic_ir_chip; static void __init setup_IO_APIC_irqs(void)