aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-10-06 09:45:07 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-10-06 09:45:07 -0400
commita223464217737c6563c7986df67fe3b7a7aaff1e (patch)
tree3a7d6c9c355f77389adde7d169c8d16dfebcbba0
parent94967b55ebf3b603f2fe750ecedd896042585a1c (diff)
parent2130b789b3ef6a518b9c9c6f245642620e2b0c0c (diff)
Merge tag 'irqchip-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/core
Pull irqchip updates from Marc Zyngier: - kexec/kdump support for EFI-based GICv3 platforms - Marvell SEI support - QC PDC fixes - GIC cleanups and optimizations - DT updates [ tglx: Dropped the madera driver as it breaks the build ]
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/marvell,icu.txt85
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt36
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt5
-rw-r--r--arch/arm64/Kconfig.platforms1
-rw-r--r--drivers/base/platform-msi.c14
-rw-r--r--drivers/firmware/efi/efi.c59
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c27
-rw-r--r--drivers/irqchip/Kconfig3
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c249
-rw-r--r--drivers/irqchip/irq-gic-v3.c85
-rw-r--r--drivers/irqchip/irq-mvebu-icu.c253
-rw-r--r--drivers/irqchip/irq-mvebu-sei.c507
-rw-r--r--drivers/irqchip/qcom-pdc.c1
-rw-r--r--include/linux/efi.h9
-rw-r--r--include/linux/irqchip/arm-gic-common.h6
-rw-r--r--include/linux/irqchip/arm-gic-v3.h4
-rw-r--r--include/linux/irqchip/arm-gic.h5
-rw-r--r--include/linux/irqdomain.h1
-rw-r--r--include/linux/msi.h17
20 files changed, 1174 insertions, 194 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/marvell,icu.txt b/Documentation/devicetree/bindings/interrupt-controller/marvell,icu.txt
index aa8bf2ec8905..1c94a57a661e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/marvell,icu.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/marvell,icu.txt
@@ -5,6 +5,8 @@ The Marvell ICU (Interrupt Consolidation Unit) controller is
5responsible for collecting all wired-interrupt sources in the CP and 5responsible for collecting all wired-interrupt sources in the CP and
6communicating them to the GIC in the AP, the unit translates interrupt 6communicating them to the GIC in the AP, the unit translates interrupt
7requests on input wires to MSG memory mapped transactions to the GIC. 7requests on input wires to MSG memory mapped transactions to the GIC.
8These messages will access a different GIC memory area depending on
9their type (NSR, SR, SEI, REI, etc).
8 10
9Required properties: 11Required properties:
10 12
@@ -12,20 +14,23 @@ Required properties:
12 14
13- reg: Should contain ICU registers location and length. 15- reg: Should contain ICU registers location and length.
14 16
15- #interrupt-cells: Specifies the number of cells needed to encode an 17Subnodes: Each group of interrupt is declared as a subnode of the ICU,
16 interrupt source. The value shall be 3. 18with their own compatible.
19
20Required properties for the icu_nsr/icu_sei subnodes:
17 21
18 The 1st cell is the group type of the ICU interrupt. Possible group 22- compatible: Should be one of:
19 types are: 23 * "marvell,cp110-icu-nsr"
24 * "marvell,cp110-icu-sr"
25 * "marvell,cp110-icu-sei"
26 * "marvell,cp110-icu-rei"
20 27
21 ICU_GRP_NSR (0x0) : Shared peripheral interrupt, non-secure 28- #interrupt-cells: Specifies the number of cells needed to encode an
22 ICU_GRP_SR (0x1) : Shared peripheral interrupt, secure 29 interrupt source. The value shall be 2.
23 ICU_GRP_SEI (0x4) : System error interrupt
24 ICU_GRP_REI (0x5) : RAM error interrupt
25 30
26 The 2nd cell is the index of the interrupt in the ICU unit. 31 The 1st cell is the index of the interrupt in the ICU unit.
27 32
28 The 3rd cell is the type of the interrupt. See arm,gic.txt for 33 The 2nd cell is the type of the interrupt. See arm,gic.txt for
29 details. 34 details.
30 35
31- interrupt-controller: Identifies the node as an interrupt 36- interrupt-controller: Identifies the node as an interrupt
@@ -35,17 +40,73 @@ Required properties:
35 that allows to trigger interrupts using MSG memory mapped 40 that allows to trigger interrupts using MSG memory mapped
36 transactions. 41 transactions.
37 42
43Note: each 'interrupts' property referring to any 'icu_xxx' node shall
44 have a different number within [0:206].
45
38Example: 46Example:
39 47
40icu: interrupt-controller@1e0000 { 48icu: interrupt-controller@1e0000 {
41 compatible = "marvell,cp110-icu"; 49 compatible = "marvell,cp110-icu";
42 reg = <0x1e0000 0x10>; 50 reg = <0x1e0000 0x440>;
51
52 CP110_LABEL(icu_nsr): interrupt-controller@10 {
53 compatible = "marvell,cp110-icu-nsr";
54 reg = <0x10 0x20>;
55 #interrupt-cells = <2>;
56 interrupt-controller;
57 msi-parent = <&gicp>;
58 };
59
60 CP110_LABEL(icu_sei): interrupt-controller@50 {
61 compatible = "marvell,cp110-icu-sei";
62 reg = <0x50 0x10>;
63 #interrupt-cells = <2>;
64 interrupt-controller;
65 msi-parent = <&sei>;
66 };
67};
68
69node1 {
70 interrupt-parent = <&icu_nsr>;
71 interrupts = <106 IRQ_TYPE_LEVEL_HIGH>;
72};
73
74node2 {
75 interrupt-parent = <&icu_sei>;
76 interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
77};
78
79/* Would not work with the above nodes */
80node3 {
81 interrupt-parent = <&icu_nsr>;
82 interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
83};
84
85The legacy bindings were different in this way:
86
87- #interrupt-cells: The value was 3.
88 The 1st cell was the group type of the ICU interrupt. Possible
89 group types were:
90 ICU_GRP_NSR (0x0) : Shared peripheral interrupt, non-secure
91 ICU_GRP_SR (0x1) : Shared peripheral interrupt, secure
92 ICU_GRP_SEI (0x4) : System error interrupt
93 ICU_GRP_REI (0x5) : RAM error interrupt
94 The 2nd cell was the index of the interrupt in the ICU unit.
95 The 3rd cell was the type of the interrupt. See arm,gic.txt for
96 details.
97
98Example:
99
100icu: interrupt-controller@1e0000 {
101 compatible = "marvell,cp110-icu";
102 reg = <0x1e0000 0x440>;
103
43 #interrupt-cells = <3>; 104 #interrupt-cells = <3>;
44 interrupt-controller; 105 interrupt-controller;
45 msi-parent = <&gicp>; 106 msi-parent = <&gicp>;
46}; 107};
47 108
48usb3h0: usb3@500000 { 109node1 {
49 interrupt-parent = <&icu>; 110 interrupt-parent = <&icu>;
50 interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>; 111 interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
51}; 112};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt b/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt
new file mode 100644
index 000000000000..0beafed502f5
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt
@@ -0,0 +1,36 @@
1Marvell SEI (System Error Interrupt) Controller
2-----------------------------------------------
3
4Marvell SEI (System Error Interrupt) controller is an interrupt
5aggregator. It receives interrupts from several sources and aggregates
6them to a single interrupt line (an SPI) on the parent interrupt
7controller.
8
9This interrupt controller can handle up to 64 SEIs, a set comes from the
10AP and is wired while a second set comes from the CPs by the mean of
11MSIs.
12
13Required properties:
14
15- compatible: should be one of:
16 * "marvell,ap806-sei"
17- reg: SEI registers location and length.
18- interrupts: identifies the parent IRQ that will be triggered.
19- #interrupt-cells: number of cells to define an SEI wired interrupt
20 coming from the AP, should be 1. The cell is the IRQ
21 number.
22- interrupt-controller: identifies the node as an interrupt controller
23 for AP interrupts.
24- msi-controller: identifies the node as an MSI controller for the CPs
25 interrupts.
26
27Example:
28
29 sei: interrupt-controller@3f0200 {
30 compatible = "marvell,ap806-sei";
31 reg = <0x3f0200 0x40>;
32 interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
33 #interrupt-cells = <1>;
34 interrupt-controller;
35 msi-controller;
36 };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
index a046ed374d80..8de96a4fb2d5 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
@@ -2,10 +2,12 @@ DT bindings for the R-Mobile/R-Car/RZ/G interrupt controller
2 2
3Required properties: 3Required properties:
4 4
5- compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. 5- compatible: must be "renesas,irqc-<soctype>" or "renesas,intc-ex-<soctype>",
6 and "renesas,irqc" as fallback.
6 Examples with soctypes are: 7 Examples with soctypes are:
7 - "renesas,irqc-r8a73a4" (R-Mobile APE6) 8 - "renesas,irqc-r8a73a4" (R-Mobile APE6)
8 - "renesas,irqc-r8a7743" (RZ/G1M) 9 - "renesas,irqc-r8a7743" (RZ/G1M)
10 - "renesas,irqc-r8a7744" (RZ/G1N)
9 - "renesas,irqc-r8a7745" (RZ/G1E) 11 - "renesas,irqc-r8a7745" (RZ/G1E)
10 - "renesas,irqc-r8a77470" (RZ/G1C) 12 - "renesas,irqc-r8a77470" (RZ/G1C)
11 - "renesas,irqc-r8a7790" (R-Car H2) 13 - "renesas,irqc-r8a7790" (R-Car H2)
@@ -19,6 +21,7 @@ Required properties:
19 - "renesas,intc-ex-r8a77965" (R-Car M3-N) 21 - "renesas,intc-ex-r8a77965" (R-Car M3-N)
20 - "renesas,intc-ex-r8a77970" (R-Car V3M) 22 - "renesas,intc-ex-r8a77970" (R-Car V3M)
21 - "renesas,intc-ex-r8a77980" (R-Car V3H) 23 - "renesas,intc-ex-r8a77980" (R-Car V3H)
24 - "renesas,intc-ex-r8a77990" (R-Car E3)
22 - "renesas,intc-ex-r8a77995" (R-Car D3) 25 - "renesas,intc-ex-r8a77995" (R-Car D3)
23- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in 26- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
24 interrupts.txt in this directory 27 interrupts.txt in this directory
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 393d2b524284..5a89a957641b 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -128,6 +128,7 @@ config ARCH_MVEBU
128 select MVEBU_ICU 128 select MVEBU_ICU
129 select MVEBU_ODMI 129 select MVEBU_ODMI
130 select MVEBU_PIC 130 select MVEBU_PIC
131 select MVEBU_SEI
131 select OF_GPIO 132 select OF_GPIO
132 select PINCTRL 133 select PINCTRL
133 select PINCTRL_ARMADA_37XX 134 select PINCTRL_ARMADA_37XX
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 60d6cc618f1c..f39a920496fb 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -321,11 +321,12 @@ void *platform_msi_get_host_data(struct irq_domain *domain)
321 * Returns an irqdomain for @nvec interrupts 321 * Returns an irqdomain for @nvec interrupts
322 */ 322 */
323struct irq_domain * 323struct irq_domain *
324platform_msi_create_device_domain(struct device *dev, 324__platform_msi_create_device_domain(struct device *dev,
325 unsigned int nvec, 325 unsigned int nvec,
326 irq_write_msi_msg_t write_msi_msg, 326 bool is_tree,
327 const struct irq_domain_ops *ops, 327 irq_write_msi_msg_t write_msi_msg,
328 void *host_data) 328 const struct irq_domain_ops *ops,
329 void *host_data)
329{ 330{
330 struct platform_msi_priv_data *data; 331 struct platform_msi_priv_data *data;
331 struct irq_domain *domain; 332 struct irq_domain *domain;
@@ -336,7 +337,8 @@ platform_msi_create_device_domain(struct device *dev,
336 return NULL; 337 return NULL;
337 338
338 data->host_data = host_data; 339 data->host_data = host_data;
339 domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec, 340 domain = irq_domain_create_hierarchy(dev->msi_domain, 0,
341 is_tree ? 0 : nvec,
340 dev->fwnode, ops, data); 342 dev->fwnode, ops, data);
341 if (!domain) 343 if (!domain)
342 goto free_priv; 344 goto free_priv;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 2a29dd9c986d..249eb70691b0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -52,7 +52,8 @@ struct efi __read_mostly efi = {
52 .properties_table = EFI_INVALID_TABLE_ADDR, 52 .properties_table = EFI_INVALID_TABLE_ADDR,
53 .mem_attr_table = EFI_INVALID_TABLE_ADDR, 53 .mem_attr_table = EFI_INVALID_TABLE_ADDR,
54 .rng_seed = EFI_INVALID_TABLE_ADDR, 54 .rng_seed = EFI_INVALID_TABLE_ADDR,
55 .tpm_log = EFI_INVALID_TABLE_ADDR 55 .tpm_log = EFI_INVALID_TABLE_ADDR,
56 .mem_reserve = EFI_INVALID_TABLE_ADDR,
56}; 57};
57EXPORT_SYMBOL(efi); 58EXPORT_SYMBOL(efi);
58 59
@@ -484,6 +485,7 @@ static __initdata efi_config_table_type_t common_tables[] = {
484 {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table}, 485 {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
485 {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed}, 486 {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed},
486 {LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log}, 487 {LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log},
488 {LINUX_EFI_MEMRESERVE_TABLE_GUID, "MEMRESERVE", &efi.mem_reserve},
487 {NULL_GUID, NULL, NULL}, 489 {NULL_GUID, NULL, NULL},
488}; 490};
489 491
@@ -591,6 +593,29 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
591 early_memunmap(tbl, sizeof(*tbl)); 593 early_memunmap(tbl, sizeof(*tbl));
592 } 594 }
593 595
596 if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
597 unsigned long prsv = efi.mem_reserve;
598
599 while (prsv) {
600 struct linux_efi_memreserve *rsv;
601
602 /* reserve the entry itself */
603 memblock_reserve(prsv, sizeof(*rsv));
604
605 rsv = early_memremap(prsv, sizeof(*rsv));
606 if (rsv == NULL) {
607 pr_err("Could not map UEFI memreserve entry!\n");
608 return -ENOMEM;
609 }
610
611 if (rsv->size)
612 memblock_reserve(rsv->base, rsv->size);
613
614 prsv = rsv->next;
615 early_memunmap(rsv, sizeof(*rsv));
616 }
617 }
618
594 return 0; 619 return 0;
595} 620}
596 621
@@ -937,6 +962,38 @@ bool efi_is_table_address(unsigned long phys_addr)
937 return false; 962 return false;
938} 963}
939 964
965static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
966
967int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
968{
969 struct linux_efi_memreserve *rsv, *parent;
970
971 if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
972 return -ENODEV;
973
974 rsv = kmalloc(sizeof(*rsv), GFP_KERNEL);
975 if (!rsv)
976 return -ENOMEM;
977
978 parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
979 if (!parent) {
980 kfree(rsv);
981 return -ENOMEM;
982 }
983
984 rsv->base = addr;
985 rsv->size = size;
986
987 spin_lock(&efi_mem_reserve_persistent_lock);
988 rsv->next = parent->next;
989 parent->next = __pa(rsv);
990 spin_unlock(&efi_mem_reserve_persistent_lock);
991
992 memunmap(parent);
993
994 return 0;
995}
996
940#ifdef CONFIG_KEXEC 997#ifdef CONFIG_KEXEC
941static int update_efi_random_seed(struct notifier_block *nb, 998static int update_efi_random_seed(struct notifier_block *nb,
942 unsigned long code, void *unused) 999 unsigned long code, void *unused)
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 6920033de6d4..30ac0c975f8a 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -69,6 +69,31 @@ static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg)
69 return si; 69 return si;
70} 70}
71 71
72void install_memreserve_table(efi_system_table_t *sys_table_arg)
73{
74 struct linux_efi_memreserve *rsv;
75 efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
76 efi_status_t status;
77
78 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
79 (void **)&rsv);
80 if (status != EFI_SUCCESS) {
81 pr_efi_err(sys_table_arg, "Failed to allocate memreserve entry!\n");
82 return;
83 }
84
85 rsv->next = 0;
86 rsv->base = 0;
87 rsv->size = 0;
88
89 status = efi_call_early(install_configuration_table,
90 &memreserve_table_guid,
91 rsv);
92 if (status != EFI_SUCCESS)
93 pr_efi_err(sys_table_arg, "Failed to install memreserve config table!\n");
94}
95
96
72/* 97/*
73 * This function handles the architcture specific differences between arm and 98 * This function handles the architcture specific differences between arm and
74 * arm64 regarding where the kernel image must be loaded and any memory that 99 * arm64 regarding where the kernel image must be loaded and any memory that
@@ -235,6 +260,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
235 } 260 }
236 } 261 }
237 262
263 install_memreserve_table(sys_table);
264
238 new_fdt_addr = fdt_addr; 265 new_fdt_addr = fdt_addr;
239 status = allocate_new_fdt_and_exit_boot(sys_table, handle, 266 status = allocate_new_fdt_and_exit_boot(sys_table, handle,
240 &new_fdt_addr, efi_get_max_fdt_addr(dram_base), 267 &new_fdt_addr, efi_get_max_fdt_addr(dram_base),
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b70221d..96451b581452 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -310,6 +310,9 @@ config MVEBU_ODMI
310config MVEBU_PIC 310config MVEBU_PIC
311 bool 311 bool
312 312
313config MVEBU_SEI
314 bool
315
313config LS_SCFG_MSI 316config LS_SCFG_MSI
314 def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE 317 def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE
315 depends on PCI && PCI_MSI 318 depends on PCI && PCI_MSI
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8070ef..b822199445ff 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_MVEBU_GICP) += irq-mvebu-gicp.o
76obj-$(CONFIG_MVEBU_ICU) += irq-mvebu-icu.o 76obj-$(CONFIG_MVEBU_ICU) += irq-mvebu-icu.o
77obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o 77obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
78obj-$(CONFIG_MVEBU_PIC) += irq-mvebu-pic.o 78obj-$(CONFIG_MVEBU_PIC) += irq-mvebu-pic.o
79obj-$(CONFIG_MVEBU_SEI) += irq-mvebu-sei.o
79obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o 80obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o
80obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o 81obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
81obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o 82obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c2df341ff6fa..db20e992a40f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -19,13 +19,16 @@
19#include <linux/acpi_iort.h> 19#include <linux/acpi_iort.h>
20#include <linux/bitmap.h> 20#include <linux/bitmap.h>
21#include <linux/cpu.h> 21#include <linux/cpu.h>
22#include <linux/crash_dump.h>
22#include <linux/delay.h> 23#include <linux/delay.h>
23#include <linux/dma-iommu.h> 24#include <linux/dma-iommu.h>
25#include <linux/efi.h>
24#include <linux/interrupt.h> 26#include <linux/interrupt.h>
25#include <linux/irqdomain.h> 27#include <linux/irqdomain.h>
26#include <linux/list.h> 28#include <linux/list.h>
27#include <linux/list_sort.h> 29#include <linux/list_sort.h>
28#include <linux/log2.h> 30#include <linux/log2.h>
31#include <linux/memblock.h>
29#include <linux/mm.h> 32#include <linux/mm.h>
30#include <linux/msi.h> 33#include <linux/msi.h>
31#include <linux/of.h> 34#include <linux/of.h>
@@ -52,6 +55,7 @@
52#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3) 55#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3)
53 56
54#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) 57#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
58#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
55 59
56static u32 lpi_id_bits; 60static u32 lpi_id_bits;
57 61
@@ -64,7 +68,7 @@ static u32 lpi_id_bits;
64#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K) 68#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
65#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) 69#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
66 70
67#define LPI_PROP_DEFAULT_PRIO 0xa0 71#define LPI_PROP_DEFAULT_PRIO GICD_INT_DEF_PRI
68 72
69/* 73/*
70 * Collection structure - just an ID, and a redistributor address to 74 * Collection structure - just an ID, and a redistributor address to
@@ -173,6 +177,7 @@ static DEFINE_RAW_SPINLOCK(vmovp_lock);
173static DEFINE_IDA(its_vpeid_ida); 177static DEFINE_IDA(its_vpeid_ida);
174 178
175#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) 179#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist))
180#define gic_data_rdist_cpu(cpu) (per_cpu_ptr(gic_rdists->rdist, cpu))
176#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) 181#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
177#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K) 182#define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
178 183
@@ -1028,7 +1033,7 @@ static inline u32 its_get_event_id(struct irq_data *d)
1028static void lpi_write_config(struct irq_data *d, u8 clr, u8 set) 1033static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
1029{ 1034{
1030 irq_hw_number_t hwirq; 1035 irq_hw_number_t hwirq;
1031 struct page *prop_page; 1036 void *va;
1032 u8 *cfg; 1037 u8 *cfg;
1033 1038
1034 if (irqd_is_forwarded_to_vcpu(d)) { 1039 if (irqd_is_forwarded_to_vcpu(d)) {
@@ -1036,7 +1041,7 @@ static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
1036 u32 event = its_get_event_id(d); 1041 u32 event = its_get_event_id(d);
1037 struct its_vlpi_map *map; 1042 struct its_vlpi_map *map;
1038 1043
1039 prop_page = its_dev->event_map.vm->vprop_page; 1044 va = page_address(its_dev->event_map.vm->vprop_page);
1040 map = &its_dev->event_map.vlpi_maps[event]; 1045 map = &its_dev->event_map.vlpi_maps[event];
1041 hwirq = map->vintid; 1046 hwirq = map->vintid;
1042 1047
@@ -1044,11 +1049,11 @@ static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
1044 map->properties &= ~clr; 1049 map->properties &= ~clr;
1045 map->properties |= set | LPI_PROP_GROUP1; 1050 map->properties |= set | LPI_PROP_GROUP1;
1046 } else { 1051 } else {
1047 prop_page = gic_rdists->prop_page; 1052 va = gic_rdists->prop_table_va;
1048 hwirq = d->hwirq; 1053 hwirq = d->hwirq;
1049 } 1054 }
1050 1055
1051 cfg = page_address(prop_page) + hwirq - 8192; 1056 cfg = va + hwirq - 8192;
1052 *cfg &= ~clr; 1057 *cfg &= ~clr;
1053 *cfg |= set | LPI_PROP_GROUP1; 1058 *cfg |= set | LPI_PROP_GROUP1;
1054 1059
@@ -1597,6 +1602,15 @@ static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids)
1597 kfree(bitmap); 1602 kfree(bitmap);
1598} 1603}
1599 1604
1605static void gic_reset_prop_table(void *va)
1606{
1607 /* Priority 0xa0, Group-1, disabled */
1608 memset(va, LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1, LPI_PROPBASE_SZ);
1609
1610 /* Make sure the GIC will observe the written configuration */
1611 gic_flush_dcache_to_poc(va, LPI_PROPBASE_SZ);
1612}
1613
1600static struct page *its_allocate_prop_table(gfp_t gfp_flags) 1614static struct page *its_allocate_prop_table(gfp_t gfp_flags)
1601{ 1615{
1602 struct page *prop_page; 1616 struct page *prop_page;
@@ -1605,13 +1619,7 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
1605 if (!prop_page) 1619 if (!prop_page)
1606 return NULL; 1620 return NULL;
1607 1621
1608 /* Priority 0xa0, Group-1, disabled */ 1622 gic_reset_prop_table(page_address(prop_page));
1609 memset(page_address(prop_page),
1610 LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
1611 LPI_PROPBASE_SZ);
1612
1613 /* Make sure the GIC will observe the written configuration */
1614 gic_flush_dcache_to_poc(page_address(prop_page), LPI_PROPBASE_SZ);
1615 1623
1616 return prop_page; 1624 return prop_page;
1617} 1625}
@@ -1622,20 +1630,74 @@ static void its_free_prop_table(struct page *prop_page)
1622 get_order(LPI_PROPBASE_SZ)); 1630 get_order(LPI_PROPBASE_SZ));
1623} 1631}
1624 1632
1625static int __init its_alloc_lpi_tables(void) 1633static bool gic_check_reserved_range(phys_addr_t addr, unsigned long size)
1626{ 1634{
1627 phys_addr_t paddr; 1635 phys_addr_t start, end, addr_end;
1636 u64 i;
1628 1637
1629 lpi_id_bits = min_t(u32, GICD_TYPER_ID_BITS(gic_rdists->gicd_typer), 1638 /*
1630 ITS_MAX_LPI_NRBITS); 1639 * We don't bother checking for a kdump kernel as by
1631 gic_rdists->prop_page = its_allocate_prop_table(GFP_NOWAIT); 1640 * construction, the LPI tables are out of this kernel's
1632 if (!gic_rdists->prop_page) { 1641 * memory map.
1633 pr_err("Failed to allocate PROPBASE\n"); 1642 */
1634 return -ENOMEM; 1643 if (is_kdump_kernel())
1644 return true;
1645
1646 addr_end = addr + size - 1;
1647
1648 for_each_reserved_mem_region(i, &start, &end) {
1649 if (addr >= start && addr_end <= end)
1650 return true;
1651 }
1652
1653 /* Not found, not a good sign... */
1654 pr_warn("GICv3: Expected reserved range [%pa:%pa], not found\n",
1655 &addr, &addr_end);
1656 add_taint(TAINT_CRAP, LOCKDEP_STILL_OK);
1657 return false;
1658}
1659
1660static int gic_reserve_range(phys_addr_t addr, unsigned long size)
1661{
1662 if (efi_enabled(EFI_CONFIG_TABLES))
1663 return efi_mem_reserve_persistent(addr, size);
1664
1665 return 0;
1666}
1667
1668static int __init its_setup_lpi_prop_table(void)
1669{
1670 if (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) {
1671 u64 val;
1672
1673 val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
1674 lpi_id_bits = (val & GICR_PROPBASER_IDBITS_MASK) + 1;
1675
1676 gic_rdists->prop_table_pa = val & GENMASK_ULL(51, 12);
1677 gic_rdists->prop_table_va = memremap(gic_rdists->prop_table_pa,
1678 LPI_PROPBASE_SZ,
1679 MEMREMAP_WB);
1680 gic_reset_prop_table(gic_rdists->prop_table_va);
1681 } else {
1682 struct page *page;
1683
1684 lpi_id_bits = min_t(u32,
1685 GICD_TYPER_ID_BITS(gic_rdists->gicd_typer),
1686 ITS_MAX_LPI_NRBITS);
1687 page = its_allocate_prop_table(GFP_NOWAIT);
1688 if (!page) {
1689 pr_err("Failed to allocate PROPBASE\n");
1690 return -ENOMEM;
1691 }
1692
1693 gic_rdists->prop_table_pa = page_to_phys(page);
1694 gic_rdists->prop_table_va = page_address(page);
1695 WARN_ON(gic_reserve_range(gic_rdists->prop_table_pa,
1696 LPI_PROPBASE_SZ));
1635 } 1697 }
1636 1698
1637 paddr = page_to_phys(gic_rdists->prop_page); 1699 pr_info("GICv3: using LPI property table @%pa\n",
1638 pr_info("GIC: using LPI property table @%pa\n", &paddr); 1700 &gic_rdists->prop_table_pa);
1639 1701
1640 return its_lpi_init(lpi_id_bits); 1702 return its_lpi_init(lpi_id_bits);
1641} 1703}
@@ -1924,12 +1986,9 @@ static int its_alloc_collections(struct its_node *its)
1924static struct page *its_allocate_pending_table(gfp_t gfp_flags) 1986static struct page *its_allocate_pending_table(gfp_t gfp_flags)
1925{ 1987{
1926 struct page *pend_page; 1988 struct page *pend_page;
1927 /* 1989
1928 * The pending pages have to be at least 64kB aligned,
1929 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
1930 */
1931 pend_page = alloc_pages(gfp_flags | __GFP_ZERO, 1990 pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
1932 get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); 1991 get_order(LPI_PENDBASE_SZ));
1933 if (!pend_page) 1992 if (!pend_page)
1934 return NULL; 1993 return NULL;
1935 1994
@@ -1941,36 +2000,103 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
1941 2000
1942static void its_free_pending_table(struct page *pt) 2001static void its_free_pending_table(struct page *pt)
1943{ 2002{
1944 free_pages((unsigned long)page_address(pt), 2003 free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ));
1945 get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); 2004}
2005
2006/*
2007 * Booting with kdump and LPIs enabled is generally fine. Any other
2008 * case is wrong in the absence of firmware/EFI support.
2009 */
2010static bool enabled_lpis_allowed(void)
2011{
2012 phys_addr_t addr;
2013 u64 val;
2014
2015 /* Check whether the property table is in a reserved region */
2016 val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
2017 addr = val & GENMASK_ULL(51, 12);
2018
2019 return gic_check_reserved_range(addr, LPI_PROPBASE_SZ);
2020}
2021
2022static int __init allocate_lpi_tables(void)
2023{
2024 u64 val;
2025 int err, cpu;
2026
2027 /*
2028 * If LPIs are enabled while we run this from the boot CPU,
2029 * flag the RD tables as pre-allocated if the stars do align.
2030 */
2031 val = readl_relaxed(gic_data_rdist_rd_base() + GICR_CTLR);
2032 if ((val & GICR_CTLR_ENABLE_LPIS) && enabled_lpis_allowed()) {
2033 gic_rdists->flags |= (RDIST_FLAGS_RD_TABLES_PREALLOCATED |
2034 RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING);
2035 pr_info("GICv3: Using preallocated redistributor tables\n");
2036 }
2037
2038 err = its_setup_lpi_prop_table();
2039 if (err)
2040 return err;
2041
2042 /*
2043 * We allocate all the pending tables anyway, as we may have a
2044 * mix of RDs that have had LPIs enabled, and some that
2045 * don't. We'll free the unused ones as each CPU comes online.
2046 */
2047 for_each_possible_cpu(cpu) {
2048 struct page *pend_page;
2049
2050 pend_page = its_allocate_pending_table(GFP_NOWAIT);
2051 if (!pend_page) {
2052 pr_err("Failed to allocate PENDBASE for CPU%d\n", cpu);
2053 return -ENOMEM;
2054 }
2055
2056 gic_data_rdist_cpu(cpu)->pend_page = pend_page;
2057 }
2058
2059 return 0;
1946} 2060}
1947 2061
1948static void its_cpu_init_lpis(void) 2062static void its_cpu_init_lpis(void)
1949{ 2063{
1950 void __iomem *rbase = gic_data_rdist_rd_base(); 2064 void __iomem *rbase = gic_data_rdist_rd_base();
1951 struct page *pend_page; 2065 struct page *pend_page;
2066 phys_addr_t paddr;
1952 u64 val, tmp; 2067 u64 val, tmp;
1953 2068
1954 /* If we didn't allocate the pending table yet, do it now */ 2069 if (gic_data_rdist()->lpi_enabled)
1955 pend_page = gic_data_rdist()->pend_page; 2070 return;
1956 if (!pend_page) {
1957 phys_addr_t paddr;
1958 2071
1959 pend_page = its_allocate_pending_table(GFP_NOWAIT); 2072 val = readl_relaxed(rbase + GICR_CTLR);
1960 if (!pend_page) { 2073 if ((gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) &&
1961 pr_err("Failed to allocate PENDBASE for CPU%d\n", 2074 (val & GICR_CTLR_ENABLE_LPIS)) {
1962 smp_processor_id()); 2075 /*
1963 return; 2076 * Check that we get the same property table on all
1964 } 2077 * RDs. If we don't, this is hopeless.
2078 */
2079 paddr = gicr_read_propbaser(rbase + GICR_PROPBASER);
2080 paddr &= GENMASK_ULL(51, 12);
2081 if (WARN_ON(gic_rdists->prop_table_pa != paddr))
2082 add_taint(TAINT_CRAP, LOCKDEP_STILL_OK);
2083
2084 paddr = gicr_read_pendbaser(rbase + GICR_PENDBASER);
2085 paddr &= GENMASK_ULL(51, 16);
1965 2086
1966 paddr = page_to_phys(pend_page); 2087 WARN_ON(!gic_check_reserved_range(paddr, LPI_PENDBASE_SZ));
1967 pr_info("CPU%d: using LPI pending table @%pa\n", 2088 its_free_pending_table(gic_data_rdist()->pend_page);
1968 smp_processor_id(), &paddr); 2089 gic_data_rdist()->pend_page = NULL;
1969 gic_data_rdist()->pend_page = pend_page; 2090
2091 goto out;
1970 } 2092 }
1971 2093
2094 pend_page = gic_data_rdist()->pend_page;
2095 paddr = page_to_phys(pend_page);
2096 WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ));
2097
1972 /* set PROPBASE */ 2098 /* set PROPBASE */
1973 val = (page_to_phys(gic_rdists->prop_page) | 2099 val = (gic_rdists->prop_table_pa |
1974 GICR_PROPBASER_InnerShareable | 2100 GICR_PROPBASER_InnerShareable |
1975 GICR_PROPBASER_RaWaWb | 2101 GICR_PROPBASER_RaWaWb |
1976 ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); 2102 ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
@@ -2020,6 +2146,12 @@ static void its_cpu_init_lpis(void)
2020 2146
2021 /* Make sure the GIC has seen the above */ 2147 /* Make sure the GIC has seen the above */
2022 dsb(sy); 2148 dsb(sy);
2149out:
2150 gic_data_rdist()->lpi_enabled = true;
2151 pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
2152 smp_processor_id(),
2153 gic_data_rdist()->pend_page ? "allocated" : "reserved",
2154 &paddr);
2023} 2155}
2024 2156
2025static void its_cpu_init_collection(struct its_node *its) 2157static void its_cpu_init_collection(struct its_node *its)
@@ -3498,16 +3630,6 @@ static int redist_disable_lpis(void)
3498 u64 timeout = USEC_PER_SEC; 3630 u64 timeout = USEC_PER_SEC;
3499 u64 val; 3631 u64 val;
3500 3632
3501 /*
3502 * If coming via a CPU hotplug event, we don't need to disable
3503 * LPIs before trying to re-enable them. They are already
3504 * configured and all is well in the world. Detect this case
3505 * by checking the allocation of the pending table for the
3506 * current CPU.
3507 */
3508 if (gic_data_rdist()->pend_page)
3509 return 0;
3510
3511 if (!gic_rdists_supports_plpis()) { 3633 if (!gic_rdists_supports_plpis()) {
3512 pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); 3634 pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
3513 return -ENXIO; 3635 return -ENXIO;
@@ -3517,7 +3639,21 @@ static int redist_disable_lpis(void)
3517 if (!(val & GICR_CTLR_ENABLE_LPIS)) 3639 if (!(val & GICR_CTLR_ENABLE_LPIS))
3518 return 0; 3640 return 0;
3519 3641
3520 pr_warn("CPU%d: Booted with LPIs enabled, memory probably corrupted\n", 3642 /*
3643 * If coming via a CPU hotplug event, we don't need to disable
3644 * LPIs before trying to re-enable them. They are already
3645 * configured and all is well in the world.
3646 *
3647 * If running with preallocated tables, there is nothing to do.
3648 */
3649 if (gic_data_rdist()->lpi_enabled ||
3650 (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED))
3651 return 0;
3652
3653 /*
3654 * From that point on, we only try to do some damage control.
3655 */
3656 pr_warn("GICv3: CPU%d: Booted with LPIs enabled, memory probably corrupted\n",
3521 smp_processor_id()); 3657 smp_processor_id());
3522 add_taint(TAINT_CRAP, LOCKDEP_STILL_OK); 3658 add_taint(TAINT_CRAP, LOCKDEP_STILL_OK);
3523 3659
@@ -3773,7 +3909,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
3773 } 3909 }
3774 3910
3775 gic_rdists = rdists; 3911 gic_rdists = rdists;
3776 err = its_alloc_lpi_tables(); 3912
3913 err = allocate_lpi_tables();
3777 if (err) 3914 if (err)
3778 return err; 3915 return err;
3779 3916
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d5912f1ec884..8f87f40c9460 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -348,48 +348,45 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
348{ 348{
349 u32 irqnr; 349 u32 irqnr;
350 350
351 do { 351 irqnr = gic_read_iar();
352 irqnr = gic_read_iar();
353 352
354 if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) { 353 if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
355 int err; 354 int err;
356 355
357 if (static_branch_likely(&supports_deactivate_key)) 356 if (static_branch_likely(&supports_deactivate_key))
357 gic_write_eoir(irqnr);
358 else
359 isb();
360
361 err = handle_domain_irq(gic_data.domain, irqnr, regs);
362 if (err) {
363 WARN_ONCE(true, "Unexpected interrupt received!\n");
364 if (static_branch_likely(&supports_deactivate_key)) {
365 if (irqnr < 8192)
366 gic_write_dir(irqnr);
367 } else {
358 gic_write_eoir(irqnr); 368 gic_write_eoir(irqnr);
359 else
360 isb();
361
362 err = handle_domain_irq(gic_data.domain, irqnr, regs);
363 if (err) {
364 WARN_ONCE(true, "Unexpected interrupt received!\n");
365 if (static_branch_likely(&supports_deactivate_key)) {
366 if (irqnr < 8192)
367 gic_write_dir(irqnr);
368 } else {
369 gic_write_eoir(irqnr);
370 }
371 } 369 }
372 continue;
373 } 370 }
374 if (irqnr < 16) { 371 return;
375 gic_write_eoir(irqnr); 372 }
376 if (static_branch_likely(&supports_deactivate_key)) 373 if (irqnr < 16) {
377 gic_write_dir(irqnr); 374 gic_write_eoir(irqnr);
375 if (static_branch_likely(&supports_deactivate_key))
376 gic_write_dir(irqnr);
378#ifdef CONFIG_SMP 377#ifdef CONFIG_SMP
379 /* 378 /*
380 * Unlike GICv2, we don't need an smp_rmb() here. 379 * Unlike GICv2, we don't need an smp_rmb() here.
381 * The control dependency from gic_read_iar to 380 * The control dependency from gic_read_iar to
382 * the ISB in gic_write_eoir is enough to ensure 381 * the ISB in gic_write_eoir is enough to ensure
383 * that any shared data read by handle_IPI will 382 * that any shared data read by handle_IPI will
384 * be read after the ACK. 383 * be read after the ACK.
385 */ 384 */
386 handle_IPI(irqnr, regs); 385 handle_IPI(irqnr, regs);
387#else 386#else
388 WARN_ONCE(true, "Unexpected SGI received!\n"); 387 WARN_ONCE(true, "Unexpected SGI received!\n");
389#endif 388#endif
390 continue; 389 }
391 }
392 } while (irqnr != ICC_IAR1_EL1_SPURIOUS);
393} 390}
394 391
395static void __init gic_dist_init(void) 392static void __init gic_dist_init(void)
@@ -653,7 +650,9 @@ early_param("irqchip.gicv3_nolpi", gicv3_nolpi_cfg);
653 650
654static int gic_dist_supports_lpis(void) 651static int gic_dist_supports_lpis(void)
655{ 652{
656 return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS) && !gicv3_nolpi; 653 return (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) &&
654 !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS) &&
655 !gicv3_nolpi);
657} 656}
658 657
659static void gic_cpu_init(void) 658static void gic_cpu_init(void)
@@ -673,10 +672,6 @@ static void gic_cpu_init(void)
673 672
674 gic_cpu_config(rbase, gic_redist_wait_for_rwp); 673 gic_cpu_config(rbase, gic_redist_wait_for_rwp);
675 674
676 /* Give LPIs a spin */
677 if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
678 its_cpu_init();
679
680 /* initialise system registers */ 675 /* initialise system registers */
681 gic_cpu_sys_reg_init(); 676 gic_cpu_sys_reg_init();
682} 677}
@@ -689,6 +684,10 @@ static void gic_cpu_init(void)
689static int gic_starting_cpu(unsigned int cpu) 684static int gic_starting_cpu(unsigned int cpu)
690{ 685{
691 gic_cpu_init(); 686 gic_cpu_init();
687
688 if (gic_dist_supports_lpis())
689 its_cpu_init();
690
692 return 0; 691 return 0;
693} 692}
694 693
@@ -1127,14 +1126,16 @@ static int __init gic_init_bases(void __iomem *dist_base,
1127 1126
1128 gic_update_vlpi_properties(); 1127 gic_update_vlpi_properties();
1129 1128
1130 if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
1131 its_init(handle, &gic_data.rdists, gic_data.domain);
1132
1133 gic_smp_init(); 1129 gic_smp_init();
1134 gic_dist_init(); 1130 gic_dist_init();
1135 gic_cpu_init(); 1131 gic_cpu_init();
1136 gic_cpu_pm_init(); 1132 gic_cpu_pm_init();
1137 1133
1134 if (gic_dist_supports_lpis()) {
1135 its_init(handle, &gic_data.rdists, gic_data.domain);
1136 its_cpu_init();
1137 }
1138
1138 return 0; 1139 return 0;
1139 1140
1140out_free: 1141out_free:
diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c
index 13063339b416..547045d89c4b 100644
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -13,6 +13,7 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/irqchip.h> 14#include <linux/irqchip.h>
15#include <linux/irqdomain.h> 15#include <linux/irqdomain.h>
16#include <linux/jump_label.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/msi.h> 18#include <linux/msi.h>
18#include <linux/of_irq.h> 19#include <linux/of_irq.h>
@@ -26,6 +27,10 @@
26#define ICU_SETSPI_NSR_AH 0x14 27#define ICU_SETSPI_NSR_AH 0x14
27#define ICU_CLRSPI_NSR_AL 0x18 28#define ICU_CLRSPI_NSR_AL 0x18
28#define ICU_CLRSPI_NSR_AH 0x1c 29#define ICU_CLRSPI_NSR_AH 0x1c
30#define ICU_SET_SEI_AL 0x50
31#define ICU_SET_SEI_AH 0x54
32#define ICU_CLR_SEI_AL 0x58
33#define ICU_CLR_SEI_AH 0x5C
29#define ICU_INT_CFG(x) (0x100 + 4 * (x)) 34#define ICU_INT_CFG(x) (0x100 + 4 * (x))
30#define ICU_INT_ENABLE BIT(24) 35#define ICU_INT_ENABLE BIT(24)
31#define ICU_IS_EDGE BIT(28) 36#define ICU_IS_EDGE BIT(28)
@@ -36,12 +41,23 @@
36#define ICU_SATA0_ICU_ID 109 41#define ICU_SATA0_ICU_ID 109
37#define ICU_SATA1_ICU_ID 107 42#define ICU_SATA1_ICU_ID 107
38 43
44struct mvebu_icu_subset_data {
45 unsigned int icu_group;
46 unsigned int offset_set_ah;
47 unsigned int offset_set_al;
48 unsigned int offset_clr_ah;
49 unsigned int offset_clr_al;
50};
51
39struct mvebu_icu { 52struct mvebu_icu {
40 struct irq_chip irq_chip;
41 void __iomem *base; 53 void __iomem *base;
42 struct irq_domain *domain;
43 struct device *dev; 54 struct device *dev;
55};
56
57struct mvebu_icu_msi_data {
58 struct mvebu_icu *icu;
44 atomic_t initialized; 59 atomic_t initialized;
60 const struct mvebu_icu_subset_data *subset_data;
45}; 61};
46 62
47struct mvebu_icu_irq_data { 63struct mvebu_icu_irq_data {
@@ -50,28 +66,40 @@ struct mvebu_icu_irq_data {
50 unsigned int type; 66 unsigned int type;
51}; 67};
52 68
53static void mvebu_icu_init(struct mvebu_icu *icu, struct msi_msg *msg) 69DEFINE_STATIC_KEY_FALSE(legacy_bindings);
70
71static void mvebu_icu_init(struct mvebu_icu *icu,
72 struct mvebu_icu_msi_data *msi_data,
73 struct msi_msg *msg)
54{ 74{
55 if (atomic_cmpxchg(&icu->initialized, false, true)) 75 const struct mvebu_icu_subset_data *subset = msi_data->subset_data;
76
77 if (atomic_cmpxchg(&msi_data->initialized, false, true))
56 return; 78 return;
57 79
58 /* Set Clear/Set ICU SPI message address in AP */ 80 /* Set 'SET' ICU SPI message address in AP */
59 writel_relaxed(msg[0].address_hi, icu->base + ICU_SETSPI_NSR_AH); 81 writel_relaxed(msg[0].address_hi, icu->base + subset->offset_set_ah);
60 writel_relaxed(msg[0].address_lo, icu->base + ICU_SETSPI_NSR_AL); 82 writel_relaxed(msg[0].address_lo, icu->base + subset->offset_set_al);
61 writel_relaxed(msg[1].address_hi, icu->base + ICU_CLRSPI_NSR_AH); 83
62 writel_relaxed(msg[1].address_lo, icu->base + ICU_CLRSPI_NSR_AL); 84 if (subset->icu_group != ICU_GRP_NSR)
85 return;
86
87 /* Set 'CLEAR' ICU SPI message address in AP (level-MSI only) */
88 writel_relaxed(msg[1].address_hi, icu->base + subset->offset_clr_ah);
89 writel_relaxed(msg[1].address_lo, icu->base + subset->offset_clr_al);
63} 90}
64 91
65static void mvebu_icu_write_msg(struct msi_desc *desc, struct msi_msg *msg) 92static void mvebu_icu_write_msg(struct msi_desc *desc, struct msi_msg *msg)
66{ 93{
67 struct irq_data *d = irq_get_irq_data(desc->irq); 94 struct irq_data *d = irq_get_irq_data(desc->irq);
95 struct mvebu_icu_msi_data *msi_data = platform_msi_get_host_data(d->domain);
68 struct mvebu_icu_irq_data *icu_irqd = d->chip_data; 96 struct mvebu_icu_irq_data *icu_irqd = d->chip_data;
69 struct mvebu_icu *icu = icu_irqd->icu; 97 struct mvebu_icu *icu = icu_irqd->icu;
70 unsigned int icu_int; 98 unsigned int icu_int;
71 99
72 if (msg->address_lo || msg->address_hi) { 100 if (msg->address_lo || msg->address_hi) {
73 /* One off initialization */ 101 /* One off initialization per domain */
74 mvebu_icu_init(icu, msg); 102 mvebu_icu_init(icu, msi_data, msg);
75 /* Configure the ICU with irq number & type */ 103 /* Configure the ICU with irq number & type */
76 icu_int = msg->data | ICU_INT_ENABLE; 104 icu_int = msg->data | ICU_INT_ENABLE;
77 if (icu_irqd->type & IRQ_TYPE_EDGE_RISING) 105 if (icu_irqd->type & IRQ_TYPE_EDGE_RISING)
@@ -101,37 +129,66 @@ static void mvebu_icu_write_msg(struct msi_desc *desc, struct msi_msg *msg)
101 } 129 }
102} 130}
103 131
132static struct irq_chip mvebu_icu_nsr_chip = {
133 .name = "ICU-NSR",
134 .irq_mask = irq_chip_mask_parent,
135 .irq_unmask = irq_chip_unmask_parent,
136 .irq_eoi = irq_chip_eoi_parent,
137 .irq_set_type = irq_chip_set_type_parent,
138 .irq_set_affinity = irq_chip_set_affinity_parent,
139};
140
141static struct irq_chip mvebu_icu_sei_chip = {
142 .name = "ICU-SEI",
143 .irq_ack = irq_chip_ack_parent,
144 .irq_mask = irq_chip_mask_parent,
145 .irq_unmask = irq_chip_unmask_parent,
146 .irq_set_type = irq_chip_set_type_parent,
147 .irq_set_affinity = irq_chip_set_affinity_parent,
148};
149
104static int 150static int
105mvebu_icu_irq_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec, 151mvebu_icu_irq_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
106 unsigned long *hwirq, unsigned int *type) 152 unsigned long *hwirq, unsigned int *type)
107{ 153{
108 struct mvebu_icu *icu = d->host_data; 154 struct mvebu_icu_msi_data *msi_data = platform_msi_get_host_data(d);
109 unsigned int icu_group; 155 struct mvebu_icu *icu = platform_msi_get_host_data(d);
156 unsigned int param_count = static_branch_unlikely(&legacy_bindings) ? 3 : 2;
110 157
111 /* Check the count of the parameters in dt */ 158 /* Check the count of the parameters in dt */
112 if (WARN_ON(fwspec->param_count < 3)) { 159 if (WARN_ON(fwspec->param_count != param_count)) {
113 dev_err(icu->dev, "wrong ICU parameter count %d\n", 160 dev_err(icu->dev, "wrong ICU parameter count %d\n",
114 fwspec->param_count); 161 fwspec->param_count);
115 return -EINVAL; 162 return -EINVAL;
116 } 163 }
117 164
118 /* Only ICU group type is handled */ 165 if (static_branch_unlikely(&legacy_bindings)) {
119 icu_group = fwspec->param[0]; 166 *hwirq = fwspec->param[1];
120 if (icu_group != ICU_GRP_NSR && icu_group != ICU_GRP_SR && 167 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
121 icu_group != ICU_GRP_SEI && icu_group != ICU_GRP_REI) { 168 if (fwspec->param[0] != ICU_GRP_NSR) {
122 dev_err(icu->dev, "wrong ICU group type %x\n", icu_group); 169 dev_err(icu->dev, "wrong ICU group type %x\n",
123 return -EINVAL; 170 fwspec->param[0]);
171 return -EINVAL;
172 }
173 } else {
174 *hwirq = fwspec->param[0];
175 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
176
177 /*
178 * The ICU receives level interrupts. While the NSR are also
179 * level interrupts, SEI are edge interrupts. Force the type
180 * here in this case. Please note that this makes the interrupt
181 * handling unreliable.
182 */
183 if (msi_data->subset_data->icu_group == ICU_GRP_SEI)
184 *type = IRQ_TYPE_EDGE_RISING;
124 } 185 }
125 186
126 *hwirq = fwspec->param[1];
127 if (*hwirq >= ICU_MAX_IRQS) { 187 if (*hwirq >= ICU_MAX_IRQS) {
128 dev_err(icu->dev, "invalid interrupt number %ld\n", *hwirq); 188 dev_err(icu->dev, "invalid interrupt number %ld\n", *hwirq);
129 return -EINVAL; 189 return -EINVAL;
130 } 190 }
131 191
132 /* Mask the type to prevent wrong DT configuration */
133 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
134
135 return 0; 192 return 0;
136} 193}
137 194
@@ -142,8 +199,10 @@ mvebu_icu_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
142 int err; 199 int err;
143 unsigned long hwirq; 200 unsigned long hwirq;
144 struct irq_fwspec *fwspec = args; 201 struct irq_fwspec *fwspec = args;
145 struct mvebu_icu *icu = platform_msi_get_host_data(domain); 202 struct mvebu_icu_msi_data *msi_data = platform_msi_get_host_data(domain);
203 struct mvebu_icu *icu = msi_data->icu;
146 struct mvebu_icu_irq_data *icu_irqd; 204 struct mvebu_icu_irq_data *icu_irqd;
205 struct irq_chip *chip = &mvebu_icu_nsr_chip;
147 206
148 icu_irqd = kmalloc(sizeof(*icu_irqd), GFP_KERNEL); 207 icu_irqd = kmalloc(sizeof(*icu_irqd), GFP_KERNEL);
149 if (!icu_irqd) 208 if (!icu_irqd)
@@ -156,7 +215,10 @@ mvebu_icu_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
156 goto free_irqd; 215 goto free_irqd;
157 } 216 }
158 217
159 icu_irqd->icu_group = fwspec->param[0]; 218 if (static_branch_unlikely(&legacy_bindings))
219 icu_irqd->icu_group = fwspec->param[0];
220 else
221 icu_irqd->icu_group = msi_data->subset_data->icu_group;
160 icu_irqd->icu = icu; 222 icu_irqd->icu = icu;
161 223
162 err = platform_msi_domain_alloc(domain, virq, nr_irqs); 224 err = platform_msi_domain_alloc(domain, virq, nr_irqs);
@@ -170,8 +232,11 @@ mvebu_icu_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
170 if (err) 232 if (err)
171 goto free_msi; 233 goto free_msi;
172 234
235 if (icu_irqd->icu_group == ICU_GRP_SEI)
236 chip = &mvebu_icu_sei_chip;
237
173 err = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, 238 err = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
174 &icu->irq_chip, icu_irqd); 239 chip, icu_irqd);
175 if (err) { 240 if (err) {
176 dev_err(icu->dev, "failed to set the data to IRQ domain\n"); 241 dev_err(icu->dev, "failed to set the data to IRQ domain\n");
177 goto free_msi; 242 goto free_msi;
@@ -204,11 +269,84 @@ static const struct irq_domain_ops mvebu_icu_domain_ops = {
204 .free = mvebu_icu_irq_domain_free, 269 .free = mvebu_icu_irq_domain_free,
205}; 270};
206 271
272static const struct mvebu_icu_subset_data mvebu_icu_nsr_subset_data = {
273 .icu_group = ICU_GRP_NSR,
274 .offset_set_ah = ICU_SETSPI_NSR_AH,
275 .offset_set_al = ICU_SETSPI_NSR_AL,
276 .offset_clr_ah = ICU_CLRSPI_NSR_AH,
277 .offset_clr_al = ICU_CLRSPI_NSR_AL,
278};
279
280static const struct mvebu_icu_subset_data mvebu_icu_sei_subset_data = {
281 .icu_group = ICU_GRP_SEI,
282 .offset_set_ah = ICU_SET_SEI_AH,
283 .offset_set_al = ICU_SET_SEI_AL,
284};
285
286static const struct of_device_id mvebu_icu_subset_of_match[] = {
287 {
288 .compatible = "marvell,cp110-icu-nsr",
289 .data = &mvebu_icu_nsr_subset_data,
290 },
291 {
292 .compatible = "marvell,cp110-icu-sei",
293 .data = &mvebu_icu_sei_subset_data,
294 },
295 {},
296};
297
298static int mvebu_icu_subset_probe(struct platform_device *pdev)
299{
300 struct mvebu_icu_msi_data *msi_data;
301 struct device_node *msi_parent_dn;
302 struct device *dev = &pdev->dev;
303 struct irq_domain *irq_domain;
304
305 msi_data = devm_kzalloc(dev, sizeof(*msi_data), GFP_KERNEL);
306 if (!msi_data)
307 return -ENOMEM;
308
309 if (static_branch_unlikely(&legacy_bindings)) {
310 msi_data->icu = dev_get_drvdata(dev);
311 msi_data->subset_data = &mvebu_icu_nsr_subset_data;
312 } else {
313 msi_data->icu = dev_get_drvdata(dev->parent);
314 msi_data->subset_data = of_device_get_match_data(dev);
315 }
316
317 dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
318 DOMAIN_BUS_PLATFORM_MSI);
319 if (!dev->msi_domain)
320 return -EPROBE_DEFER;
321
322 msi_parent_dn = irq_domain_get_of_node(dev->msi_domain);
323 if (!msi_parent_dn)
324 return -ENODEV;
325
326 irq_domain = platform_msi_create_device_tree_domain(dev, ICU_MAX_IRQS,
327 mvebu_icu_write_msg,
328 &mvebu_icu_domain_ops,
329 msi_data);
330 if (!irq_domain) {
331 dev_err(dev, "Failed to create ICU MSI domain\n");
332 return -ENOMEM;
333 }
334
335 return 0;
336}
337
338static struct platform_driver mvebu_icu_subset_driver = {
339 .probe = mvebu_icu_subset_probe,
340 .driver = {
341 .name = "mvebu-icu-subset",
342 .of_match_table = mvebu_icu_subset_of_match,
343 },
344};
345builtin_platform_driver(mvebu_icu_subset_driver);
346
207static int mvebu_icu_probe(struct platform_device *pdev) 347static int mvebu_icu_probe(struct platform_device *pdev)
208{ 348{
209 struct mvebu_icu *icu; 349 struct mvebu_icu *icu;
210 struct device_node *node = pdev->dev.of_node;
211 struct device_node *gicp_dn;
212 struct resource *res; 350 struct resource *res;
213 int i; 351 int i;
214 352
@@ -226,53 +364,38 @@ static int mvebu_icu_probe(struct platform_device *pdev)
226 return PTR_ERR(icu->base); 364 return PTR_ERR(icu->base);
227 } 365 }
228 366
229 icu->irq_chip.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
230 "ICU.%x",
231 (unsigned int)res->start);
232 if (!icu->irq_chip.name)
233 return -ENOMEM;
234
235 icu->irq_chip.irq_mask = irq_chip_mask_parent;
236 icu->irq_chip.irq_unmask = irq_chip_unmask_parent;
237 icu->irq_chip.irq_eoi = irq_chip_eoi_parent;
238 icu->irq_chip.irq_set_type = irq_chip_set_type_parent;
239#ifdef CONFIG_SMP
240 icu->irq_chip.irq_set_affinity = irq_chip_set_affinity_parent;
241#endif
242
243 /* 367 /*
244 * We're probed after MSI domains have been resolved, so force 368 * Legacy bindings: ICU is one node with one MSI parent: force manually
245 * resolution here. 369 * the probe of the NSR interrupts side.
370 * New bindings: ICU node has children, one per interrupt controller
371 * having its own MSI parent: call platform_populate().
372 * All ICU instances should use the same bindings.
246 */ 373 */
247 pdev->dev.msi_domain = of_msi_get_domain(&pdev->dev, node, 374 if (!of_get_child_count(pdev->dev.of_node))
248 DOMAIN_BUS_PLATFORM_MSI); 375 static_branch_enable(&legacy_bindings);
249 if (!pdev->dev.msi_domain)
250 return -EPROBE_DEFER;
251
252 gicp_dn = irq_domain_get_of_node(pdev->dev.msi_domain);
253 if (!gicp_dn)
254 return -ENODEV;
255 376
256 /* 377 /*
257 * Clean all ICU interrupts with type SPI_NSR, required to 378 * Clean all ICU interrupts of type NSR and SEI, required to
258 * avoid unpredictable SPI assignments done by firmware. 379 * avoid unpredictable SPI assignments done by firmware.
259 */ 380 */
260 for (i = 0 ; i < ICU_MAX_IRQS ; i++) { 381 for (i = 0 ; i < ICU_MAX_IRQS ; i++) {
261 u32 icu_int = readl_relaxed(icu->base + ICU_INT_CFG(i)); 382 u32 icu_int, icu_grp;
262 if ((icu_int >> ICU_GROUP_SHIFT) == ICU_GRP_NSR) 383
384 icu_int = readl_relaxed(icu->base + ICU_INT_CFG(i));
385 icu_grp = icu_int >> ICU_GROUP_SHIFT;
386
387 if (icu_grp == ICU_GRP_NSR ||
388 (icu_grp == ICU_GRP_SEI &&
389 !static_branch_unlikely(&legacy_bindings)))
263 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i)); 390 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i));
264 } 391 }
265 392
266 icu->domain = 393 platform_set_drvdata(pdev, icu);
267 platform_msi_create_device_domain(&pdev->dev, ICU_MAX_IRQS,
268 mvebu_icu_write_msg,
269 &mvebu_icu_domain_ops, icu);
270 if (!icu->domain) {
271 dev_err(&pdev->dev, "Failed to create ICU domain\n");
272 return -ENOMEM;
273 }
274 394
275 return 0; 395 if (static_branch_unlikely(&legacy_bindings))
396 return mvebu_icu_subset_probe(pdev);
397 else
398 return devm_of_platform_populate(&pdev->dev);
276} 399}
277 400
278static const struct of_device_id mvebu_icu_of_match[] = { 401static const struct of_device_id mvebu_icu_of_match[] = {
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
new file mode 100644
index 000000000000..566d69a2edbc
--- /dev/null
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -0,0 +1,507 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#define pr_fmt(fmt) "mvebu-sei: " fmt
4
5#include <linux/interrupt.h>
6#include <linux/irq.h>
7#include <linux/irqchip.h>
8#include <linux/irqchip/chained_irq.h>
9#include <linux/irqdomain.h>
10#include <linux/kernel.h>
11#include <linux/msi.h>
12#include <linux/platform_device.h>
13#include <linux/of_address.h>
14#include <linux/of_irq.h>
15#include <linux/of_platform.h>
16
17/* Cause register */
18#define GICP_SECR(idx) (0x0 + ((idx) * 0x4))
19/* Mask register */
20#define GICP_SEMR(idx) (0x20 + ((idx) * 0x4))
21#define GICP_SET_SEI_OFFSET 0x30
22
23#define SEI_IRQ_COUNT_PER_REG 32
24#define SEI_IRQ_REG_COUNT 2
25#define SEI_IRQ_COUNT (SEI_IRQ_COUNT_PER_REG * SEI_IRQ_REG_COUNT)
26#define SEI_IRQ_REG_IDX(irq_id) ((irq_id) / SEI_IRQ_COUNT_PER_REG)
27#define SEI_IRQ_REG_BIT(irq_id) ((irq_id) % SEI_IRQ_COUNT_PER_REG)
28
29struct mvebu_sei_interrupt_range {
30 u32 first;
31 u32 size;
32};
33
34struct mvebu_sei_caps {
35 struct mvebu_sei_interrupt_range ap_range;
36 struct mvebu_sei_interrupt_range cp_range;
37};
38
39struct mvebu_sei {
40 struct device *dev;
41 void __iomem *base;
42 struct resource *res;
43 struct irq_domain *sei_domain;
44 struct irq_domain *ap_domain;
45 struct irq_domain *cp_domain;
46 const struct mvebu_sei_caps *caps;
47
48 /* Lock on MSI allocations/releases */
49 struct mutex cp_msi_lock;
50 DECLARE_BITMAP(cp_msi_bitmap, SEI_IRQ_COUNT);
51
52 /* Lock on IRQ masking register */
53 raw_spinlock_t mask_lock;
54};
55
56static void mvebu_sei_ack_irq(struct irq_data *d)
57{
58 struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
59 u32 reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
60
61 writel_relaxed(BIT(SEI_IRQ_REG_BIT(d->hwirq)),
62 sei->base + GICP_SECR(reg_idx));
63}
64
65static void mvebu_sei_mask_irq(struct irq_data *d)
66{
67 struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
68 u32 reg, reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
69 unsigned long flags;
70
71 /* 1 disables the interrupt */
72 raw_spin_lock_irqsave(&sei->mask_lock, flags);
73 reg = readl_relaxed(sei->base + GICP_SEMR(reg_idx));
74 reg |= BIT(SEI_IRQ_REG_BIT(d->hwirq));
75 writel_relaxed(reg, sei->base + GICP_SEMR(reg_idx));
76 raw_spin_unlock_irqrestore(&sei->mask_lock, flags);
77}
78
79static void mvebu_sei_unmask_irq(struct irq_data *d)
80{
81 struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
82 u32 reg, reg_idx = SEI_IRQ_REG_IDX(d->hwirq);
83 unsigned long flags;
84
85 /* 0 enables the interrupt */
86 raw_spin_lock_irqsave(&sei->mask_lock, flags);
87 reg = readl_relaxed(sei->base + GICP_SEMR(reg_idx));
88 reg &= ~BIT(SEI_IRQ_REG_BIT(d->hwirq));
89 writel_relaxed(reg, sei->base + GICP_SEMR(reg_idx));
90 raw_spin_unlock_irqrestore(&sei->mask_lock, flags);
91}
92
93static int mvebu_sei_set_affinity(struct irq_data *d,
94 const struct cpumask *mask_val,
95 bool force)
96{
97 return -EINVAL;
98}
99
100static int mvebu_sei_set_irqchip_state(struct irq_data *d,
101 enum irqchip_irq_state which,
102 bool state)
103{
104 /* We can only clear the pending state by acking the interrupt */
105 if (which != IRQCHIP_STATE_PENDING || state)
106 return -EINVAL;
107
108 mvebu_sei_ack_irq(d);
109 return 0;
110}
111
112static struct irq_chip mvebu_sei_irq_chip = {
113 .name = "SEI",
114 .irq_ack = mvebu_sei_ack_irq,
115 .irq_mask = mvebu_sei_mask_irq,
116 .irq_unmask = mvebu_sei_unmask_irq,
117 .irq_set_affinity = mvebu_sei_set_affinity,
118 .irq_set_irqchip_state = mvebu_sei_set_irqchip_state,
119};
120
121static int mvebu_sei_ap_set_type(struct irq_data *data, unsigned int type)
122{
123 if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH)
124 return -EINVAL;
125
126 return 0;
127}
128
129static struct irq_chip mvebu_sei_ap_irq_chip = {
130 .name = "AP SEI",
131 .irq_ack = irq_chip_ack_parent,
132 .irq_mask = irq_chip_mask_parent,
133 .irq_unmask = irq_chip_unmask_parent,
134 .irq_set_affinity = irq_chip_set_affinity_parent,
135 .irq_set_type = mvebu_sei_ap_set_type,
136};
137
138static void mvebu_sei_cp_compose_msi_msg(struct irq_data *data,
139 struct msi_msg *msg)
140{
141 struct mvebu_sei *sei = data->chip_data;
142 phys_addr_t set = sei->res->start + GICP_SET_SEI_OFFSET;
143
144 msg->data = data->hwirq + sei->caps->cp_range.first;
145 msg->address_lo = lower_32_bits(set);
146 msg->address_hi = upper_32_bits(set);
147}
148
149static int mvebu_sei_cp_set_type(struct irq_data *data, unsigned int type)
150{
151 if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_EDGE_RISING)
152 return -EINVAL;
153
154 return 0;
155}
156
157static struct irq_chip mvebu_sei_cp_irq_chip = {
158 .name = "CP SEI",
159 .irq_ack = irq_chip_ack_parent,
160 .irq_mask = irq_chip_mask_parent,
161 .irq_unmask = irq_chip_unmask_parent,
162 .irq_set_affinity = irq_chip_set_affinity_parent,
163 .irq_set_type = mvebu_sei_cp_set_type,
164 .irq_compose_msi_msg = mvebu_sei_cp_compose_msi_msg,
165};
166
167static int mvebu_sei_domain_alloc(struct irq_domain *domain, unsigned int virq,
168 unsigned int nr_irqs, void *arg)
169{
170 struct mvebu_sei *sei = domain->host_data;
171 struct irq_fwspec *fwspec = arg;
172
173 /* Not much to do, just setup the irqdata */
174 irq_domain_set_hwirq_and_chip(domain, virq, fwspec->param[0],
175 &mvebu_sei_irq_chip, sei);
176
177 return 0;
178}
179
180static void mvebu_sei_domain_free(struct irq_domain *domain, unsigned int virq,
181 unsigned int nr_irqs)
182{
183 int i;
184
185 for (i = 0; i < nr_irqs; i++) {
186 struct irq_data *d = irq_domain_get_irq_data(domain, virq + i);
187 irq_set_handler(virq + i, NULL);
188 irq_domain_reset_irq_data(d);
189 }
190}
191
192static const struct irq_domain_ops mvebu_sei_domain_ops = {
193 .alloc = mvebu_sei_domain_alloc,
194 .free = mvebu_sei_domain_free,
195};
196
197static int mvebu_sei_ap_translate(struct irq_domain *domain,
198 struct irq_fwspec *fwspec,
199 unsigned long *hwirq,
200 unsigned int *type)
201{
202 *hwirq = fwspec->param[0];
203 *type = IRQ_TYPE_LEVEL_HIGH;
204
205 return 0;
206}
207
208static int mvebu_sei_ap_alloc(struct irq_domain *domain, unsigned int virq,
209 unsigned int nr_irqs, void *arg)
210{
211 struct mvebu_sei *sei = domain->host_data;
212 struct irq_fwspec fwspec;
213 unsigned long hwirq;
214 unsigned int type;
215 int err;
216
217 mvebu_sei_ap_translate(domain, arg, &hwirq, &type);
218
219 fwspec.fwnode = domain->parent->fwnode;
220 fwspec.param_count = 1;
221 fwspec.param[0] = hwirq + sei->caps->ap_range.first;
222
223 err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
224 if (err)
225 return err;
226
227 irq_domain_set_info(domain, virq, hwirq,
228 &mvebu_sei_ap_irq_chip, sei,
229 handle_level_irq, NULL, NULL);
230 irq_set_probe(virq);
231
232 return 0;
233}
234
235static const struct irq_domain_ops mvebu_sei_ap_domain_ops = {
236 .translate = mvebu_sei_ap_translate,
237 .alloc = mvebu_sei_ap_alloc,
238 .free = irq_domain_free_irqs_parent,
239};
240
241static void mvebu_sei_cp_release_irq(struct mvebu_sei *sei, unsigned long hwirq)
242{
243 mutex_lock(&sei->cp_msi_lock);
244 clear_bit(hwirq, sei->cp_msi_bitmap);
245 mutex_unlock(&sei->cp_msi_lock);
246}
247
248static int mvebu_sei_cp_domain_alloc(struct irq_domain *domain,
249 unsigned int virq, unsigned int nr_irqs,
250 void *args)
251{
252 struct mvebu_sei *sei = domain->host_data;
253 struct irq_fwspec fwspec;
254 unsigned long hwirq;
255 int ret;
256
257 /* The software only supports single allocations for now */
258 if (nr_irqs != 1)
259 return -ENOTSUPP;
260
261 mutex_lock(&sei->cp_msi_lock);
262 hwirq = find_first_zero_bit(sei->cp_msi_bitmap,
263 sei->caps->cp_range.size);
264 if (hwirq < sei->caps->cp_range.size)
265 set_bit(hwirq, sei->cp_msi_bitmap);
266 mutex_unlock(&sei->cp_msi_lock);
267
268 if (hwirq == sei->caps->cp_range.size)
269 return -ENOSPC;
270
271 fwspec.fwnode = domain->parent->fwnode;
272 fwspec.param_count = 1;
273 fwspec.param[0] = hwirq + sei->caps->cp_range.first;
274
275 ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
276 if (ret)
277 goto free_irq;
278
279 irq_domain_set_info(domain, virq, hwirq,
280 &mvebu_sei_cp_irq_chip, sei,
281 handle_edge_irq, NULL, NULL);
282
283 return 0;
284
285free_irq:
286 mvebu_sei_cp_release_irq(sei, hwirq);
287 return ret;
288}
289
290static void mvebu_sei_cp_domain_free(struct irq_domain *domain,
291 unsigned int virq, unsigned int nr_irqs)
292{
293 struct mvebu_sei *sei = domain->host_data;
294 struct irq_data *d = irq_domain_get_irq_data(domain, virq);
295
296 if (nr_irqs != 1 || d->hwirq >= sei->caps->cp_range.size) {
297 dev_err(sei->dev, "Invalid hwirq %lu\n", d->hwirq);
298 return;
299 }
300
301 mvebu_sei_cp_release_irq(sei, d->hwirq);
302 irq_domain_free_irqs_parent(domain, virq, 1);
303}
304
305static const struct irq_domain_ops mvebu_sei_cp_domain_ops = {
306 .alloc = mvebu_sei_cp_domain_alloc,
307 .free = mvebu_sei_cp_domain_free,
308};
309
310static struct irq_chip mvebu_sei_msi_irq_chip = {
311 .name = "SEI pMSI",
312 .irq_ack = irq_chip_ack_parent,
313 .irq_set_type = irq_chip_set_type_parent,
314};
315
316static struct msi_domain_ops mvebu_sei_msi_ops = {
317};
318
319static struct msi_domain_info mvebu_sei_msi_domain_info = {
320 .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS,
321 .ops = &mvebu_sei_msi_ops,
322 .chip = &mvebu_sei_msi_irq_chip,
323};
324
325static void mvebu_sei_handle_cascade_irq(struct irq_desc *desc)
326{
327 struct mvebu_sei *sei = irq_desc_get_handler_data(desc);
328 struct irq_chip *chip = irq_desc_get_chip(desc);
329 u32 idx;
330
331 chained_irq_enter(chip, desc);
332
333 for (idx = 0; idx < SEI_IRQ_REG_COUNT; idx++) {
334 unsigned long irqmap;
335 int bit;
336
337 irqmap = readl_relaxed(sei->base + GICP_SECR(idx));
338 for_each_set_bit(bit, &irqmap, SEI_IRQ_COUNT_PER_REG) {
339 unsigned long hwirq;
340 unsigned int virq;
341
342 hwirq = idx * SEI_IRQ_COUNT_PER_REG + bit;
343 virq = irq_find_mapping(sei->sei_domain, hwirq);
344 if (likely(virq)) {
345 generic_handle_irq(virq);
346 continue;
347 }
348
349 dev_warn(sei->dev,
350 "Spurious IRQ detected (hwirq %lu)\n", hwirq);
351 }
352 }
353
354 chained_irq_exit(chip, desc);
355}
356
357static void mvebu_sei_reset(struct mvebu_sei *sei)
358{
359 u32 reg_idx;
360
361 /* Clear IRQ cause registers, mask all interrupts */
362 for (reg_idx = 0; reg_idx < SEI_IRQ_REG_COUNT; reg_idx++) {
363 writel_relaxed(0xFFFFFFFF, sei->base + GICP_SECR(reg_idx));
364 writel_relaxed(0xFFFFFFFF, sei->base + GICP_SEMR(reg_idx));
365 }
366}
367
368static int mvebu_sei_probe(struct platform_device *pdev)
369{
370 struct device_node *node = pdev->dev.of_node;
371 struct irq_domain *plat_domain;
372 struct mvebu_sei *sei;
373 u32 parent_irq;
374 int ret;
375
376 sei = devm_kzalloc(&pdev->dev, sizeof(*sei), GFP_KERNEL);
377 if (!sei)
378 return -ENOMEM;
379
380 sei->dev = &pdev->dev;
381
382 mutex_init(&sei->cp_msi_lock);
383 raw_spin_lock_init(&sei->mask_lock);
384
385 sei->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
386 sei->base = devm_ioremap_resource(sei->dev, sei->res);
387 if (!sei->base) {
388 dev_err(sei->dev, "Failed to remap SEI resource\n");
389 return -ENODEV;
390 }
391
392 /* Retrieve the SEI capabilities with the interrupt ranges */
393 sei->caps = of_device_get_match_data(&pdev->dev);
394 if (!sei->caps) {
395 dev_err(sei->dev,
396 "Could not retrieve controller capabilities\n");
397 return -EINVAL;
398 }
399
400 /*
401 * Reserve the single (top-level) parent SPI IRQ from which all the
402 * interrupts handled by this driver will be signaled.
403 */
404 parent_irq = irq_of_parse_and_map(node, 0);
405 if (parent_irq <= 0) {
406 dev_err(sei->dev, "Failed to retrieve top-level SPI IRQ\n");
407 return -ENODEV;
408 }
409
410 /* Create the root SEI domain */
411 sei->sei_domain = irq_domain_create_linear(of_node_to_fwnode(node),
412 (sei->caps->ap_range.size +
413 sei->caps->cp_range.size),
414 &mvebu_sei_domain_ops,
415 sei);
416 if (!sei->sei_domain) {
417 dev_err(sei->dev, "Failed to create SEI IRQ domain\n");
418 ret = -ENOMEM;
419 goto dispose_irq;
420 }
421
422 irq_domain_update_bus_token(sei->sei_domain, DOMAIN_BUS_NEXUS);
423
424 /* Create the 'wired' domain */
425 sei->ap_domain = irq_domain_create_hierarchy(sei->sei_domain, 0,
426 sei->caps->ap_range.size,
427 of_node_to_fwnode(node),
428 &mvebu_sei_ap_domain_ops,
429 sei);
430 if (!sei->ap_domain) {
431 dev_err(sei->dev, "Failed to create AP IRQ domain\n");
432 ret = -ENOMEM;
433 goto remove_sei_domain;
434 }
435
436 irq_domain_update_bus_token(sei->ap_domain, DOMAIN_BUS_WIRED);
437
438 /* Create the 'MSI' domain */
439 sei->cp_domain = irq_domain_create_hierarchy(sei->sei_domain, 0,
440 sei->caps->cp_range.size,
441 of_node_to_fwnode(node),
442 &mvebu_sei_cp_domain_ops,
443 sei);
444 if (!sei->cp_domain) {
445 pr_err("Failed to create CPs IRQ domain\n");
446 ret = -ENOMEM;
447 goto remove_ap_domain;
448 }
449
450 irq_domain_update_bus_token(sei->cp_domain, DOMAIN_BUS_GENERIC_MSI);
451
452 plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
453 &mvebu_sei_msi_domain_info,
454 sei->cp_domain);
455 if (!plat_domain) {
456 pr_err("Failed to create CPs MSI domain\n");
457 ret = -ENOMEM;
458 goto remove_cp_domain;
459 }
460
461 mvebu_sei_reset(sei);
462
463 irq_set_chained_handler_and_data(parent_irq,
464 mvebu_sei_handle_cascade_irq,
465 sei);
466
467 return 0;
468
469remove_cp_domain:
470 irq_domain_remove(sei->cp_domain);
471remove_ap_domain:
472 irq_domain_remove(sei->ap_domain);
473remove_sei_domain:
474 irq_domain_remove(sei->sei_domain);
475dispose_irq:
476 irq_dispose_mapping(parent_irq);
477
478 return ret;
479}
480
481struct mvebu_sei_caps mvebu_sei_ap806_caps = {
482 .ap_range = {
483 .first = 0,
484 .size = 21,
485 },
486 .cp_range = {
487 .first = 21,
488 .size = 43,
489 },
490};
491
492static const struct of_device_id mvebu_sei_of_match[] = {
493 {
494 .compatible = "marvell,ap806-sei",
495 .data = &mvebu_sei_ap806_caps,
496 },
497 {},
498};
499
500static struct platform_driver mvebu_sei_driver = {
501 .probe = mvebu_sei_probe,
502 .driver = {
503 .name = "mvebu-sei",
504 .of_match_table = mvebu_sei_of_match,
505 },
506};
507builtin_platform_driver(mvebu_sei_driver);
diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
index b1b47a40a278..faa7d61b9d6c 100644
--- a/drivers/irqchip/qcom-pdc.c
+++ b/drivers/irqchip/qcom-pdc.c
@@ -124,6 +124,7 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
124 break; 124 break;
125 case IRQ_TYPE_EDGE_BOTH: 125 case IRQ_TYPE_EDGE_BOTH:
126 pdc_type = PDC_EDGE_DUAL; 126 pdc_type = PDC_EDGE_DUAL;
127 type = IRQ_TYPE_EDGE_RISING;
127 break; 128 break;
128 case IRQ_TYPE_LEVEL_HIGH: 129 case IRQ_TYPE_LEVEL_HIGH:
129 pdc_type = PDC_LEVEL_HIGH; 130 pdc_type = PDC_LEVEL_HIGH;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 401e4b254e30..22e4de9d3700 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -672,6 +672,7 @@ void efi_native_runtime_setup(void);
672#define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) 672#define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
673#define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) 673#define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
674#define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) 674#define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa)
675#define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
675 676
676typedef struct { 677typedef struct {
677 efi_guid_t guid; 678 efi_guid_t guid;
@@ -957,6 +958,7 @@ extern struct efi {
957 unsigned long mem_attr_table; /* memory attributes table */ 958 unsigned long mem_attr_table; /* memory attributes table */
958 unsigned long rng_seed; /* UEFI firmware random seed */ 959 unsigned long rng_seed; /* UEFI firmware random seed */
959 unsigned long tpm_log; /* TPM2 Event Log table */ 960 unsigned long tpm_log; /* TPM2 Event Log table */
961 unsigned long mem_reserve; /* Linux EFI memreserve table */
960 efi_get_time_t *get_time; 962 efi_get_time_t *get_time;
961 efi_set_time_t *set_time; 963 efi_set_time_t *set_time;
962 efi_get_wakeup_time_t *get_wakeup_time; 964 efi_get_wakeup_time_t *get_wakeup_time;
@@ -1041,6 +1043,7 @@ extern int __init efi_uart_console_only (void);
1041extern u64 efi_mem_desc_end(efi_memory_desc_t *md); 1043extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
1042extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md); 1044extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
1043extern void efi_mem_reserve(phys_addr_t addr, u64 size); 1045extern void efi_mem_reserve(phys_addr_t addr, u64 size);
1046extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
1044extern void efi_initialize_iomem_resources(struct resource *code_resource, 1047extern void efi_initialize_iomem_resources(struct resource *code_resource,
1045 struct resource *data_resource, struct resource *bss_resource); 1048 struct resource *data_resource, struct resource *bss_resource);
1046extern void efi_reserve_boot_services(void); 1049extern void efi_reserve_boot_services(void);
@@ -1662,4 +1665,10 @@ extern int efi_tpm_eventlog_init(void);
1662/* Workqueue to queue EFI Runtime Services */ 1665/* Workqueue to queue EFI Runtime Services */
1663extern struct workqueue_struct *efi_rts_wq; 1666extern struct workqueue_struct *efi_rts_wq;
1664 1667
1668struct linux_efi_memreserve {
1669 phys_addr_t next;
1670 phys_addr_t base;
1671 phys_addr_t size;
1672};
1673
1665#endif /* _LINUX_EFI_H */ 1674#endif /* _LINUX_EFI_H */
diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h
index 0a83b4379f34..9a1a479a2bf4 100644
--- a/include/linux/irqchip/arm-gic-common.h
+++ b/include/linux/irqchip/arm-gic-common.h
@@ -13,6 +13,12 @@
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/ioport.h> 14#include <linux/ioport.h>
15 15
16#define GICD_INT_DEF_PRI 0xa0
17#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
18 (GICD_INT_DEF_PRI << 16) |\
19 (GICD_INT_DEF_PRI << 8) |\
20 GICD_INT_DEF_PRI)
21
16enum gic_type { 22enum gic_type {
17 GIC_V2, 23 GIC_V2,
18 GIC_V3, 24 GIC_V3,
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 8bdbb5f29494..c2a7b863fc2e 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -585,8 +585,10 @@ struct rdists {
585 void __iomem *rd_base; 585 void __iomem *rd_base;
586 struct page *pend_page; 586 struct page *pend_page;
587 phys_addr_t phys_base; 587 phys_addr_t phys_base;
588 bool lpi_enabled;
588 } __percpu *rdist; 589 } __percpu *rdist;
589 struct page *prop_page; 590 phys_addr_t prop_table_pa;
591 void *prop_table_va;
590 u64 flags; 592 u64 flags;
591 u32 gicd_typer; 593 u32 gicd_typer;
592 bool has_vlpis; 594 bool has_vlpis;
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 6c4aaf04046c..626179077bb0 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -65,11 +65,6 @@
65#define GICD_INT_EN_CLR_X32 0xffffffff 65#define GICD_INT_EN_CLR_X32 0xffffffff
66#define GICD_INT_EN_SET_SGI 0x0000ffff 66#define GICD_INT_EN_SET_SGI 0x0000ffff
67#define GICD_INT_EN_CLR_PPI 0xffff0000 67#define GICD_INT_EN_CLR_PPI 0xffff0000
68#define GICD_INT_DEF_PRI 0xa0
69#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
70 (GICD_INT_DEF_PRI << 16) |\
71 (GICD_INT_DEF_PRI << 8) |\
72 GICD_INT_DEF_PRI)
73 68
74#define GICD_IIDR_IMPLEMENTER_SHIFT 0 69#define GICD_IIDR_IMPLEMENTER_SHIFT 0
75#define GICD_IIDR_IMPLEMENTER_MASK (0xfff << GICD_IIDR_IMPLEMENTER_SHIFT) 70#define GICD_IIDR_IMPLEMENTER_MASK (0xfff << GICD_IIDR_IMPLEMENTER_SHIFT)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index dccfa65aee96..068aa46f0d55 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -75,6 +75,7 @@ struct irq_fwspec {
75enum irq_domain_bus_token { 75enum irq_domain_bus_token {
76 DOMAIN_BUS_ANY = 0, 76 DOMAIN_BUS_ANY = 0,
77 DOMAIN_BUS_WIRED, 77 DOMAIN_BUS_WIRED,
78 DOMAIN_BUS_GENERIC_MSI,
78 DOMAIN_BUS_PCI_MSI, 79 DOMAIN_BUS_PCI_MSI,
79 DOMAIN_BUS_PLATFORM_MSI, 80 DOMAIN_BUS_PLATFORM_MSI,
80 DOMAIN_BUS_NEXUS, 81 DOMAIN_BUS_NEXUS,
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 5839d8062dfc..0e9c50052ff3 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -317,11 +317,18 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
317int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, 317int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
318 int virq, int nvec, msi_alloc_info_t *args); 318 int virq, int nvec, msi_alloc_info_t *args);
319struct irq_domain * 319struct irq_domain *
320platform_msi_create_device_domain(struct device *dev, 320__platform_msi_create_device_domain(struct device *dev,
321 unsigned int nvec, 321 unsigned int nvec,
322 irq_write_msi_msg_t write_msi_msg, 322 bool is_tree,
323 const struct irq_domain_ops *ops, 323 irq_write_msi_msg_t write_msi_msg,
324 void *host_data); 324 const struct irq_domain_ops *ops,
325 void *host_data);
326
327#define platform_msi_create_device_domain(dev, nvec, write, ops, data) \
328 __platform_msi_create_device_domain(dev, nvec, false, write, ops, data)
329#define platform_msi_create_device_tree_domain(dev, nvec, write, ops, data) \
330 __platform_msi_create_device_domain(dev, nvec, true, write, ops, data)
331
325int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, 332int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
326 unsigned int nr_irqs); 333 unsigned int nr_irqs);
327void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq, 334void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,