From: Hongbo Yao yaohongbo@huawei.com
hulk inclusion category: bugfix bugzilla: 20890, https://gitee.com/openeuler/kernel/issues/I5ZV1W
--------------------------------
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 Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Zhang Jianhua chris.zjh@huawei.com Reviewed-by: Liao Chang liaochang1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@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 a1a26f6d3aa4..294b99f1a84a 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -195,6 +195,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 25b1d5c6af96..34bc1e3325a8 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1201,6 +1201,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)