From f32eeba925980e41373babec930dede2624bd9ed Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Wed, 4 Mar 2020 16:01:39 -0800 Subject: [PATCH] dts: x86: configure different IO APIC delivery modes for various devices For HPET devices, configure it with fixed delivery mode because HPET timer interrupt is needed to fuel the scheduler for all CPUS. For all other type of devices, like UART, I2C, GPIO, Ethernet, etc. configure them as lowest priority delivery mode, in which IO APIC delivers the interrupt to the processor core that is executing at the lowest priority among all the processors listed in the specified destination. In this case, the device drivers can avoid the trouble of handling repeated interrupts delivered to all CPUS. Signed-off-by: Zide Chen --- boards/x86/gpmrb/gpmrb.dts | 8 ++-- boards/x86/qemu_x86/qemu_x86.dts | 2 +- dts/x86/apollo_lake.dtsi | 46 +++++++++---------- dts/x86/atom.dtsi | 6 +-- dts/x86/ia32.dtsi | 6 +-- dts/xtensa/intel/intel_s1000.dtsi | 2 +- .../interrupt-controller/intel-ioapic.h | 21 +++++++-- 7 files changed, 52 insertions(+), 39 deletions(-) diff --git a/boards/x86/gpmrb/gpmrb.dts b/boards/x86/gpmrb/gpmrb.dts index 433bafa78fc..16809acffe0 100644 --- a/boards/x86/gpmrb/gpmrb.dts +++ b/boards/x86/gpmrb/gpmrb.dts @@ -26,7 +26,7 @@ }; }; -&uart0 { interrupts = <4 IRQ_TYPE_LEVEL_LOW 3>; }; -&uart1 { interrupts = <5 IRQ_TYPE_LEVEL_LOW 3>; }; -&uart2 { interrupts = <6 IRQ_TYPE_LEVEL_LOW 3>; }; -&uart3 { interrupts = <7 IRQ_TYPE_LEVEL_LOW 3>; }; +&uart0 { interrupts = <4 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; +&uart1 { interrupts = <5 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; +&uart2 { interrupts = <6 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; +&uart3 { interrupts = <7 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 9c5d2457e1a..7a998d1c993 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -41,7 +41,7 @@ compatible = "intel,e1000"; reg = <0xfebc0000 0x100>; label = "eth0"; - interrupts = <11 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <11 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; status = "okay"; diff --git a/dts/x86/apollo_lake.dtsi b/dts/x86/apollo_lake.dtsi index db898514ce6..c4f41f8fa39 100644 --- a/dts/x86/apollo_lake.dtsi +++ b/dts/x86/apollo_lake.dtsi @@ -49,7 +49,7 @@ label = "UART_0"; clock-frequency = <1843200>; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; current-speed = <115200>; @@ -63,7 +63,7 @@ label = "UART_1"; clock-frequency = <1843200>; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; @@ -78,7 +78,7 @@ label = "UART_2"; clock-frequency = <1843200>; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; @@ -93,7 +93,7 @@ label = "UART_3"; clock-frequency = <1843200>; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; status = "okay"; @@ -107,7 +107,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_0"; @@ -121,7 +121,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_1"; @@ -135,7 +135,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_2"; @@ -149,7 +149,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_3"; @@ -163,7 +163,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_4"; @@ -177,7 +177,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_5"; @@ -191,7 +191,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_6"; @@ -205,7 +205,7 @@ #size-cells = <0>; pcie; reg = ; - interrupts = ; + interrupts = ; interrupt-parent = <&intc>; label = "I2C_7"; @@ -215,7 +215,7 @@ gpio_n_000_031: gpio@d0c50000 { compatible = "intel,apl-gpio"; reg = <0xd0c50000 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_N_000"; @@ -231,7 +231,7 @@ gpio_n_032_063: gpio@d0c50001 { compatible = "intel,apl-gpio"; reg = <0xd0c50001 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_N_032"; @@ -247,7 +247,7 @@ gpio_n_064_077: gpio@d0c50002 { compatible = "intel,apl-gpio"; reg = <0xd0c50002 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_N_064"; @@ -263,7 +263,7 @@ gpio_nw_000_031: gpio@d0c40000 { compatible = "intel,apl-gpio"; reg = <0xd0c40000 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_NW_000"; @@ -279,7 +279,7 @@ gpio_nw_032_063: gpio@d0c40001 { compatible = "intel,apl-gpio"; reg = <0xd0c40001 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_NW_032"; @@ -295,7 +295,7 @@ gpio_nw_064_076: gpio@d0c40002 { compatible = "intel,apl-gpio"; reg = <0xd0c40002 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_NW_064"; @@ -311,7 +311,7 @@ gpio_w_000_031: gpio@d0c70000 { compatible = "intel,apl-gpio"; reg = <0xd0c70000 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_W_000"; @@ -327,7 +327,7 @@ gpio_w_032_046: gpio@d0c70001 { compatible = "intel,apl-gpio"; reg = <0xd0c70001 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_W_032"; @@ -343,7 +343,7 @@ gpio_sw_000_031: gpio@d0c00000 { compatible = "intel,apl-gpio"; reg = <0xd0c00000 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_SW_000"; @@ -360,7 +360,7 @@ gpio_sw_032_042: gpio@d0c00001 { compatible = "intel,apl-gpio"; reg = <0xd0c00001 0x1000>; - interrupts = <14 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <14 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; interrupt-parent = <&intc>; label = "GPIO_SW_032"; @@ -377,7 +377,7 @@ label = "HPET"; compatible = "intel,hpet"; reg = <0xfed00000 0x400>; - interrupts = <2 IRQ_TYPE_EDGE_RISING 4>; + interrupts = <2 IRQ_TYPE_FIXED_EDGE_RISING 4>; interrupt-parent = <&intc>; status = "okay"; diff --git a/dts/x86/atom.dtsi b/dts/x86/atom.dtsi index d863196debc..c1d37aad5e4 100644 --- a/dts/x86/atom.dtsi +++ b/dts/x86/atom.dtsi @@ -44,7 +44,7 @@ reg = <0x000003f8 0x100>; label = "UART_0"; clock-frequency = <1843200>; - interrupts = <4 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; status = "disabled"; @@ -55,7 +55,7 @@ reg = <0x000002f8 0x100>; label = "UART_1"; clock-frequency = <1843200>; - interrupts = <3 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; status = "disabled"; @@ -65,7 +65,7 @@ label = "HPET"; compatible = "intel,hpet"; reg = <0xfed00000 0x400>; - interrupts = <2 IRQ_TYPE_EDGE_RISING 4>; + interrupts = <2 IRQ_TYPE_FIXED_EDGE_RISING 4>; interrupt-parent = <&intc>; status = "disabled"; diff --git a/dts/x86/ia32.dtsi b/dts/x86/ia32.dtsi index ddfb376d917..844103b1548 100644 --- a/dts/x86/ia32.dtsi +++ b/dts/x86/ia32.dtsi @@ -44,7 +44,7 @@ reg = <0x000003f8 0x100>; label = "UART_0"; clock-frequency = <1843200>; - interrupts = <4 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; status = "disabled"; @@ -55,7 +55,7 @@ reg = <0x000002f8 0x100>; label = "UART_1"; clock-frequency = <1843200>; - interrupts = <3 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; status = "disabled"; @@ -65,7 +65,7 @@ label = "HPET"; compatible = "intel,hpet"; reg = <0xfed00000 0x400>; - interrupts = <2 IRQ_TYPE_EDGE_RISING 4>; + interrupts = <2 IRQ_TYPE_FIXED_EDGE_RISING 4>; interrupt-parent = <&intc>; status = "disabled"; diff --git a/dts/xtensa/intel/intel_s1000.dtsi b/dts/xtensa/intel/intel_s1000.dtsi index c969de4cb80..da3955045e2 100644 --- a/dts/xtensa/intel/intel_s1000.dtsi +++ b/dts/xtensa/intel/intel_s1000.dtsi @@ -199,7 +199,7 @@ usb: usb@a0000 { compatible = "snps,designware-usb"; reg = <0x000A0000 0x1000>; - interrupts = <0x07 IRQ_TYPE_EDGE_RISING 3>; + interrupts = <0x07 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&cavs0>; num-bidir-endpoints = <6>; label = "USB_0"; diff --git a/include/dt-bindings/interrupt-controller/intel-ioapic.h b/include/dt-bindings/interrupt-controller/intel-ioapic.h index 493cfb807a3..8637c6de7ef 100644 --- a/include/dt-bindings/interrupt-controller/intel-ioapic.h +++ b/include/dt-bindings/interrupt-controller/intel-ioapic.h @@ -10,9 +10,22 @@ #define IRQ_TYPE_EDGE 0x00000000 #define IRQ_TYPE_LOW 0x00002000 #define IRQ_TYPE_HIGH 0x00000000 -#define IRQ_TYPE_EDGE_RISING (IRQ_TYPE_EDGE | IRQ_TYPE_HIGH) -#define IRQ_TYPE_EDGE_FALLING (IRQ_TYPE_EDGE | IRQ_TYPE_LOW) -#define IRQ_TYPE_LEVEL_HIGH (IRQ_TYPE_LEVEL | IRQ_TYPE_HIGH) -#define IRQ_TYPE_LEVEL_LOW (IRQ_TYPE_LEVEL | IRQ_TYPE_LOW) +#define IRQ_DELIVERY_LOWEST 0x00000100 +#define IRQ_DELIVERY_FIXED 0x00000000 + +/* + * for most device interrupts, lowest priority delivery is preferred + * since this ensures only one CPU gets the interrupt in SMP systems. + */ +#define IRQ_TYPE_LOWEST_EDGE_RISING (IRQ_DELIVERY_LOWEST | IRQ_TYPE_EDGE | IRQ_TYPE_HIGH) +#define IRQ_TYPE_LOWEST_EDGE_FALLING (IRQ_DELIVERY_LOWEST | IRQ_TYPE_EDGE | IRQ_TYPE_LOW) +#define IRQ_TYPE_LOWEST_LEVEL_HIGH (IRQ_DELIVERY_LOWEST | IRQ_TYPE_LEVEL | IRQ_TYPE_HIGH) +#define IRQ_TYPE_LOWEST_LEVEL_LOW (IRQ_DELIVERY_LOWEST | IRQ_TYPE_LEVEL | IRQ_TYPE_LOW) + +/* for interrupts that want to be delivered to all CPUs, e.g. HPET */ +#define IRQ_TYPE_FIXED_EDGE_RISING (IRQ_DELIVERY_FIXED | IRQ_TYPE_EDGE | IRQ_TYPE_HIGH) +#define IRQ_TYPE_FIXED_EDGE_FALLING (IRQ_DELIVERY_FIXED | IRQ_TYPE_EDGE | IRQ_TYPE_LOW) +#define IRQ_TYPE_FIXED_LEVEL_HIGH (IRQ_DELIVERY_FIXED | IRQ_TYPE_LEVEL | IRQ_TYPE_HIGH) +#define IRQ_TYPE_FIXED_LEVEL_LOW (IRQ_DELIVERY_FIXED | IRQ_TYPE_LEVEL | IRQ_TYPE_LOW) #endif