Commit bd973161 authored by Hongbo Yao's avatar Hongbo Yao Committed by Zheng Zengkai
Browse files

x86/ioapic: add an interface for driver to sync hardware data into memory

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: default avatarHongbo Yao <yaohongbo@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarLiao Chang <liaochang1@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 4ff8cda8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+25 −0
Original line number Diff line number Diff line
@@ -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)