From: Hongbo Yao yaohongbo@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8NV1E
--------------------------------
The default interrupt trigger mode of Pci driver is Level, however, some pci drivers want to change irq trigger mode to edge by writing hardware register directly. In current kernel, this kind of driver needs to sync entry data which has already been reservd in memory.
This patch provides an interface for the driver to sync entry data in memory.
Signed-off-by: Hongbo Yao yaohongbo@huawei.com Signed-off-by: Lin Yujun linyujun809@huawei.com --- arch/x86/include/asm/io_apic.h | 1 + arch/x86/kernel/apic/io_apic.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 51c782600e02..435ae723a238 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 00da6cf6b07d..d256e0b57e94 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)