aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 21:28:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 21:28:06 -0500
commit3d116a66ed9df0271b8d267093b3bfde2be19b3a (patch)
tree8415b051c87b44ea9f7ecd50bf850155b028737e
parentb4cee21ee057ff3e5c9014fb6a175bd932c5ce62 (diff)
parentd3b421cd07e4c0d4d6c0bbd55ca169c054fc081d (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "The irq department provides: - Support for MSI to wire bridges and a first user of it - More ACPI support for ARM/GIC - A new TS-4800 interrupt controller driver - RCU based free of interrupt descriptors to support the upcoming Intel VMD technology without introducing a locking nightmare - The usual pile of fixes and updates to drivers and core code" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (41 commits) irqchip/omap-intc: Add support for spurious irq handling irqchip/zevio: Use irq_data_get_chip_type() helper irqchip/omap-intc: Remove duplicate setup for IRQ chip type handler irqchip/ts4800: Add TS-4800 interrupt controller irqchip/ts4800: Add documentation for TS-4800 interrupt controller irq/platform-MSI: Increase the maximum MSIs the MSI framework can support irqchip/gicv2m: Miscellaneous fixes for v2m resources and SPI ranges irqchip/bcm2836: Make code more readable irqchip/bcm2836: Tolerate IRQs while no flag is set in ISR irqchip/bcm2836: Add SMP support for the 2836 irqchip/bcm2836: Fix initialization of the LOCAL_IRQ_CNT timers irqchip/gic-v2m: acpi: Introducing GICv2m ACPI support irqchip/gic-v2m: Refactor to prepare for ACPI support irqdomain: Introduce is_fwnode_irqchip helper acpi: pci: Setup MSI domain for ACPI based pci devices genirq/msi: Export functions to allow MSI domains in modules irqchip/mbigen: Implement the mbigen irq chip operation functions irqchip/mbigen: Create irq domain for each mbigen device irqchip/mgigen: Add platform device driver for mbigen device dt-bindings: Documents the mbigen bindings ...
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt (renamed from Documentation/devicetree/bindings/interrupt-controller/allwinner,sun67i-sc-nmi.txt)2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt1
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt74
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/technologic,ts4800.txt16
-rw-r--r--drivers/base/platform-msi.c256
-rw-r--r--drivers/irqchip/Kconfig19
-rw-r--r--drivers/irqchip/Makefile3
-rw-r--r--drivers/irqchip/irq-bcm2836.c55
-rw-r--r--drivers/irqchip/irq-gic-realview.c43
-rw-r--r--drivers/irqchip/irq-gic-v2m.c165
-rw-r--r--drivers/irqchip/irq-gic.c64
-rw-r--r--drivers/irqchip/irq-mbigen.c297
-rw-r--r--drivers/irqchip/irq-omap-intc.c28
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c96
-rw-r--r--drivers/irqchip/irq-sunxi-nmi.c13
-rw-r--r--drivers/irqchip/irq-ts4800.c163
-rw-r--r--drivers/irqchip/irq-zevio.c3
-rw-r--r--drivers/pci/msi.c4
-rw-r--r--drivers/pci/pci-acpi.c42
-rw-r--r--drivers/pci/probe.c2
-rw-r--r--include/linux/interrupt.h1
-rw-r--r--include/linux/irqchip/arm-gic.h13
-rw-r--r--include/linux/irqdesc.h6
-rw-r--r--include/linux/irqdomain.h13
-rw-r--r--include/linux/msi.h18
-rw-r--r--include/linux/pci.h10
-rw-r--r--include/linux/platform_data/irq-renesas-intc-irqpin.h29
-rw-r--r--kernel/irq/chip.c9
-rw-r--r--kernel/irq/irqdesc.c19
-rw-r--r--kernel/irq/irqdomain.c12
-rw-r--r--kernel/irq/manage.c25
-rw-r--r--kernel/irq/msi.c58
32 files changed, 1350 insertions, 209 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun67i-sc-nmi.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
index d1c5cdabc3e0..81cd3692405e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun67i-sc-nmi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
@@ -4,7 +4,7 @@ Allwinner Sunxi NMI Controller
4Required properties: 4Required properties:
5 5
6- compatible : should be "allwinner,sun7i-a20-sc-nmi" or 6- compatible : should be "allwinner,sun7i-a20-sc-nmi" or
7 "allwinner,sun6i-a31-sc-nmi" 7 "allwinner,sun6i-a31-sc-nmi" or "allwinner,sun9i-a80-nmi"
8- reg : Specifies base physical address and size of the registers. 8- reg : Specifies base physical address and size of the registers.
9- interrupt-controller : Identifies the node as an interrupt controller 9- interrupt-controller : Identifies the node as an interrupt controller
10- #interrupt-cells : Specifies the number of cells needed to encode an 10- #interrupt-cells : Specifies the number of cells needed to encode an
diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
index cc56021eb60b..5a1cb4bc3dfe 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
@@ -18,6 +18,7 @@ Main node required properties:
18 "arm,cortex-a9-gic" 18 "arm,cortex-a9-gic"
19 "arm,gic-400" 19 "arm,gic-400"
20 "arm,pl390" 20 "arm,pl390"
21 "arm,tc11mp-gic"
21 "brcm,brahma-b15-gic" 22 "brcm,brahma-b15-gic"
22 "qcom,msm-8660-qgic" 23 "qcom,msm-8660-qgic"
23 "qcom,msm-qgic2" 24 "qcom,msm-qgic2"
diff --git a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt
new file mode 100644
index 000000000000..720f7c92e9a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt
@@ -0,0 +1,74 @@
1Hisilicon mbigen device tree bindings.
2=======================================
3
4Mbigen means: message based interrupt generator.
5
6MBI is kind of msi interrupt only used on Non-PCI devices.
7
8To reduce the wired interrupt number connected to GIC,
9Hisilicon designed mbigen to collect and generate interrupt.
10
11
12Non-pci devices can connect to mbigen and generate the
13interrupt by writing ITS register.
14
15The mbigen chip and devices connect to mbigen have the following properties:
16
17Mbigen main node required properties:
18-------------------------------------------
19- compatible: Should be "hisilicon,mbigen-v2"
20
21- reg: Specifies the base physical address and size of the Mbigen
22 registers.
23
24- interrupt controller: Identifies the node as an interrupt controller
25
26- msi-parent: Specifies the MSI controller this mbigen use.
27 For more detail information,please refer to the generic msi-parent binding in
28 Documentation/devicetree/bindings/interrupt-controller/msi.txt.
29
30- num-pins: the total number of pins implemented in this Mbigen
31 instance.
32
33- #interrupt-cells : Specifies the number of cells needed to encode an
34 interrupt source. The value must be 2.
35
36 The 1st cell is hardware pin number of the interrupt.This number is local to
37 each mbigen chip and in the range from 0 to the maximum interrupts number
38 of the mbigen.
39
40 The 2nd cell is the interrupt trigger type.
41 The value of this cell should be:
42 1: rising edge triggered
43 or
44 4: high level triggered
45
46Examples:
47
48 mbigen_device_gmac:intc {
49 compatible = "hisilicon,mbigen-v2";
50 reg = <0x0 0xc0080000 0x0 0x10000>;
51 interrupt-controller;
52 msi-parent = <&its_dsa 0x40b1c>;
53 num-pins = <9>;
54 #interrupt-cells = <2>;
55 };
56
57Devices connect to mbigen required properties:
58----------------------------------------------------
59-interrupt-parent: Specifies the mbigen device node which device connected.
60
61-interrupts:Specifies the interrupt source.
62 For the specific information of each cell in this property,please refer to
63 the "interrupt-cells" description mentioned above.
64
65Examples:
66 gmac0: ethernet@c2080000 {
67 #address-cells = <1>;
68 #size-cells = <0>;
69 reg = <0 0xc2080000 0 0x20000>,
70 <0 0xc0000000 0 0x1000>;
71 interrupt-parent = <&mbigen_device_gmac>;
72 interrupts = <656 1>,
73 <657 1>;
74 };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/technologic,ts4800.txt b/Documentation/devicetree/bindings/interrupt-controller/technologic,ts4800.txt
new file mode 100644
index 000000000000..7f15f1b0325b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/technologic,ts4800.txt
@@ -0,0 +1,16 @@
1TS-4800 FPGA interrupt controller
2
3TS-4800 FPGA has an internal interrupt controller. When one of the
4interrupts is triggered, the SoC is notified, usually using a GPIO as
5parent interrupt source.
6
7Required properties:
8- compatible: should be "technologic,ts4800-irqc"
9- interrupt-controller: identifies the node as an interrupt controller
10- reg: physical base address of the controller and length of memory mapped
11 region
12- #interrupt-cells: specifies the number of cells needed to encode an interrupt
13 source, should be 1.
14- interrupt-parent: phandle to the parent interrupt controller this one is
15 cascaded from
16- interrupts: specifies the interrupt line in the interrupt-parent controller
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 5df4575b5ba7..47c43386786b 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -24,13 +24,17 @@
24#include <linux/msi.h> 24#include <linux/msi.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26 26
27#define DEV_ID_SHIFT 24 27#define DEV_ID_SHIFT 21
28#define MAX_DEV_MSIS (1 << (32 - DEV_ID_SHIFT))
28 29
29/* 30/*
30 * Internal data structure containing a (made up, but unique) devid 31 * Internal data structure containing a (made up, but unique) devid
31 * and the callback to write the MSI message. 32 * and the callback to write the MSI message.
32 */ 33 */
33struct platform_msi_priv_data { 34struct platform_msi_priv_data {
35 struct device *dev;
36 void *host_data;
37 msi_alloc_info_t arg;
34 irq_write_msi_msg_t write_msg; 38 irq_write_msi_msg_t write_msg;
35 int devid; 39 int devid;
36}; 40};
@@ -110,39 +114,49 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info)
110 chip->irq_write_msi_msg = platform_msi_write_msg; 114 chip->irq_write_msi_msg = platform_msi_write_msg;
111} 115}
112 116
113static void platform_msi_free_descs(struct device *dev) 117static void platform_msi_free_descs(struct device *dev, int base, int nvec)
114{ 118{
115 struct msi_desc *desc, *tmp; 119 struct msi_desc *desc, *tmp;
116 120
117 list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { 121 list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
118 list_del(&desc->list); 122 if (desc->platform.msi_index >= base &&
119 free_msi_entry(desc); 123 desc->platform.msi_index < (base + nvec)) {
124 list_del(&desc->list);
125 free_msi_entry(desc);
126 }
120 } 127 }
121} 128}
122 129
123static int platform_msi_alloc_descs(struct device *dev, int nvec, 130static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
124 struct platform_msi_priv_data *data) 131 int nvec,
132 struct platform_msi_priv_data *data)
125 133
126{ 134{
127 int i; 135 struct msi_desc *desc;
136 int i, base = 0;
128 137
129 for (i = 0; i < nvec; i++) { 138 if (!list_empty(dev_to_msi_list(dev))) {
130 struct msi_desc *desc; 139 desc = list_last_entry(dev_to_msi_list(dev),
140 struct msi_desc, list);
141 base = desc->platform.msi_index + 1;
142 }
131 143
144 for (i = 0; i < nvec; i++) {
132 desc = alloc_msi_entry(dev); 145 desc = alloc_msi_entry(dev);
133 if (!desc) 146 if (!desc)
134 break; 147 break;
135 148
136 desc->platform.msi_priv_data = data; 149 desc->platform.msi_priv_data = data;
137 desc->platform.msi_index = i; 150 desc->platform.msi_index = base + i;
138 desc->nvec_used = 1; 151 desc->nvec_used = 1;
152 desc->irq = virq ? virq + i : 0;
139 153
140 list_add_tail(&desc->list, dev_to_msi_list(dev)); 154 list_add_tail(&desc->list, dev_to_msi_list(dev));
141 } 155 }
142 156
143 if (i != nvec) { 157 if (i != nvec) {
144 /* Clean up the mess */ 158 /* Clean up the mess */
145 platform_msi_free_descs(dev); 159 platform_msi_free_descs(dev, base, nvec);
146 160
147 return -ENOMEM; 161 return -ENOMEM;
148 } 162 }
@@ -150,6 +164,13 @@ static int platform_msi_alloc_descs(struct device *dev, int nvec,
150 return 0; 164 return 0;
151} 165}
152 166
167static int platform_msi_alloc_descs(struct device *dev, int nvec,
168 struct platform_msi_priv_data *data)
169
170{
171 return platform_msi_alloc_descs_with_irq(dev, 0, nvec, data);
172}
173
153/** 174/**
154 * platform_msi_create_irq_domain - Create a platform MSI interrupt domain 175 * platform_msi_create_irq_domain - Create a platform MSI interrupt domain
155 * @fwnode: Optional fwnode of the interrupt controller 176 * @fwnode: Optional fwnode of the interrupt controller
@@ -180,56 +201,75 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
180 return domain; 201 return domain;
181} 202}
182 203
183/** 204static struct platform_msi_priv_data *
184 * platform_msi_domain_alloc_irqs - Allocate MSI interrupts for @dev 205platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
185 * @dev: The device for which to allocate interrupts 206 irq_write_msi_msg_t write_msi_msg)
186 * @nvec: The number of interrupts to allocate
187 * @write_msi_msg: Callback to write an interrupt message for @dev
188 *
189 * Returns:
190 * Zero for success, or an error code in case of failure
191 */
192int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
193 irq_write_msi_msg_t write_msi_msg)
194{ 207{
195 struct platform_msi_priv_data *priv_data; 208 struct platform_msi_priv_data *datap;
196 int err;
197
198 /* 209 /*
199 * Limit the number of interrupts to 256 per device. Should we 210 * Limit the number of interrupts to 256 per device. Should we
200 * need to bump this up, DEV_ID_SHIFT should be adjusted 211 * need to bump this up, DEV_ID_SHIFT should be adjusted
201 * accordingly (which would impact the max number of MSI 212 * accordingly (which would impact the max number of MSI
202 * capable devices). 213 * capable devices).
203 */ 214 */
204 if (!dev->msi_domain || !write_msi_msg || !nvec || 215 if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
205 nvec > (1 << (32 - DEV_ID_SHIFT))) 216 return ERR_PTR(-EINVAL);
206 return -EINVAL;
207 217
208 if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { 218 if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
209 dev_err(dev, "Incompatible msi_domain, giving up\n"); 219 dev_err(dev, "Incompatible msi_domain, giving up\n");
210 return -EINVAL; 220 return ERR_PTR(-EINVAL);
211 } 221 }
212 222
213 /* Already had a helping of MSI? Greed... */ 223 /* Already had a helping of MSI? Greed... */
214 if (!list_empty(dev_to_msi_list(dev))) 224 if (!list_empty(dev_to_msi_list(dev)))
215 return -EBUSY; 225 return ERR_PTR(-EBUSY);
226
227 datap = kzalloc(sizeof(*datap), GFP_KERNEL);
228 if (!datap)
229 return ERR_PTR(-ENOMEM);
230
231 datap->devid = ida_simple_get(&platform_msi_devid_ida,
232 0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
233 if (datap->devid < 0) {
234 int err = datap->devid;
235 kfree(datap);
236 return ERR_PTR(err);
237 }
216 238
217 priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); 239 datap->write_msg = write_msi_msg;
218 if (!priv_data) 240 datap->dev = dev;
219 return -ENOMEM;
220 241
221 priv_data->devid = ida_simple_get(&platform_msi_devid_ida, 242 return datap;
222 0, 1 << DEV_ID_SHIFT, GFP_KERNEL); 243}
223 if (priv_data->devid < 0) { 244
224 err = priv_data->devid; 245static void platform_msi_free_priv_data(struct platform_msi_priv_data *data)
225 goto out_free_data; 246{
226 } 247 ida_simple_remove(&platform_msi_devid_ida, data->devid);
248 kfree(data);
249}
250
251/**
252 * platform_msi_domain_alloc_irqs - Allocate MSI interrupts for @dev
253 * @dev: The device for which to allocate interrupts
254 * @nvec: The number of interrupts to allocate
255 * @write_msi_msg: Callback to write an interrupt message for @dev
256 *
257 * Returns:
258 * Zero for success, or an error code in case of failure
259 */
260int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
261 irq_write_msi_msg_t write_msi_msg)
262{
263 struct platform_msi_priv_data *priv_data;
264 int err;
227 265
228 priv_data->write_msg = write_msi_msg; 266 priv_data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
267 if (IS_ERR(priv_data))
268 return PTR_ERR(priv_data);
229 269
230 err = platform_msi_alloc_descs(dev, nvec, priv_data); 270 err = platform_msi_alloc_descs(dev, nvec, priv_data);
231 if (err) 271 if (err)
232 goto out_free_id; 272 goto out_free_priv_data;
233 273
234 err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec); 274 err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec);
235 if (err) 275 if (err)
@@ -238,11 +278,9 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
238 return 0; 278 return 0;
239 279
240out_free_desc: 280out_free_desc:
241 platform_msi_free_descs(dev); 281 platform_msi_free_descs(dev, 0, nvec);
242out_free_id: 282out_free_priv_data:
243 ida_simple_remove(&platform_msi_devid_ida, priv_data->devid); 283 platform_msi_free_priv_data(priv_data);
244out_free_data:
245 kfree(priv_data);
246 284
247 return err; 285 return err;
248} 286}
@@ -253,18 +291,126 @@ out_free_data:
253 */ 291 */
254void platform_msi_domain_free_irqs(struct device *dev) 292void platform_msi_domain_free_irqs(struct device *dev)
255{ 293{
256 struct msi_desc *desc; 294 if (!list_empty(dev_to_msi_list(dev))) {
295 struct msi_desc *desc;
296
297 desc = first_msi_entry(dev);
298 platform_msi_free_priv_data(desc->platform.msi_priv_data);
299 }
300
301 msi_domain_free_irqs(dev->msi_domain, dev);
302 platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
303}
304
305/**
306 * platform_msi_get_host_data - Query the private data associated with
307 * a platform-msi domain
308 * @domain: The platform-msi domain
309 *
310 * Returns the private data provided when calling
311 * platform_msi_create_device_domain.
312 */
313void *platform_msi_get_host_data(struct irq_domain *domain)
314{
315 struct platform_msi_priv_data *data = domain->host_data;
316 return data->host_data;
317}
318
319/**
320 * platform_msi_create_device_domain - Create a platform-msi domain
321 *
322 * @dev: The device generating the MSIs
323 * @nvec: The number of MSIs that need to be allocated
324 * @write_msi_msg: Callback to write an interrupt message for @dev
325 * @ops: The hierarchy domain operations to use
326 * @host_data: Private data associated to this domain
327 *
328 * Returns an irqdomain for @nvec interrupts
329 */
330struct irq_domain *
331platform_msi_create_device_domain(struct device *dev,
332 unsigned int nvec,
333 irq_write_msi_msg_t write_msi_msg,
334 const struct irq_domain_ops *ops,
335 void *host_data)
336{
337 struct platform_msi_priv_data *data;
338 struct irq_domain *domain;
339 int err;
340
341 data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
342 if (IS_ERR(data))
343 return NULL;
344
345 data->host_data = host_data;
346 domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
347 of_node_to_fwnode(dev->of_node),
348 ops, data);
349 if (!domain)
350 goto free_priv;
257 351
258 desc = first_msi_entry(dev); 352 err = msi_domain_prepare_irqs(domain->parent, dev, nvec, &data->arg);
259 if (desc) { 353 if (err)
260 struct platform_msi_priv_data *data; 354 goto free_domain;
355
356 return domain;
261 357
262 data = desc->platform.msi_priv_data; 358free_domain:
359 irq_domain_remove(domain);
360free_priv:
361 platform_msi_free_priv_data(data);
362 return NULL;
363}
364
365/**
366 * platform_msi_domain_free - Free interrupts associated with a platform-msi
367 * domain
368 *
369 * @domain: The platform-msi domain
370 * @virq: The base irq from which to perform the free operation
371 * @nvec: How many interrupts to free from @virq
372 */
373void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
374 unsigned int nvec)
375{
376 struct platform_msi_priv_data *data = domain->host_data;
377 struct msi_desc *desc;
378 for_each_msi_entry(desc, data->dev) {
379 if (WARN_ON(!desc->irq || desc->nvec_used != 1))
380 return;
381 if (!(desc->irq >= virq && desc->irq < (virq + nvec)))
382 continue;
263 383
264 ida_simple_remove(&platform_msi_devid_ida, data->devid); 384 irq_domain_free_irqs_common(domain, desc->irq, 1);
265 kfree(data);
266 } 385 }
386}
267 387
268 msi_domain_free_irqs(dev->msi_domain, dev); 388/**
269 platform_msi_free_descs(dev); 389 * platform_msi_domain_alloc - Allocate interrupts associated with
390 * a platform-msi domain
391 *
392 * @domain: The platform-msi domain
393 * @virq: The base irq from which to perform the allocate operation
394 * @nvec: How many interrupts to free from @virq
395 *
396 * Return 0 on success, or an error code on failure. Must be called
397 * with irq_domain_mutex held (which can only be done as part of a
398 * top-level interrupt allocation).
399 */
400int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
401 unsigned int nr_irqs)
402{
403 struct platform_msi_priv_data *data = domain->host_data;
404 int err;
405
406 err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs, data);
407 if (err)
408 return err;
409
410 err = msi_domain_populate_irqs(domain->parent, data->dev,
411 virq, nr_irqs, &data->arg);
412 if (err)
413 platform_msi_domain_free(domain, virq, nr_irqs);
414
415 return err;
270} 416}
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 4d7294e5d982..11fc2a27fa2e 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -8,6 +8,11 @@ config ARM_GIC
8 select IRQ_DOMAIN_HIERARCHY 8 select IRQ_DOMAIN_HIERARCHY
9 select MULTI_IRQ_HANDLER 9 select MULTI_IRQ_HANDLER
10 10
11config ARM_GIC_MAX_NR
12 int
13 default 2 if ARCH_REALVIEW
14 default 1
15
11config ARM_GIC_V2M 16config ARM_GIC_V2M
12 bool 17 bool
13 depends on ARM_GIC 18 depends on ARM_GIC
@@ -27,6 +32,14 @@ config ARM_GIC_V3_ITS
27 bool 32 bool
28 select PCI_MSI_IRQ_DOMAIN 33 select PCI_MSI_IRQ_DOMAIN
29 34
35config HISILICON_IRQ_MBIGEN
36 bool "Support mbigen interrupt controller"
37 default n
38 depends on ARM_GIC_V3 && ARM_GIC_V3_ITS && GENERIC_MSI_IRQ_DOMAIN
39 help
40 Enable the mbigen interrupt controller used on
41 Hisilicon platform.
42
30config ARM_NVIC 43config ARM_NVIC
31 bool 44 bool
32 select IRQ_DOMAIN 45 select IRQ_DOMAIN
@@ -138,6 +151,12 @@ config TB10X_IRQC
138 select IRQ_DOMAIN 151 select IRQ_DOMAIN
139 select GENERIC_IRQ_CHIP 152 select GENERIC_IRQ_CHIP
140 153
154config TS4800_IRQ
155 tristate "TS-4800 IRQ controller"
156 select IRQ_DOMAIN
157 help
158 Support for the TS-4800 FPGA IRQ controller
159
141config VERSATILE_FPGA_IRQ 160config VERSATILE_FPGA_IRQ
142 bool 161 bool
143 select IRQ_DOMAIN 162 select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f6e6d6..d4c2e4ebc308 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -21,9 +21,11 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
21obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o 21obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
22obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o 22obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
23obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o 23obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o
24obj-$(CONFIG_REALVIEW_DT) += irq-gic-realview.o
24obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o 25obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o
25obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o 26obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
26obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o 27obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
28obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
27obj-$(CONFIG_ARM_NVIC) += irq-nvic.o 29obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
28obj-$(CONFIG_ARM_VIC) += irq-vic.o 30obj-$(CONFIG_ARM_VIC) += irq-vic.o
29obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o 31obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o
@@ -39,6 +41,7 @@ obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o
39obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o 41obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
40obj-$(CONFIG_ST_IRQCHIP) += irq-st.o 42obj-$(CONFIG_ST_IRQCHIP) += irq-st.o
41obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o 43obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
44obj-$(CONFIG_TS4800_IRQ) += irq-ts4800.o
42obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o 45obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
43obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o 46obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
44obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o 47obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index f68708281fcf..963065a0d774 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -21,6 +21,9 @@
21#include <linux/irqdomain.h> 21#include <linux/irqdomain.h>
22#include <asm/exception.h> 22#include <asm/exception.h>
23 23
24#define LOCAL_CONTROL 0x000
25#define LOCAL_PRESCALER 0x008
26
24/* 27/*
25 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the 28 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
26 * next 2 bits identify the CPU that the GPU FIQ goes to. 29 * next 2 bits identify the CPU that the GPU FIQ goes to.
@@ -50,14 +53,16 @@
50/* Same status bits as above, but for FIQ. */ 53/* Same status bits as above, but for FIQ. */
51#define LOCAL_FIQ_PENDING0 0x070 54#define LOCAL_FIQ_PENDING0 0x070
52/* 55/*
53 * Mailbox0 write-to-set bits. There are 16 mailboxes, 4 per CPU, and 56 * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
54 * these bits are organized by mailbox number and then CPU number. We 57 * these bits are organized by mailbox number and then CPU number. We
55 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while 58 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
56 * any bit is set. 59 * any bit is set.
57 */ 60 */
58#define LOCAL_MAILBOX0_SET0 0x080 61#define LOCAL_MAILBOX0_SET0 0x080
59/* Mailbox0 write-to-clear bits. */ 62#define LOCAL_MAILBOX3_SET0 0x08c
63/* Mailbox write-to-clear bits. */
60#define LOCAL_MAILBOX0_CLR0 0x0c0 64#define LOCAL_MAILBOX0_CLR0 0x0c0
65#define LOCAL_MAILBOX3_CLR0 0x0cc
61 66
62#define LOCAL_IRQ_CNTPSIRQ 0 67#define LOCAL_IRQ_CNTPSIRQ 0
63#define LOCAL_IRQ_CNTPNSIRQ 1 68#define LOCAL_IRQ_CNTPNSIRQ 1
@@ -162,7 +167,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
162 u32 stat; 167 u32 stat;
163 168
164 stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); 169 stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu);
165 if (stat & 0x10) { 170 if (stat & BIT(LOCAL_IRQ_MAILBOX0)) {
166#ifdef CONFIG_SMP 171#ifdef CONFIG_SMP
167 void __iomem *mailbox0 = (intc.base + 172 void __iomem *mailbox0 = (intc.base +
168 LOCAL_MAILBOX0_CLR0 + 16 * cpu); 173 LOCAL_MAILBOX0_CLR0 + 16 * cpu);
@@ -172,7 +177,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
172 writel(1 << ipi, mailbox0); 177 writel(1 << ipi, mailbox0);
173 handle_IPI(ipi, regs); 178 handle_IPI(ipi, regs);
174#endif 179#endif
175 } else { 180 } else if (stat) {
176 u32 hwirq = ffs(stat) - 1; 181 u32 hwirq = ffs(stat) - 1;
177 182
178 handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); 183 handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
@@ -217,6 +222,24 @@ static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = {
217 .notifier_call = bcm2836_arm_irqchip_cpu_notify, 222 .notifier_call = bcm2836_arm_irqchip_cpu_notify,
218 .priority = 100, 223 .priority = 100,
219}; 224};
225
226int __init bcm2836_smp_boot_secondary(unsigned int cpu,
227 struct task_struct *idle)
228{
229 unsigned long secondary_startup_phys =
230 (unsigned long)virt_to_phys((void *)secondary_startup);
231
232 dsb();
233 writel(secondary_startup_phys,
234 intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
235
236 return 0;
237}
238
239static const struct smp_operations bcm2836_smp_ops __initconst = {
240 .smp_boot_secondary = bcm2836_smp_boot_secondary,
241};
242
220#endif 243#endif
221 244
222static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { 245static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
@@ -234,9 +257,31 @@ bcm2836_arm_irqchip_smp_init(void)
234 register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier); 257 register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier);
235 258
236 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 259 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
260 smp_set_ops(&bcm2836_smp_ops);
237#endif 261#endif
238} 262}
239 263
264/*
265 * The LOCAL_IRQ_CNT* timer firings are based off of the external
266 * oscillator with some scaling. The firmware sets up CNTFRQ to
267 * report 19.2Mhz, but doesn't set up the scaling registers.
268 */
269static void bcm2835_init_local_timer_frequency(void)
270{
271 /*
272 * Set the timer to source from the 19.2Mhz crystal clock (bit
273 * 8 unset), and only increment by 1 instead of 2 (bit 9
274 * unset).
275 */
276 writel(0, intc.base + LOCAL_CONTROL);
277
278 /*
279 * Set the timer prescaler to 1:1 (timer freq = input freq *
280 * 2**31 / prescaler)
281 */
282 writel(0x80000000, intc.base + LOCAL_PRESCALER);
283}
284
240static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, 285static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
241 struct device_node *parent) 286 struct device_node *parent)
242{ 287{
@@ -246,6 +291,8 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
246 node->full_name); 291 node->full_name);
247 } 292 }
248 293
294 bcm2835_init_local_timer_frequency();
295
249 intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, 296 intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1,
250 &bcm2836_arm_irqchip_intc_ops, 297 &bcm2836_arm_irqchip_intc_ops,
251 NULL); 298 NULL);
diff --git a/drivers/irqchip/irq-gic-realview.c b/drivers/irqchip/irq-gic-realview.c
new file mode 100644
index 000000000000..aa46eb280a7f
--- /dev/null
+++ b/drivers/irqchip/irq-gic-realview.c
@@ -0,0 +1,43 @@
1/*
2 * Special GIC quirks for the ARM RealView
3 * Copyright (C) 2015 Linus Walleij
4 */
5#include <linux/of.h>
6#include <linux/regmap.h>
7#include <linux/mfd/syscon.h>
8#include <linux/bitops.h>
9#include <linux/irqchip.h>
10#include <linux/irqchip/arm-gic.h>
11
12#define REALVIEW_SYS_LOCK_OFFSET 0x20
13#define REALVIEW_PB11MP_SYS_PLD_CTRL1 0x74
14#define VERSATILE_LOCK_VAL 0xA05F
15#define PLD_INTMODE_MASK BIT(22)|BIT(23)|BIT(24)
16#define PLD_INTMODE_LEGACY 0x0
17#define PLD_INTMODE_NEW_DCC BIT(22)
18#define PLD_INTMODE_NEW_NO_DCC BIT(23)
19#define PLD_INTMODE_FIQ_ENABLE BIT(24)
20
21static int __init
22realview_gic_of_init(struct device_node *node, struct device_node *parent)
23{
24 static struct regmap *map;
25
26 /* The PB11MPCore GIC needs to be configured in the syscon */
27 map = syscon_regmap_lookup_by_compatible("arm,realview-pb11mp-syscon");
28 if (!IS_ERR(map)) {
29 /* new irq mode with no DCC */
30 regmap_write(map, REALVIEW_SYS_LOCK_OFFSET,
31 VERSATILE_LOCK_VAL);
32 regmap_update_bits(map, REALVIEW_PB11MP_SYS_PLD_CTRL1,
33 PLD_INTMODE_NEW_NO_DCC,
34 PLD_INTMODE_MASK);
35 regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, 0x0000);
36 pr_info("TC11MP GIC: set up interrupt controller to NEW mode, no DCC\n");
37 } else {
38 pr_err("TC11MP GIC setup: could not find syscon\n");
39 return -ENXIO;
40 }
41 return gic_of_init(node, parent);
42}
43IRQCHIP_DECLARE(armtc11mp_gic, "arm,tc11mp-gic", realview_gic_of_init);
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 87f8d104acab..c779f83e511d 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -15,9 +15,11 @@
15 15
16#define pr_fmt(fmt) "GICv2m: " fmt 16#define pr_fmt(fmt) "GICv2m: " fmt
17 17
18#include <linux/acpi.h>
18#include <linux/irq.h> 19#include <linux/irq.h>
19#include <linux/irqdomain.h> 20#include <linux/irqdomain.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/msi.h>
21#include <linux/of_address.h> 23#include <linux/of_address.h>
22#include <linux/of_pci.h> 24#include <linux/of_pci.h>
23#include <linux/slab.h> 25#include <linux/slab.h>
@@ -55,7 +57,7 @@ static DEFINE_SPINLOCK(v2m_lock);
55 57
56struct v2m_data { 58struct v2m_data {
57 struct list_head entry; 59 struct list_head entry;
58 struct device_node *node; 60 struct fwnode_handle *fwnode;
59 struct resource res; /* GICv2m resource */ 61 struct resource res; /* GICv2m resource */
60 void __iomem *base; /* GICv2m virt address */ 62 void __iomem *base; /* GICv2m virt address */
61 u32 spi_start; /* The SPI number that MSIs start */ 63 u32 spi_start; /* The SPI number that MSIs start */
@@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
138 fwspec.param[0] = 0; 140 fwspec.param[0] = 0;
139 fwspec.param[1] = hwirq - 32; 141 fwspec.param[1] = hwirq - 32;
140 fwspec.param[2] = IRQ_TYPE_EDGE_RISING; 142 fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
143 } else if (is_fwnode_irqchip(domain->parent->fwnode)) {
144 fwspec.fwnode = domain->parent->fwnode;
145 fwspec.param_count = 2;
146 fwspec.param[0] = hwirq;
147 fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
141 } else { 148 } else {
142 return -EINVAL; 149 return -EINVAL;
143 } 150 }
@@ -254,7 +261,9 @@ static void gicv2m_teardown(void)
254 list_del(&v2m->entry); 261 list_del(&v2m->entry);
255 kfree(v2m->bm); 262 kfree(v2m->bm);
256 iounmap(v2m->base); 263 iounmap(v2m->base);
257 of_node_put(v2m->node); 264 of_node_put(to_of_node(v2m->fwnode));
265 if (is_fwnode_irqchip(v2m->fwnode))
266 irq_domain_free_fwnode(v2m->fwnode);
258 kfree(v2m); 267 kfree(v2m);
259 } 268 }
260} 269}
@@ -268,7 +277,7 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
268 if (!v2m) 277 if (!v2m)
269 return 0; 278 return 0;
270 279
271 inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node), 280 inner_domain = irq_domain_create_tree(v2m->fwnode,
272 &gicv2m_domain_ops, v2m); 281 &gicv2m_domain_ops, v2m);
273 if (!inner_domain) { 282 if (!inner_domain) {
274 pr_err("Failed to create GICv2m domain\n"); 283 pr_err("Failed to create GICv2m domain\n");
@@ -277,10 +286,10 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
277 286
278 inner_domain->bus_token = DOMAIN_BUS_NEXUS; 287 inner_domain->bus_token = DOMAIN_BUS_NEXUS;
279 inner_domain->parent = parent; 288 inner_domain->parent = parent;
280 pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node), 289 pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
281 &gicv2m_msi_domain_info, 290 &gicv2m_msi_domain_info,
282 inner_domain); 291 inner_domain);
283 plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node), 292 plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
284 &gicv2m_pmsi_domain_info, 293 &gicv2m_pmsi_domain_info,
285 inner_domain); 294 inner_domain);
286 if (!pci_domain || !plat_domain) { 295 if (!pci_domain || !plat_domain) {
@@ -296,8 +305,9 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
296 return 0; 305 return 0;
297} 306}
298 307
299static int __init gicv2m_init_one(struct device_node *node, 308static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
300 struct irq_domain *parent) 309 u32 spi_start, u32 nr_spis,
310 struct resource *res)
301{ 311{
302 int ret; 312 int ret;
303 struct v2m_data *v2m; 313 struct v2m_data *v2m;
@@ -309,13 +319,9 @@ static int __init gicv2m_init_one(struct device_node *node,
309 } 319 }
310 320
311 INIT_LIST_HEAD(&v2m->entry); 321 INIT_LIST_HEAD(&v2m->entry);
312 v2m->node = node; 322 v2m->fwnode = fwnode;
313 323
314 ret = of_address_to_resource(node, 0, &v2m->res); 324 memcpy(&v2m->res, res, sizeof(struct resource));
315 if (ret) {
316 pr_err("Failed to allocate v2m resource.\n");
317 goto err_free_v2m;
318 }
319 325
320 v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res)); 326 v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
321 if (!v2m->base) { 327 if (!v2m->base) {
@@ -324,10 +330,9 @@ static int __init gicv2m_init_one(struct device_node *node,
324 goto err_free_v2m; 330 goto err_free_v2m;
325 } 331 }
326 332
327 if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) && 333 if (spi_start && nr_spis) {
328 !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) { 334 v2m->spi_start = spi_start;
329 pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n", 335 v2m->nr_spis = nr_spis;
330 v2m->spi_start, v2m->nr_spis);
331 } else { 336 } else {
332 u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER); 337 u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
333 338
@@ -359,10 +364,9 @@ static int __init gicv2m_init_one(struct device_node *node,
359 } 364 }
360 365
361 list_add_tail(&v2m->entry, &v2m_nodes); 366 list_add_tail(&v2m->entry, &v2m_nodes);
362 pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
363 (unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
364 v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
365 367
368 pr_info("range%pR, SPI[%d:%d]\n", res,
369 v2m->spi_start, (v2m->spi_start + v2m->nr_spis - 1));
366 return 0; 370 return 0;
367 371
368err_iounmap: 372err_iounmap:
@@ -377,19 +381,36 @@ static struct of_device_id gicv2m_device_id[] = {
377 {}, 381 {},
378}; 382};
379 383
380int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent) 384static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
385 struct irq_domain *parent)
381{ 386{
382 int ret = 0; 387 int ret = 0;
388 struct device_node *node = to_of_node(parent_handle);
383 struct device_node *child; 389 struct device_node *child;
384 390
385 for (child = of_find_matching_node(node, gicv2m_device_id); child; 391 for (child = of_find_matching_node(node, gicv2m_device_id); child;
386 child = of_find_matching_node(child, gicv2m_device_id)) { 392 child = of_find_matching_node(child, gicv2m_device_id)) {
393 u32 spi_start = 0, nr_spis = 0;
394 struct resource res;
395
387 if (!of_find_property(child, "msi-controller", NULL)) 396 if (!of_find_property(child, "msi-controller", NULL))
388 continue; 397 continue;
389 398
390 ret = gicv2m_init_one(child, parent); 399 ret = of_address_to_resource(child, 0, &res);
400 if (ret) {
401 pr_err("Failed to allocate v2m resource.\n");
402 break;
403 }
404
405 if (!of_property_read_u32(child, "arm,msi-base-spi",
406 &spi_start) &&
407 !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
408 pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n",
409 spi_start, nr_spis);
410
411 ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res);
391 if (ret) { 412 if (ret) {
392 of_node_put(node); 413 of_node_put(child);
393 break; 414 break;
394 } 415 }
395 } 416 }
@@ -400,3 +421,101 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
400 gicv2m_teardown(); 421 gicv2m_teardown();
401 return ret; 422 return ret;
402} 423}
424
425#ifdef CONFIG_ACPI
426static int acpi_num_msi;
427
428static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
429{
430 struct v2m_data *data;
431
432 if (WARN_ON(acpi_num_msi <= 0))
433 return NULL;
434
435 /* We only return the fwnode of the first MSI frame. */
436 data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
437 if (!data)
438 return NULL;
439
440 return data->fwnode;
441}
442
443static int __init
444acpi_parse_madt_msi(struct acpi_subtable_header *header,
445 const unsigned long end)
446{
447 int ret;
448 struct resource res;
449 u32 spi_start = 0, nr_spis = 0;
450 struct acpi_madt_generic_msi_frame *m;
451 struct fwnode_handle *fwnode;
452
453 m = (struct acpi_madt_generic_msi_frame *)header;
454 if (BAD_MADT_ENTRY(m, end))
455 return -EINVAL;
456
457 res.start = m->base_address;
458 res.end = m->base_address + SZ_4K - 1;
459 res.flags = IORESOURCE_MEM;
460
461 if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
462 spi_start = m->spi_base;
463 nr_spis = m->spi_count;
464
465 pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
466 spi_start, nr_spis);
467 }
468
469 fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
470 if (!fwnode) {
471 pr_err("Unable to allocate GICv2m domain token\n");
472 return -EINVAL;
473 }
474
475 ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
476 if (ret)
477 irq_domain_free_fwnode(fwnode);
478
479 return ret;
480}
481
482static int __init gicv2m_acpi_init(struct irq_domain *parent)
483{
484 int ret;
485
486 if (acpi_num_msi > 0)
487 return 0;
488
489 acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
490 acpi_parse_madt_msi, 0);
491
492 if (acpi_num_msi <= 0)
493 goto err_out;
494
495 ret = gicv2m_allocate_domains(parent);
496 if (ret)
497 goto err_out;
498
499 pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
500
501 return 0;
502
503err_out:
504 gicv2m_teardown();
505 return -EINVAL;
506}
507#else /* CONFIG_ACPI */
508static int __init gicv2m_acpi_init(struct irq_domain *parent)
509{
510 return -EINVAL;
511}
512#endif /* CONFIG_ACPI */
513
514int __init gicv2m_init(struct fwnode_handle *parent_handle,
515 struct irq_domain *parent)
516{
517 if (is_of_node(parent_handle))
518 return gicv2m_of_init(parent_handle, parent);
519
520 return gicv2m_acpi_init(parent);
521}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index abf2ffaed392..911758c056c1 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -69,6 +69,7 @@ union gic_base {
69}; 69};
70 70
71struct gic_chip_data { 71struct gic_chip_data {
72 struct irq_chip chip;
72 union gic_base dist_base; 73 union gic_base dist_base;
73 union gic_base cpu_base; 74 union gic_base cpu_base;
74#ifdef CONFIG_CPU_PM 75#ifdef CONFIG_CPU_PM
@@ -99,11 +100,7 @@ static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
99 100
100static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE; 101static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
101 102
102#ifndef MAX_GIC_NR 103static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly;
103#define MAX_GIC_NR 1
104#endif
105
106static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
107 104
108#ifdef CONFIG_GIC_NON_BANKED 105#ifdef CONFIG_GIC_NON_BANKED
109static void __iomem *gic_get_percpu_base(union gic_base *base) 106static void __iomem *gic_get_percpu_base(union gic_base *base)
@@ -336,7 +333,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
336 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); 333 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
337 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 334 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
338 335
339 if (likely(irqnr > 15 && irqnr < 1021)) { 336 if (likely(irqnr > 15 && irqnr < 1020)) {
340 if (static_key_true(&supports_deactivate)) 337 if (static_key_true(&supports_deactivate))
341 writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); 338 writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
342 handle_domain_irq(gic->domain, irqnr, regs); 339 handle_domain_irq(gic->domain, irqnr, regs);
@@ -383,7 +380,6 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
383} 380}
384 381
385static struct irq_chip gic_chip = { 382static struct irq_chip gic_chip = {
386 .name = "GIC",
387 .irq_mask = gic_mask_irq, 383 .irq_mask = gic_mask_irq,
388 .irq_unmask = gic_unmask_irq, 384 .irq_unmask = gic_unmask_irq,
389 .irq_eoi = gic_eoi_irq, 385 .irq_eoi = gic_eoi_irq,
@@ -417,8 +413,7 @@ static struct irq_chip gic_eoimode1_chip = {
417 413
418void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) 414void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
419{ 415{
420 if (gic_nr >= MAX_GIC_NR) 416 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
421 BUG();
422 irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, 417 irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq,
423 &gic_data[gic_nr]); 418 &gic_data[gic_nr]);
424} 419}
@@ -524,7 +519,7 @@ int gic_cpu_if_down(unsigned int gic_nr)
524 void __iomem *cpu_base; 519 void __iomem *cpu_base;
525 u32 val = 0; 520 u32 val = 0;
526 521
527 if (gic_nr >= MAX_GIC_NR) 522 if (gic_nr >= CONFIG_ARM_GIC_MAX_NR)
528 return -EINVAL; 523 return -EINVAL;
529 524
530 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); 525 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
@@ -548,8 +543,7 @@ static void gic_dist_save(unsigned int gic_nr)
548 void __iomem *dist_base; 543 void __iomem *dist_base;
549 int i; 544 int i;
550 545
551 if (gic_nr >= MAX_GIC_NR) 546 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
552 BUG();
553 547
554 gic_irqs = gic_data[gic_nr].gic_irqs; 548 gic_irqs = gic_data[gic_nr].gic_irqs;
555 dist_base = gic_data_dist_base(&gic_data[gic_nr]); 549 dist_base = gic_data_dist_base(&gic_data[gic_nr]);
@@ -587,8 +581,7 @@ static void gic_dist_restore(unsigned int gic_nr)
587 unsigned int i; 581 unsigned int i;
588 void __iomem *dist_base; 582 void __iomem *dist_base;
589 583
590 if (gic_nr >= MAX_GIC_NR) 584 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
591 BUG();
592 585
593 gic_irqs = gic_data[gic_nr].gic_irqs; 586 gic_irqs = gic_data[gic_nr].gic_irqs;
594 dist_base = gic_data_dist_base(&gic_data[gic_nr]); 587 dist_base = gic_data_dist_base(&gic_data[gic_nr]);
@@ -634,8 +627,7 @@ static void gic_cpu_save(unsigned int gic_nr)
634 void __iomem *dist_base; 627 void __iomem *dist_base;
635 void __iomem *cpu_base; 628 void __iomem *cpu_base;
636 629
637 if (gic_nr >= MAX_GIC_NR) 630 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
638 BUG();
639 631
640 dist_base = gic_data_dist_base(&gic_data[gic_nr]); 632 dist_base = gic_data_dist_base(&gic_data[gic_nr]);
641 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); 633 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
@@ -664,8 +656,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
664 void __iomem *dist_base; 656 void __iomem *dist_base;
665 void __iomem *cpu_base; 657 void __iomem *cpu_base;
666 658
667 if (gic_nr >= MAX_GIC_NR) 659 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
668 BUG();
669 660
670 dist_base = gic_data_dist_base(&gic_data[gic_nr]); 661 dist_base = gic_data_dist_base(&gic_data[gic_nr]);
671 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); 662 cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
@@ -703,7 +694,7 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
703{ 694{
704 int i; 695 int i;
705 696
706 for (i = 0; i < MAX_GIC_NR; i++) { 697 for (i = 0; i < CONFIG_ARM_GIC_MAX_NR; i++) {
707#ifdef CONFIG_GIC_NON_BANKED 698#ifdef CONFIG_GIC_NON_BANKED
708 /* Skip over unused GICs */ 699 /* Skip over unused GICs */
709 if (!gic_data[i].get_base) 700 if (!gic_data[i].get_base)
@@ -835,8 +826,7 @@ void gic_migrate_target(unsigned int new_cpu_id)
835 int i, ror_val, cpu = smp_processor_id(); 826 int i, ror_val, cpu = smp_processor_id();
836 u32 val, cur_target_mask, active_mask; 827 u32 val, cur_target_mask, active_mask;
837 828
838 if (gic_nr >= MAX_GIC_NR) 829 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
839 BUG();
840 830
841 dist_base = gic_data_dist_base(&gic_data[gic_nr]); 831 dist_base = gic_data_dist_base(&gic_data[gic_nr]);
842 if (!dist_base) 832 if (!dist_base)
@@ -925,20 +915,15 @@ void __init gic_init_physaddr(struct device_node *node)
925static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, 915static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
926 irq_hw_number_t hw) 916 irq_hw_number_t hw)
927{ 917{
928 struct irq_chip *chip = &gic_chip; 918 struct gic_chip_data *gic = d->host_data;
929
930 if (static_key_true(&supports_deactivate)) {
931 if (d->host_data == (void *)&gic_data[0])
932 chip = &gic_eoimode1_chip;
933 }
934 919
935 if (hw < 32) { 920 if (hw < 32) {
936 irq_set_percpu_devid(irq); 921 irq_set_percpu_devid(irq);
937 irq_domain_set_info(d, irq, hw, chip, d->host_data, 922 irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data,
938 handle_percpu_devid_irq, NULL, NULL); 923 handle_percpu_devid_irq, NULL, NULL);
939 irq_set_status_flags(irq, IRQ_NOAUTOEN); 924 irq_set_status_flags(irq, IRQ_NOAUTOEN);
940 } else { 925 } else {
941 irq_domain_set_info(d, irq, hw, chip, d->host_data, 926 irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data,
942 handle_fasteoi_irq, NULL, NULL); 927 handle_fasteoi_irq, NULL, NULL);
943 irq_set_probe(irq); 928 irq_set_probe(irq);
944 } 929 }
@@ -972,7 +957,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
972 return 0; 957 return 0;
973 } 958 }
974 959
975 if (fwspec->fwnode->type == FWNODE_IRQCHIP) { 960 if (is_fwnode_irqchip(fwspec->fwnode)) {
976 if(fwspec->param_count != 2) 961 if(fwspec->param_count != 2)
977 return -EINVAL; 962 return -EINVAL;
978 963
@@ -1040,11 +1025,20 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1040 struct gic_chip_data *gic; 1025 struct gic_chip_data *gic;
1041 int gic_irqs, irq_base, i; 1026 int gic_irqs, irq_base, i;
1042 1027
1043 BUG_ON(gic_nr >= MAX_GIC_NR); 1028 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
1044 1029
1045 gic_check_cpu_features(); 1030 gic_check_cpu_features();
1046 1031
1047 gic = &gic_data[gic_nr]; 1032 gic = &gic_data[gic_nr];
1033
1034 /* Initialize irq_chip */
1035 if (static_key_true(&supports_deactivate) && gic_nr == 0) {
1036 gic->chip = gic_eoimode1_chip;
1037 } else {
1038 gic->chip = gic_chip;
1039 gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr);
1040 }
1041
1048#ifdef CONFIG_GIC_NON_BANKED 1042#ifdef CONFIG_GIC_NON_BANKED
1049 if (percpu_offset) { /* Frankein-GIC without banked registers... */ 1043 if (percpu_offset) { /* Frankein-GIC without banked registers... */
1050 unsigned int cpu; 1044 unsigned int cpu;
@@ -1196,7 +1190,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
1196 return true; 1190 return true;
1197} 1191}
1198 1192
1199static int __init 1193int __init
1200gic_of_init(struct device_node *node, struct device_node *parent) 1194gic_of_init(struct device_node *node, struct device_node *parent)
1201{ 1195{
1202 void __iomem *cpu_base; 1196 void __iomem *cpu_base;
@@ -1234,7 +1228,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
1234 } 1228 }
1235 1229
1236 if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) 1230 if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
1237 gicv2m_of_init(node, gic_data[gic_cnt].domain); 1231 gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
1238 1232
1239 gic_cnt++; 1233 gic_cnt++;
1240 return 0; 1234 return 0;
@@ -1359,6 +1353,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1359 __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle); 1353 __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
1360 1354
1361 acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle); 1355 acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
1356
1357 if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
1358 gicv2m_init(NULL, gic_data[0].domain);
1359
1362 return 0; 1360 return 0;
1363} 1361}
1364IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 1362IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
new file mode 100644
index 000000000000..4dd3eb8a40b3
--- /dev/null
+++ b/drivers/irqchip/irq-mbigen.c
@@ -0,0 +1,297 @@
1/*
2 * Copyright (C) 2015 Hisilicon Limited, All Rights Reserved.
3 * Author: Jun Ma <majun258@huawei.com>
4 * Author: Yun Wu <wuyun.wu@huawei.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/interrupt.h>
20#include <linux/irqchip.h>
21#include <linux/module.h>
22#include <linux/msi.h>
23#include <linux/of_address.h>
24#include <linux/of_irq.h>
25#include <linux/of_platform.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28
29/* Interrupt numbers per mbigen node supported */
30#define IRQS_PER_MBIGEN_NODE 128
31
32/* 64 irqs (Pin0-pin63) are reserved for each mbigen chip */
33#define RESERVED_IRQ_PER_MBIGEN_CHIP 64
34
35/* The maximum IRQ pin number of mbigen chip(start from 0) */
36#define MAXIMUM_IRQ_PIN_NUM 1407
37
38/**
39 * In mbigen vector register
40 * bit[21:12]: event id value
41 * bit[11:0]: device id
42 */
43#define IRQ_EVENT_ID_SHIFT 12
44#define IRQ_EVENT_ID_MASK 0x3ff
45
46/* register range of each mbigen node */
47#define MBIGEN_NODE_OFFSET 0x1000
48
49/* offset of vector register in mbigen node */
50#define REG_MBIGEN_VEC_OFFSET 0x200
51
52/**
53 * offset of clear register in mbigen node
54 * This register is used to clear the status
55 * of interrupt
56 */
57#define REG_MBIGEN_CLEAR_OFFSET 0xa000
58
59/**
60 * offset of interrupt type register
61 * This register is used to configure interrupt
62 * trigger type
63 */
64#define REG_MBIGEN_TYPE_OFFSET 0x0
65
66/**
67 * struct mbigen_device - holds the information of mbigen device.
68 *
69 * @pdev: pointer to the platform device structure of mbigen chip.
70 * @base: mapped address of this mbigen chip.
71 */
72struct mbigen_device {
73 struct platform_device *pdev;
74 void __iomem *base;
75};
76
77static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
78{
79 unsigned int nid, pin;
80
81 hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
82 nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
83 pin = hwirq % IRQS_PER_MBIGEN_NODE;
84
85 return pin * 4 + nid * MBIGEN_NODE_OFFSET
86 + REG_MBIGEN_VEC_OFFSET;
87}
88
89static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
90 u32 *mask, u32 *addr)
91{
92 unsigned int nid, irq_ofst, ofst;
93
94 hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
95 nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
96 irq_ofst = hwirq % IRQS_PER_MBIGEN_NODE;
97
98 *mask = 1 << (irq_ofst % 32);
99 ofst = irq_ofst / 32 * 4;
100
101 *addr = ofst + nid * MBIGEN_NODE_OFFSET
102 + REG_MBIGEN_TYPE_OFFSET;
103}
104
105static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
106 u32 *mask, u32 *addr)
107{
108 unsigned int ofst;
109
110 hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
111 ofst = hwirq / 32 * 4;
112
113 *mask = 1 << (hwirq % 32);
114 *addr = ofst + REG_MBIGEN_CLEAR_OFFSET;
115}
116
117static void mbigen_eoi_irq(struct irq_data *data)
118{
119 void __iomem *base = data->chip_data;
120 u32 mask, addr;
121
122 get_mbigen_clear_reg(data->hwirq, &mask, &addr);
123
124 writel_relaxed(mask, base + addr);
125
126 irq_chip_eoi_parent(data);
127}
128
129static int mbigen_set_type(struct irq_data *data, unsigned int type)
130{
131 void __iomem *base = data->chip_data;
132 u32 mask, addr, val;
133
134 if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
135 return -EINVAL;
136
137 get_mbigen_type_reg(data->hwirq, &mask, &addr);
138
139 val = readl_relaxed(base + addr);
140
141 if (type == IRQ_TYPE_LEVEL_HIGH)
142 val |= mask;
143 else
144 val &= ~mask;
145
146 writel_relaxed(val, base + addr);
147
148 return 0;
149}
150
151static struct irq_chip mbigen_irq_chip = {
152 .name = "mbigen-v2",
153 .irq_mask = irq_chip_mask_parent,
154 .irq_unmask = irq_chip_unmask_parent,
155 .irq_eoi = mbigen_eoi_irq,
156 .irq_set_type = mbigen_set_type,
157 .irq_set_affinity = irq_chip_set_affinity_parent,
158};
159
160static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
161{
162 struct irq_data *d = irq_get_irq_data(desc->irq);
163 void __iomem *base = d->chip_data;
164 u32 val;
165
166 base += get_mbigen_vec_reg(d->hwirq);
167 val = readl_relaxed(base);
168
169 val &= ~(IRQ_EVENT_ID_MASK << IRQ_EVENT_ID_SHIFT);
170 val |= (msg->data << IRQ_EVENT_ID_SHIFT);
171
172 /* The address of doorbell is encoded in mbigen register by default
173 * So,we don't need to program the doorbell address at here
174 */
175 writel_relaxed(val, base);
176}
177
178static int mbigen_domain_translate(struct irq_domain *d,
179 struct irq_fwspec *fwspec,
180 unsigned long *hwirq,
181 unsigned int *type)
182{
183 if (is_of_node(fwspec->fwnode)) {
184 if (fwspec->param_count != 2)
185 return -EINVAL;
186
187 if ((fwspec->param[0] > MAXIMUM_IRQ_PIN_NUM) ||
188 (fwspec->param[0] < RESERVED_IRQ_PER_MBIGEN_CHIP))
189 return -EINVAL;
190 else
191 *hwirq = fwspec->param[0];
192
193 /* If there is no valid irq type, just use the default type */
194 if ((fwspec->param[1] == IRQ_TYPE_EDGE_RISING) ||
195 (fwspec->param[1] == IRQ_TYPE_LEVEL_HIGH))
196 *type = fwspec->param[1];
197 else
198 return -EINVAL;
199
200 return 0;
201 }
202 return -EINVAL;
203}
204
205static int mbigen_irq_domain_alloc(struct irq_domain *domain,
206 unsigned int virq,
207 unsigned int nr_irqs,
208 void *args)
209{
210 struct irq_fwspec *fwspec = args;
211 irq_hw_number_t hwirq;
212 unsigned int type;
213 struct mbigen_device *mgn_chip;
214 int i, err;
215
216 err = mbigen_domain_translate(domain, fwspec, &hwirq, &type);
217 if (err)
218 return err;
219
220 err = platform_msi_domain_alloc(domain, virq, nr_irqs);
221 if (err)
222 return err;
223
224 mgn_chip = platform_msi_get_host_data(domain);
225
226 for (i = 0; i < nr_irqs; i++)
227 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
228 &mbigen_irq_chip, mgn_chip->base);
229
230 return 0;
231}
232
233static struct irq_domain_ops mbigen_domain_ops = {
234 .translate = mbigen_domain_translate,
235 .alloc = mbigen_irq_domain_alloc,
236 .free = irq_domain_free_irqs_common,
237};
238
239static int mbigen_device_probe(struct platform_device *pdev)
240{
241 struct mbigen_device *mgn_chip;
242 struct resource *res;
243 struct irq_domain *domain;
244 u32 num_pins;
245
246 mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
247 if (!mgn_chip)
248 return -ENOMEM;
249
250 mgn_chip->pdev = pdev;
251
252 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
253 mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
254 if (IS_ERR(mgn_chip->base))
255 return PTR_ERR(mgn_chip->base);
256
257 if (of_property_read_u32(pdev->dev.of_node, "num-pins", &num_pins) < 0) {
258 dev_err(&pdev->dev, "No num-pins property\n");
259 return -EINVAL;
260 }
261
262 domain = platform_msi_create_device_domain(&pdev->dev, num_pins,
263 mbigen_write_msg,
264 &mbigen_domain_ops,
265 mgn_chip);
266
267 if (!domain)
268 return -ENOMEM;
269
270 platform_set_drvdata(pdev, mgn_chip);
271
272 dev_info(&pdev->dev, "Allocated %d MSIs\n", num_pins);
273
274 return 0;
275}
276
277static const struct of_device_id mbigen_of_match[] = {
278 { .compatible = "hisilicon,mbigen-v2" },
279 { /* END */ }
280};
281MODULE_DEVICE_TABLE(of, mbigen_of_match);
282
283static struct platform_driver mbigen_platform_driver = {
284 .driver = {
285 .name = "Hisilicon MBIGEN-V2",
286 .owner = THIS_MODULE,
287 .of_match_table = mbigen_of_match,
288 },
289 .probe = mbigen_device_probe,
290};
291
292module_platform_driver(mbigen_platform_driver);
293
294MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
295MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
296MODULE_LICENSE("GPL");
297MODULE_DESCRIPTION("Hisilicon MBI Generator driver");
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c
index 8587d0f8d8c0..9d1bcfc33e4c 100644
--- a/drivers/irqchip/irq-omap-intc.c
+++ b/drivers/irqchip/irq-omap-intc.c
@@ -47,6 +47,7 @@
47#define INTC_ILR0 0x0100 47#define INTC_ILR0 0x0100
48 48
49#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */ 49#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */
50#define SPURIOUSIRQ_MASK (0x1ffffff << 7)
50#define INTCPS_NR_ILR_REGS 128 51#define INTCPS_NR_ILR_REGS 128
51#define INTCPS_NR_MIR_REGS 4 52#define INTCPS_NR_MIR_REGS 4
52 53
@@ -207,7 +208,6 @@ static int __init omap_alloc_gc_of(struct irq_domain *d, void __iomem *base)
207 ct = gc->chip_types; 208 ct = gc->chip_types;
208 209
209 ct->type = IRQ_TYPE_LEVEL_MASK; 210 ct->type = IRQ_TYPE_LEVEL_MASK;
210 ct->handler = handle_level_irq;
211 211
212 ct->chip.irq_ack = omap_mask_ack_irq; 212 ct->chip.irq_ack = omap_mask_ack_irq;
213 ct->chip.irq_mask = irq_gc_mask_disable_reg; 213 ct->chip.irq_mask = irq_gc_mask_disable_reg;
@@ -330,11 +330,35 @@ static int __init omap_init_irq(u32 base, struct device_node *node)
330static asmlinkage void __exception_irq_entry 330static asmlinkage void __exception_irq_entry
331omap_intc_handle_irq(struct pt_regs *regs) 331omap_intc_handle_irq(struct pt_regs *regs)
332{ 332{
333 extern unsigned long irq_err_count;
333 u32 irqnr; 334 u32 irqnr;
334 335
335 irqnr = intc_readl(INTC_SIR); 336 irqnr = intc_readl(INTC_SIR);
337
338 /*
339 * A spurious IRQ can result if interrupt that triggered the
340 * sorting is no longer active during the sorting (10 INTC
341 * functional clock cycles after interrupt assertion). Or a
342 * change in interrupt mask affected the result during sorting
343 * time. There is no special handling required except ignoring
344 * the SIR register value just read and retrying.
345 * See section 6.2.5 of AM335x TRM Literature Number: SPRUH73K
346 *
347 * Many a times, a spurious interrupt situation has been fixed
348 * by adding a flush for the posted write acking the IRQ in
349 * the device driver. Typically, this is going be the device
350 * driver whose interrupt was handled just before the spurious
351 * IRQ occurred. Pay attention to those device drivers if you
352 * run into hitting the spurious IRQ condition below.
353 */
354 if (unlikely((irqnr & SPURIOUSIRQ_MASK) == SPURIOUSIRQ_MASK)) {
355 pr_err_once("%s: spurious irq!\n", __func__);
356 irq_err_count++;
357 omap_ack_irq(NULL);
358 return;
359 }
360
336 irqnr &= ACTIVEIRQ_MASK; 361 irqnr &= ACTIVEIRQ_MASK;
337 WARN_ONCE(!irqnr, "Spurious IRQ ?\n");
338 handle_domain_irq(domain, irqnr, regs); 362 handle_domain_irq(domain, irqnr, regs);
339} 363}
340 364
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index c325806561be..713177d97c7a 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/of_device.h> 33#include <linux/of_device.h>
34#include <linux/platform_data/irq-renesas-intc-irqpin.h>
35#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
36 35
37#define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */ 36#define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */
@@ -75,18 +74,20 @@ struct intc_irqpin_irq {
75struct intc_irqpin_priv { 74struct intc_irqpin_priv {
76 struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; 75 struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR];
77 struct intc_irqpin_irq irq[INTC_IRQPIN_MAX]; 76 struct intc_irqpin_irq irq[INTC_IRQPIN_MAX];
78 struct renesas_intc_irqpin_config config; 77 unsigned int sense_bitfield_width;
79 unsigned int number_of_irqs;
80 struct platform_device *pdev; 78 struct platform_device *pdev;
81 struct irq_chip irq_chip; 79 struct irq_chip irq_chip;
82 struct irq_domain *irq_domain; 80 struct irq_domain *irq_domain;
83 struct clk *clk; 81 struct clk *clk;
84 bool shared_irqs; 82 unsigned shared_irqs:1;
83 unsigned needs_clk:1;
85 u8 shared_irq_mask; 84 u8 shared_irq_mask;
86}; 85};
87 86
88struct intc_irqpin_irlm_config { 87struct intc_irqpin_config {
89 unsigned int irlm_bit; 88 unsigned int irlm_bit;
89 unsigned needs_irlm:1;
90 unsigned needs_clk:1;
90}; 91};
91 92
92static unsigned long intc_irqpin_read32(void __iomem *iomem) 93static unsigned long intc_irqpin_read32(void __iomem *iomem)
@@ -171,7 +172,7 @@ static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p,
171static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value) 172static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value)
172{ 173{
173 /* The SENSE register is assumed to be 32-bit. */ 174 /* The SENSE register is assumed to be 32-bit. */
174 int bitfield_width = p->config.sense_bitfield_width; 175 int bitfield_width = p->sense_bitfield_width;
175 int shift = 32 - (irq + 1) * bitfield_width; 176 int shift = 32 - (irq + 1) * bitfield_width;
176 177
177 dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value); 178 dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value);
@@ -361,8 +362,15 @@ static const struct irq_domain_ops intc_irqpin_irq_domain_ops = {
361 .xlate = irq_domain_xlate_twocell, 362 .xlate = irq_domain_xlate_twocell,
362}; 363};
363 364
364static const struct intc_irqpin_irlm_config intc_irqpin_irlm_r8a777x = { 365static const struct intc_irqpin_config intc_irqpin_irlm_r8a777x = {
365 .irlm_bit = 23, /* ICR0.IRLM0 */ 366 .irlm_bit = 23, /* ICR0.IRLM0 */
367 .needs_irlm = 1,
368 .needs_clk = 0,
369};
370
371static const struct intc_irqpin_config intc_irqpin_rmobile = {
372 .needs_irlm = 0,
373 .needs_clk = 1,
366}; 374};
367 375
368static const struct of_device_id intc_irqpin_dt_ids[] = { 376static const struct of_device_id intc_irqpin_dt_ids[] = {
@@ -371,14 +379,18 @@ static const struct of_device_id intc_irqpin_dt_ids[] = {
371 .data = &intc_irqpin_irlm_r8a777x }, 379 .data = &intc_irqpin_irlm_r8a777x },
372 { .compatible = "renesas,intc-irqpin-r8a7779", 380 { .compatible = "renesas,intc-irqpin-r8a7779",
373 .data = &intc_irqpin_irlm_r8a777x }, 381 .data = &intc_irqpin_irlm_r8a777x },
382 { .compatible = "renesas,intc-irqpin-r8a7740",
383 .data = &intc_irqpin_rmobile },
384 { .compatible = "renesas,intc-irqpin-sh73a0",
385 .data = &intc_irqpin_rmobile },
374 {}, 386 {},
375}; 387};
376MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); 388MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids);
377 389
378static int intc_irqpin_probe(struct platform_device *pdev) 390static int intc_irqpin_probe(struct platform_device *pdev)
379{ 391{
392 const struct intc_irqpin_config *config = NULL;
380 struct device *dev = &pdev->dev; 393 struct device *dev = &pdev->dev;
381 struct renesas_intc_irqpin_config *pdata = dev->platform_data;
382 const struct of_device_id *of_id; 394 const struct of_device_id *of_id;
383 struct intc_irqpin_priv *p; 395 struct intc_irqpin_priv *p;
384 struct intc_irqpin_iomem *i; 396 struct intc_irqpin_iomem *i;
@@ -388,6 +400,8 @@ static int intc_irqpin_probe(struct platform_device *pdev)
388 void (*enable_fn)(struct irq_data *d); 400 void (*enable_fn)(struct irq_data *d);
389 void (*disable_fn)(struct irq_data *d); 401 void (*disable_fn)(struct irq_data *d);
390 const char *name = dev_name(dev); 402 const char *name = dev_name(dev);
403 bool control_parent;
404 unsigned int nirqs;
391 int ref_irq; 405 int ref_irq;
392 int ret; 406 int ret;
393 int k; 407 int k;
@@ -399,23 +413,28 @@ static int intc_irqpin_probe(struct platform_device *pdev)
399 } 413 }
400 414
401 /* deal with driver instance configuration */ 415 /* deal with driver instance configuration */
402 if (pdata) { 416 of_property_read_u32(dev->of_node, "sense-bitfield-width",
403 memcpy(&p->config, pdata, sizeof(*pdata)); 417 &p->sense_bitfield_width);
404 } else { 418 control_parent = of_property_read_bool(dev->of_node, "control-parent");
405 of_property_read_u32(dev->of_node, "sense-bitfield-width", 419 if (!p->sense_bitfield_width)
406 &p->config.sense_bitfield_width); 420 p->sense_bitfield_width = 4; /* default to 4 bits */
407 p->config.control_parent = of_property_read_bool(dev->of_node,
408 "control-parent");
409 }
410 if (!p->config.sense_bitfield_width)
411 p->config.sense_bitfield_width = 4; /* default to 4 bits */
412 421
413 p->pdev = pdev; 422 p->pdev = pdev;
414 platform_set_drvdata(pdev, p); 423 platform_set_drvdata(pdev, p);
415 424
425 of_id = of_match_device(intc_irqpin_dt_ids, dev);
426 if (of_id && of_id->data) {
427 config = of_id->data;
428 p->needs_clk = config->needs_clk;
429 }
430
416 p->clk = devm_clk_get(dev, NULL); 431 p->clk = devm_clk_get(dev, NULL);
417 if (IS_ERR(p->clk)) { 432 if (IS_ERR(p->clk)) {
418 dev_warn(dev, "unable to get clock\n"); 433 if (p->needs_clk) {
434 dev_err(dev, "unable to get clock\n");
435 ret = PTR_ERR(p->clk);
436 goto err0;
437 }
419 p->clk = NULL; 438 p->clk = NULL;
420 } 439 }
421 440
@@ -443,8 +462,8 @@ static int intc_irqpin_probe(struct platform_device *pdev)
443 p->irq[k].requested_irq = irq->start; 462 p->irq[k].requested_irq = irq->start;
444 } 463 }
445 464
446 p->number_of_irqs = k; 465 nirqs = k;
447 if (p->number_of_irqs < 1) { 466 if (nirqs < 1) {
448 dev_err(dev, "not enough IRQ resources\n"); 467 dev_err(dev, "not enough IRQ resources\n");
449 ret = -EINVAL; 468 ret = -EINVAL;
450 goto err0; 469 goto err0;
@@ -485,20 +504,16 @@ static int intc_irqpin_probe(struct platform_device *pdev)
485 } 504 }
486 505
487 /* configure "individual IRQ mode" where needed */ 506 /* configure "individual IRQ mode" where needed */
488 of_id = of_match_device(intc_irqpin_dt_ids, dev); 507 if (config && config->needs_irlm) {
489 if (of_id && of_id->data) {
490 const struct intc_irqpin_irlm_config *irlm_config = of_id->data;
491
492 if (io[INTC_IRQPIN_REG_IRLM]) 508 if (io[INTC_IRQPIN_REG_IRLM])
493 intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM, 509 intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM,
494 irlm_config->irlm_bit, 510 config->irlm_bit, 1, 1);
495 1, 1);
496 else 511 else
497 dev_warn(dev, "unable to select IRLM mode\n"); 512 dev_warn(dev, "unable to select IRLM mode\n");
498 } 513 }
499 514
500 /* mask all interrupts using priority */ 515 /* mask all interrupts using priority */
501 for (k = 0; k < p->number_of_irqs; k++) 516 for (k = 0; k < nirqs; k++)
502 intc_irqpin_mask_unmask_prio(p, k, 1); 517 intc_irqpin_mask_unmask_prio(p, k, 1);
503 518
504 /* clear all pending interrupts */ 519 /* clear all pending interrupts */
@@ -506,16 +521,16 @@ static int intc_irqpin_probe(struct platform_device *pdev)
506 521
507 /* scan for shared interrupt lines */ 522 /* scan for shared interrupt lines */
508 ref_irq = p->irq[0].requested_irq; 523 ref_irq = p->irq[0].requested_irq;
509 p->shared_irqs = true; 524 p->shared_irqs = 1;
510 for (k = 1; k < p->number_of_irqs; k++) { 525 for (k = 1; k < nirqs; k++) {
511 if (ref_irq != p->irq[k].requested_irq) { 526 if (ref_irq != p->irq[k].requested_irq) {
512 p->shared_irqs = false; 527 p->shared_irqs = 0;
513 break; 528 break;
514 } 529 }
515 } 530 }
516 531
517 /* use more severe masking method if requested */ 532 /* use more severe masking method if requested */
518 if (p->config.control_parent) { 533 if (control_parent) {
519 enable_fn = intc_irqpin_irq_enable_force; 534 enable_fn = intc_irqpin_irq_enable_force;
520 disable_fn = intc_irqpin_irq_disable_force; 535 disable_fn = intc_irqpin_irq_disable_force;
521 } else if (!p->shared_irqs) { 536 } else if (!p->shared_irqs) {
@@ -534,9 +549,7 @@ static int intc_irqpin_probe(struct platform_device *pdev)
534 irq_chip->irq_set_wake = intc_irqpin_irq_set_wake; 549 irq_chip->irq_set_wake = intc_irqpin_irq_set_wake;
535 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; 550 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
536 551
537 p->irq_domain = irq_domain_add_simple(dev->of_node, 552 p->irq_domain = irq_domain_add_simple(dev->of_node, nirqs, 0,
538 p->number_of_irqs,
539 p->config.irq_base,
540 &intc_irqpin_irq_domain_ops, p); 553 &intc_irqpin_irq_domain_ops, p);
541 if (!p->irq_domain) { 554 if (!p->irq_domain) {
542 ret = -ENXIO; 555 ret = -ENXIO;
@@ -555,7 +568,7 @@ static int intc_irqpin_probe(struct platform_device *pdev)
555 } 568 }
556 } else { 569 } else {
557 /* request interrupts one by one */ 570 /* request interrupts one by one */
558 for (k = 0; k < p->number_of_irqs; k++) { 571 for (k = 0; k < nirqs; k++) {
559 if (devm_request_irq(dev, p->irq[k].requested_irq, 572 if (devm_request_irq(dev, p->irq[k].requested_irq,
560 intc_irqpin_irq_handler, 0, name, 573 intc_irqpin_irq_handler, 0, name,
561 &p->irq[k])) { 574 &p->irq[k])) {
@@ -567,17 +580,10 @@ static int intc_irqpin_probe(struct platform_device *pdev)
567 } 580 }
568 581
569 /* unmask all interrupts on prio level */ 582 /* unmask all interrupts on prio level */
570 for (k = 0; k < p->number_of_irqs; k++) 583 for (k = 0; k < nirqs; k++)
571 intc_irqpin_mask_unmask_prio(p, k, 0); 584 intc_irqpin_mask_unmask_prio(p, k, 0);
572 585
573 dev_info(dev, "driving %d irqs\n", p->number_of_irqs); 586 dev_info(dev, "driving %d irqs\n", nirqs);
574
575 /* warn in case of mismatch if irq base is specified */
576 if (p->config.irq_base) {
577 if (p->config.irq_base != p->irq[0].domain_irq)
578 dev_warn(dev, "irq base mismatch (%d/%d)\n",
579 p->config.irq_base, p->irq[0].domain_irq);
580 }
581 587
582 return 0; 588 return 0;
583 589
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
index 4ef178078e5b..0820f67cc9a7 100644
--- a/drivers/irqchip/irq-sunxi-nmi.c
+++ b/drivers/irqchip/irq-sunxi-nmi.c
@@ -50,6 +50,12 @@ static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = {
50 .enable = 0x34, 50 .enable = 0x34,
51}; 51};
52 52
53static struct sunxi_sc_nmi_reg_offs sun9i_reg_offs = {
54 .ctrl = 0x00,
55 .pend = 0x08,
56 .enable = 0x04,
57};
58
53static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, 59static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
54 u32 val) 60 u32 val)
55{ 61{
@@ -207,3 +213,10 @@ static int __init sun7i_sc_nmi_irq_init(struct device_node *node,
207 return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs); 213 return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs);
208} 214}
209IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init); 215IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init);
216
217static int __init sun9i_nmi_irq_init(struct device_node *node,
218 struct device_node *parent)
219{
220 return sunxi_sc_nmi_irq_init(node, &sun9i_reg_offs);
221}
222IRQCHIP_DECLARE(sun9i_nmi, "allwinner,sun9i-a80-nmi", sun9i_nmi_irq_init);
diff --git a/drivers/irqchip/irq-ts4800.c b/drivers/irqchip/irq-ts4800.c
new file mode 100644
index 000000000000..4192bdcd2734
--- /dev/null
+++ b/drivers/irqchip/irq-ts4800.c
@@ -0,0 +1,163 @@
1/*
2 * Multiplexed-IRQs driver for TS-4800's FPGA
3 *
4 * Copyright (c) 2015 - Savoir-faire Linux
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/interrupt.h>
12#include <linux/io.h>
13#include <linux/irq.h>
14#include <linux/irqchip.h>
15#include <linux/irqchip/chained_irq.h>
16#include <linux/irqdomain.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <linux/platform_device.h>
22
23#define IRQ_MASK 0x4
24#define IRQ_STATUS 0x8
25
26struct ts4800_irq_data {
27 void __iomem *base;
28 struct irq_domain *domain;
29 struct irq_chip irq_chip;
30};
31
32static void ts4800_irq_mask(struct irq_data *d)
33{
34 struct ts4800_irq_data *data = irq_data_get_irq_chip_data(d);
35 u16 reg = readw(data->base + IRQ_MASK);
36 u16 mask = 1 << d->hwirq;
37
38 writew(reg | mask, data->base + IRQ_MASK);
39}
40
41static void ts4800_irq_unmask(struct irq_data *d)
42{
43 struct ts4800_irq_data *data = irq_data_get_irq_chip_data(d);
44 u16 reg = readw(data->base + IRQ_MASK);
45 u16 mask = 1 << d->hwirq;
46
47 writew(reg & ~mask, data->base + IRQ_MASK);
48}
49
50static int ts4800_irqdomain_map(struct irq_domain *d, unsigned int irq,
51 irq_hw_number_t hwirq)
52{
53 struct ts4800_irq_data *data = d->host_data;
54
55 irq_set_chip_and_handler(irq, &data->irq_chip, handle_simple_irq);
56 irq_set_chip_data(irq, data);
57 irq_set_noprobe(irq);
58
59 return 0;
60}
61
62struct irq_domain_ops ts4800_ic_ops = {
63 .map = ts4800_irqdomain_map,
64 .xlate = irq_domain_xlate_onecell,
65};
66
67static void ts4800_ic_chained_handle_irq(struct irq_desc *desc)
68{
69 struct ts4800_irq_data *data = irq_desc_get_handler_data(desc);
70 struct irq_chip *chip = irq_desc_get_chip(desc);
71 u16 status = readw(data->base + IRQ_STATUS);
72
73 chained_irq_enter(chip, desc);
74
75 if (unlikely(status == 0)) {
76 handle_bad_irq(desc);
77 goto out;
78 }
79
80 do {
81 unsigned int bit = __ffs(status);
82 int irq = irq_find_mapping(data->domain, bit);
83
84 status &= ~(1 << bit);
85 generic_handle_irq(irq);
86 } while (status);
87
88out:
89 chained_irq_exit(chip, desc);
90}
91
92static int ts4800_ic_probe(struct platform_device *pdev)
93{
94 struct device_node *node = pdev->dev.of_node;
95 struct ts4800_irq_data *data;
96 struct irq_chip *irq_chip;
97 struct resource *res;
98 int parent_irq;
99
100 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
101 if (!data)
102 return -ENOMEM;
103
104 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
105 data->base = devm_ioremap_resource(&pdev->dev, res);
106 if (IS_ERR(data->base))
107 return PTR_ERR(data->base);
108
109 writew(0xFFFF, data->base + IRQ_MASK);
110
111 parent_irq = irq_of_parse_and_map(node, 0);
112 if (!parent_irq) {
113 dev_err(&pdev->dev, "failed to get parent IRQ\n");
114 return -EINVAL;
115 }
116
117 irq_chip = &data->irq_chip;
118 irq_chip->name = dev_name(&pdev->dev);
119 irq_chip->irq_mask = ts4800_irq_mask;
120 irq_chip->irq_unmask = ts4800_irq_unmask;
121
122 data->domain = irq_domain_add_linear(node, 8, &ts4800_ic_ops, data);
123 if (!data->domain) {
124 dev_err(&pdev->dev, "cannot add IRQ domain\n");
125 return -ENOMEM;
126 }
127
128 irq_set_chained_handler_and_data(parent_irq,
129 ts4800_ic_chained_handle_irq, data);
130
131 platform_set_drvdata(pdev, data);
132
133 return 0;
134}
135
136static int ts4800_ic_remove(struct platform_device *pdev)
137{
138 struct ts4800_irq_data *data = platform_get_drvdata(pdev);
139
140 irq_domain_remove(data->domain);
141
142 return 0;
143}
144
145static const struct of_device_id ts4800_ic_of_match[] = {
146 { .compatible = "technologic,ts4800-irqc", },
147 {},
148};
149MODULE_DEVICE_TABLE(of, ts4800_ic_of_match);
150
151static struct platform_driver ts4800_ic_driver = {
152 .probe = ts4800_ic_probe,
153 .remove = ts4800_ic_remove,
154 .driver = {
155 .name = "ts4800-irqc",
156 .of_match_table = ts4800_ic_of_match,
157 },
158};
159module_platform_driver(ts4800_ic_driver);
160
161MODULE_AUTHOR("Damien Riegel <damien.riegel@savoirfairelinux.com>");
162MODULE_LICENSE("GPL v2");
163MODULE_ALIAS("platform:ts4800_irqc");
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c
index 4c48fa88a03d..cb9d8ec37507 100644
--- a/drivers/irqchip/irq-zevio.c
+++ b/drivers/irqchip/irq-zevio.c
@@ -43,8 +43,7 @@ static void __iomem *zevio_irq_io;
43static void zevio_irq_ack(struct irq_data *irqd) 43static void zevio_irq_ack(struct irq_data *irqd)
44{ 44{
45 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd); 45 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd);
46 struct irq_chip_regs *regs = 46 struct irq_chip_regs *regs = &irq_data_get_chip_type(irqd)->regs;
47 &container_of(irqd->chip, struct irq_chip_type, chip)->regs;
48 47
49 readl(gc->reg_base + regs->ack); 48 readl(gc->reg_base + regs->ack);
50} 49}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7eaa4c87fec7..7a0df3fdbfae 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
257{ 257{
258 msi_set_mask_bit(data, 1); 258 msi_set_mask_bit(data, 1);
259} 259}
260EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
260 261
261/** 262/**
262 * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts 263 * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
266{ 267{
267 msi_set_mask_bit(data, 0); 268 msi_set_mask_bit(data, 0);
268} 269}
270EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
269 271
270void default_restore_msi_irqs(struct pci_dev *dev) 272void default_restore_msi_irqs(struct pci_dev *dev)
271{ 273{
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
1126{ 1128{
1127 return to_pci_dev(desc->dev); 1129 return to_pci_dev(desc->dev);
1128} 1130}
1131EXPORT_SYMBOL(msi_desc_to_pci_dev);
1129 1132
1130void *msi_desc_to_pci_sysdata(struct msi_desc *desc) 1133void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
1131{ 1134{
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
1285 domain->bus_token = DOMAIN_BUS_PCI_MSI; 1288 domain->bus_token = DOMAIN_BUS_PCI_MSI;
1286 return domain; 1289 return domain;
1287} 1290}
1291EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
1288 1292
1289/** 1293/**
1290 * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain 1294 * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a32ba753e413..d3f32d6417ef 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
9 9
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irqdomain.h>
12#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/msi.h>
13#include <linux/pci_hotplug.h> 15#include <linux/pci_hotplug.h>
14#include <linux/module.h> 16#include <linux/module.h>
15#include <linux/pci-aspm.h> 17#include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
689 .cleanup = pci_acpi_cleanup, 691 .cleanup = pci_acpi_cleanup,
690}; 692};
691 693
694
695static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
696
697/**
698 * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
699 * @fn: Callback matching a device to a fwnode that identifies a PCI
700 * MSI domain.
701 *
702 * This should be called by irqchip driver, which is the parent of
703 * the MSI domain to provide callback interface to query fwnode.
704 */
705void
706pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
707{
708 pci_msi_get_fwnode_cb = fn;
709}
710
711/**
712 * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
713 * @bus: The PCI host bridge bus.
714 *
715 * This function uses the callback function registered by
716 * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
717 * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
718 * This returns NULL on error or when the domain is not found.
719 */
720struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
721{
722 struct fwnode_handle *fwnode;
723
724 if (!pci_msi_get_fwnode_cb)
725 return NULL;
726
727 fwnode = pci_msi_get_fwnode_cb(&bus->dev);
728 if (!fwnode)
729 return NULL;
730
731 return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
732}
733
692static int __init acpi_pci_init(void) 734static int __init acpi_pci_init(void)
693{ 735{
694 int ret; 736 int ret;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984201e9..553a029e37f1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
672 * should be called from here. 672 * should be called from here.
673 */ 673 */
674 d = pci_host_bridge_of_msi_domain(bus); 674 d = pci_host_bridge_of_msi_domain(bus);
675 if (!d)
676 d = pci_host_bridge_acpi_msi_domain(bus);
675 677
676 return d; 678 return d;
677} 679}
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index ad16809c8596..cb30edbfe9fc 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -195,6 +195,7 @@ extern void disable_irq(unsigned int irq);
195extern void disable_percpu_irq(unsigned int irq); 195extern void disable_percpu_irq(unsigned int irq);
196extern void enable_irq(unsigned int irq); 196extern void enable_irq(unsigned int irq);
197extern void enable_percpu_irq(unsigned int irq, unsigned int type); 197extern void enable_percpu_irq(unsigned int irq, unsigned int type);
198extern bool irq_percpu_is_enabled(unsigned int irq);
198extern void irq_wake_thread(unsigned int irq, void *dev_id); 199extern void irq_wake_thread(unsigned int irq, void *dev_id);
199 200
200/* The following three functions are for the core kernel use only. */ 201/* The following three functions are for the core kernel use only. */
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index bae69e5d693c..9c940263ca23 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -103,10 +103,21 @@ struct device_node;
103void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 103void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
104int gic_cpu_if_down(unsigned int gic_nr); 104int gic_cpu_if_down(unsigned int gic_nr);
105 105
106/*
107 * Subdrivers that need some preparatory work can initialize their
108 * chips and call this to register their GICs.
109 */
110int gic_of_init(struct device_node *node, struct device_node *parent);
111
112/*
113 * Legacy platforms not converted to DT yet must use this to init
114 * their GIC
115 */
106void gic_init(unsigned int nr, int start, 116void gic_init(unsigned int nr, int start,
107 void __iomem *dist , void __iomem *cpu); 117 void __iomem *dist , void __iomem *cpu);
108 118
109int gicv2m_of_init(struct device_node *node, struct irq_domain *parent); 119int gicv2m_init(struct fwnode_handle *parent_handle,
120 struct irq_domain *parent);
110 121
111void gic_send_sgi(unsigned int cpu_id, unsigned int irq); 122void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
112int gic_get_cpu_id(unsigned int cpu); 123int gic_get_cpu_id(unsigned int cpu);
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index a587a33363c7..dcca77c4b9d2 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -1,6 +1,8 @@
1#ifndef _LINUX_IRQDESC_H 1#ifndef _LINUX_IRQDESC_H
2#define _LINUX_IRQDESC_H 2#define _LINUX_IRQDESC_H
3 3
4#include <linux/rcupdate.h>
5
4/* 6/*
5 * Core internal functions to deal with irq descriptors 7 * Core internal functions to deal with irq descriptors
6 */ 8 */
@@ -40,6 +42,7 @@ struct pt_regs;
40 * IRQF_NO_SUSPEND set 42 * IRQF_NO_SUSPEND set
41 * @force_resume_depth: number of irqactions on a irq descriptor with 43 * @force_resume_depth: number of irqactions on a irq descriptor with
42 * IRQF_FORCE_RESUME set 44 * IRQF_FORCE_RESUME set
45 * @rcu: rcu head for delayed free
43 * @dir: /proc/irq/ procfs entry 46 * @dir: /proc/irq/ procfs entry
44 * @name: flow handler name for /proc/interrupts output 47 * @name: flow handler name for /proc/interrupts output
45 */ 48 */
@@ -82,6 +85,9 @@ struct irq_desc {
82#ifdef CONFIG_PROC_FS 85#ifdef CONFIG_PROC_FS
83 struct proc_dir_entry *dir; 86 struct proc_dir_entry *dir;
84#endif 87#endif
88#ifdef CONFIG_SPARSE_IRQ
89 struct rcu_head rcu;
90#endif
85 int parent_irq; 91 int parent_irq;
86 struct module *owner; 92 struct module *owner;
87 const char *name; 93 const char *name;
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5bef28c..f64622ad02c1 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -211,6 +211,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
211 return node ? &node->fwnode : NULL; 211 return node ? &node->fwnode : NULL;
212} 212}
213 213
214static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
215{
216 return fwnode && fwnode->type == FWNODE_IRQCHIP;
217}
218
214static inline struct irq_domain *irq_find_matching_host(struct device_node *node, 219static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
215 enum irq_domain_bus_token bus_token) 220 enum irq_domain_bus_token bus_token)
216{ 221{
@@ -367,6 +372,9 @@ static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
367 return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false); 372 return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false);
368} 373}
369 374
375extern int irq_domain_alloc_irqs_recursive(struct irq_domain *domain,
376 unsigned int irq_base,
377 unsigned int nr_irqs, void *arg);
370extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, 378extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
371 unsigned int virq, 379 unsigned int virq,
372 irq_hw_number_t hwirq, 380 irq_hw_number_t hwirq,
@@ -410,6 +418,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
410static inline void irq_dispose_mapping(unsigned int virq) { } 418static inline void irq_dispose_mapping(unsigned int virq) { }
411static inline void irq_domain_activate_irq(struct irq_data *data) { } 419static inline void irq_domain_activate_irq(struct irq_data *data) { }
412static inline void irq_domain_deactivate_irq(struct irq_data *data) { } 420static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
421static inline struct irq_domain *irq_find_matching_fwnode(
422 struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
423{
424 return NULL;
425}
413#endif /* !CONFIG_IRQ_DOMAIN */ 426#endif /* !CONFIG_IRQ_DOMAIN */
414 427
415#endif /* _LINUX_IRQDOMAIN_H */ 428#endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/msi.h b/include/linux/msi.h
index f71a25e5fd25..1c6342ab8c0e 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -174,6 +174,7 @@ struct msi_controller {
174#include <asm/msi.h> 174#include <asm/msi.h>
175 175
176struct irq_domain; 176struct irq_domain;
177struct irq_domain_ops;
177struct irq_chip; 178struct irq_chip;
178struct device_node; 179struct device_node;
179struct fwnode_handle; 180struct fwnode_handle;
@@ -279,6 +280,23 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
279int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, 280int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
280 irq_write_msi_msg_t write_msi_msg); 281 irq_write_msi_msg_t write_msi_msg);
281void platform_msi_domain_free_irqs(struct device *dev); 282void platform_msi_domain_free_irqs(struct device *dev);
283
284/* When an MSI domain is used as an intermediate domain */
285int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
286 int nvec, msi_alloc_info_t *args);
287int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
288 int virq, int nvec, msi_alloc_info_t *args);
289struct irq_domain *
290platform_msi_create_device_domain(struct device *dev,
291 unsigned int nvec,
292 irq_write_msi_msg_t write_msi_msg,
293 const struct irq_domain_ops *ops,
294 void *host_data);
295int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
296 unsigned int nr_irqs);
297void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
298 unsigned int nvec);
299void *platform_msi_get_host_data(struct irq_domain *domain);
282#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */ 300#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
283 301
284#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN 302#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aae88fd..d86378c226fb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1946,6 +1946,16 @@ static inline struct irq_domain *
1946pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } 1946pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
1947#endif /* CONFIG_OF */ 1947#endif /* CONFIG_OF */
1948 1948
1949#ifdef CONFIG_ACPI
1950struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
1951
1952void
1953pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
1954#else
1955static inline struct irq_domain *
1956pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
1957#endif
1958
1949#ifdef CONFIG_EEH 1959#ifdef CONFIG_EEH
1950static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) 1960static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
1951{ 1961{
diff --git a/include/linux/platform_data/irq-renesas-intc-irqpin.h b/include/linux/platform_data/irq-renesas-intc-irqpin.h
deleted file mode 100644
index e4cb911066a6..000000000000
--- a/include/linux/platform_data/irq-renesas-intc-irqpin.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Renesas INTC External IRQ Pin Driver
3 *
4 * Copyright (C) 2013 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef __IRQ_RENESAS_INTC_IRQPIN_H__
21#define __IRQ_RENESAS_INTC_IRQPIN_H__
22
23struct renesas_intc_irqpin_config {
24 unsigned int sense_bitfield_width;
25 unsigned int irq_base;
26 bool control_parent;
27};
28
29#endif /* __IRQ_RENESAS_INTC_IRQPIN_H__ */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 15206453b12a..5797909f4e5b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -338,7 +338,6 @@ void handle_nested_irq(unsigned int irq)
338 raw_spin_lock_irq(&desc->lock); 338 raw_spin_lock_irq(&desc->lock);
339 339
340 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); 340 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
341 kstat_incr_irqs_this_cpu(desc);
342 341
343 action = desc->action; 342 action = desc->action;
344 if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) { 343 if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
@@ -346,6 +345,7 @@ void handle_nested_irq(unsigned int irq)
346 goto out_unlock; 345 goto out_unlock;
347 } 346 }
348 347
348 kstat_incr_irqs_this_cpu(desc);
349 irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); 349 irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
350 raw_spin_unlock_irq(&desc->lock); 350 raw_spin_unlock_irq(&desc->lock);
351 351
@@ -412,13 +412,13 @@ void handle_simple_irq(struct irq_desc *desc)
412 goto out_unlock; 412 goto out_unlock;
413 413
414 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); 414 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
415 kstat_incr_irqs_this_cpu(desc);
416 415
417 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { 416 if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
418 desc->istate |= IRQS_PENDING; 417 desc->istate |= IRQS_PENDING;
419 goto out_unlock; 418 goto out_unlock;
420 } 419 }
421 420
421 kstat_incr_irqs_this_cpu(desc);
422 handle_irq_event(desc); 422 handle_irq_event(desc);
423 423
424out_unlock: 424out_unlock:
@@ -462,7 +462,6 @@ void handle_level_irq(struct irq_desc *desc)
462 goto out_unlock; 462 goto out_unlock;
463 463
464 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); 464 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
465 kstat_incr_irqs_this_cpu(desc);
466 465
467 /* 466 /*
468 * If its disabled or no action available 467 * If its disabled or no action available
@@ -473,6 +472,7 @@ void handle_level_irq(struct irq_desc *desc)
473 goto out_unlock; 472 goto out_unlock;
474 } 473 }
475 474
475 kstat_incr_irqs_this_cpu(desc);
476 handle_irq_event(desc); 476 handle_irq_event(desc);
477 477
478 cond_unmask_irq(desc); 478 cond_unmask_irq(desc);
@@ -532,7 +532,6 @@ void handle_fasteoi_irq(struct irq_desc *desc)
532 goto out; 532 goto out;
533 533
534 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); 534 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
535 kstat_incr_irqs_this_cpu(desc);
536 535
537 /* 536 /*
538 * If its disabled or no action available 537 * If its disabled or no action available
@@ -544,6 +543,7 @@ void handle_fasteoi_irq(struct irq_desc *desc)
544 goto out; 543 goto out;
545 } 544 }
546 545
546 kstat_incr_irqs_this_cpu(desc);
547 if (desc->istate & IRQS_ONESHOT) 547 if (desc->istate & IRQS_ONESHOT)
548 mask_irq(desc); 548 mask_irq(desc);
549 549
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
950 data = data->parent_data; 950 data = data->parent_data;
951 data->chip->irq_ack(data); 951 data->chip->irq_ack(data);
952} 952}
953EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
953 954
954/** 955/**
955 * irq_chip_mask_parent - Mask the parent interrupt 956 * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 239e2ae2c947..0409da0bcc33 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -159,6 +159,7 @@ static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
159 159
160 raw_spin_lock_init(&desc->lock); 160 raw_spin_lock_init(&desc->lock);
161 lockdep_set_class(&desc->lock, &irq_desc_lock_class); 161 lockdep_set_class(&desc->lock, &irq_desc_lock_class);
162 init_rcu_head(&desc->rcu);
162 163
163 desc_set_defaults(irq, desc, node, owner); 164 desc_set_defaults(irq, desc, node, owner);
164 165
@@ -171,6 +172,15 @@ err_desc:
171 return NULL; 172 return NULL;
172} 173}
173 174
175static void delayed_free_desc(struct rcu_head *rhp)
176{
177 struct irq_desc *desc = container_of(rhp, struct irq_desc, rcu);
178
179 free_masks(desc);
180 free_percpu(desc->kstat_irqs);
181 kfree(desc);
182}
183
174static void free_desc(unsigned int irq) 184static void free_desc(unsigned int irq)
175{ 185{
176 struct irq_desc *desc = irq_to_desc(irq); 186 struct irq_desc *desc = irq_to_desc(irq);
@@ -187,9 +197,12 @@ static void free_desc(unsigned int irq)
187 delete_irq_desc(irq); 197 delete_irq_desc(irq);
188 mutex_unlock(&sparse_irq_lock); 198 mutex_unlock(&sparse_irq_lock);
189 199
190 free_masks(desc); 200 /*
191 free_percpu(desc->kstat_irqs); 201 * We free the descriptor, masks and stat fields via RCU. That
192 kfree(desc); 202 * allows demultiplex interrupts to do rcu based management of
203 * the child interrupts.
204 */
205 call_rcu(&desc->rcu, delayed_free_desc);
193} 206}
194 207
195static int alloc_descs(unsigned int start, unsigned int cnt, int node, 208static int alloc_descs(unsigned int start, unsigned int cnt, int node,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa9612ef7c..8cf95de1ab3f 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
60 fwid->fwnode.type = FWNODE_IRQCHIP; 60 fwid->fwnode.type = FWNODE_IRQCHIP;
61 return &fwid->fwnode; 61 return &fwid->fwnode;
62} 62}
63EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
63 64
64/** 65/**
65 * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle 66 * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -70,13 +71,14 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
70{ 71{
71 struct irqchip_fwid *fwid; 72 struct irqchip_fwid *fwid;
72 73
73 if (WARN_ON(fwnode->type != FWNODE_IRQCHIP)) 74 if (WARN_ON(!is_fwnode_irqchip(fwnode)))
74 return; 75 return;
75 76
76 fwid = container_of(fwnode, struct irqchip_fwid, fwnode); 77 fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
77 kfree(fwid->name); 78 kfree(fwid->name);
78 kfree(fwid); 79 kfree(fwid);
79} 80}
81EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
80 82
81/** 83/**
82 * __irq_domain_add() - Allocate a new irq_domain data structure 84 * __irq_domain_add() - Allocate a new irq_domain data structure
@@ -1013,6 +1015,7 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
1013 1015
1014 return NULL; 1016 return NULL;
1015} 1017}
1018EXPORT_SYMBOL_GPL(irq_domain_get_irq_data);
1016 1019
1017/** 1020/**
1018 * irq_domain_set_hwirq_and_chip - Set hwirq and irqchip of @virq at @domain 1021 * irq_domain_set_hwirq_and_chip - Set hwirq and irqchip of @virq at @domain
@@ -1125,9 +1128,9 @@ static void irq_domain_free_irqs_recursive(struct irq_domain *domain,
1125 } 1128 }
1126} 1129}
1127 1130
1128static int irq_domain_alloc_irqs_recursive(struct irq_domain *domain, 1131int irq_domain_alloc_irqs_recursive(struct irq_domain *domain,
1129 unsigned int irq_base, 1132 unsigned int irq_base,
1130 unsigned int nr_irqs, void *arg) 1133 unsigned int nr_irqs, void *arg)
1131{ 1134{
1132 int ret = 0; 1135 int ret = 0;
1133 struct irq_domain *parent = domain->parent; 1136 struct irq_domain *parent = domain->parent;
@@ -1343,6 +1346,7 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
1343 1346
1344 return (irq_data && irq_data->domain == domain) ? irq_data : NULL; 1347 return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
1345} 1348}
1349EXPORT_SYMBOL_GPL(irq_domain_get_irq_data);
1346 1350
1347/** 1351/**
1348 * irq_domain_set_info - Set the complete data for a @virq in @domain 1352 * irq_domain_set_info - Set the complete data for a @virq in @domain
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 6ead200370da..841187239adc 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1743,6 +1743,31 @@ out:
1743} 1743}
1744EXPORT_SYMBOL_GPL(enable_percpu_irq); 1744EXPORT_SYMBOL_GPL(enable_percpu_irq);
1745 1745
1746/**
1747 * irq_percpu_is_enabled - Check whether the per cpu irq is enabled
1748 * @irq: Linux irq number to check for
1749 *
1750 * Must be called from a non migratable context. Returns the enable
1751 * state of a per cpu interrupt on the current cpu.
1752 */
1753bool irq_percpu_is_enabled(unsigned int irq)
1754{
1755 unsigned int cpu = smp_processor_id();
1756 struct irq_desc *desc;
1757 unsigned long flags;
1758 bool is_enabled;
1759
1760 desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
1761 if (!desc)
1762 return false;
1763
1764 is_enabled = cpumask_test_cpu(cpu, desc->percpu_enabled);
1765 irq_put_desc_unlock(desc, flags);
1766
1767 return is_enabled;
1768}
1769EXPORT_SYMBOL_GPL(irq_percpu_is_enabled);
1770
1746void disable_percpu_irq(unsigned int irq) 1771void disable_percpu_irq(unsigned int irq)
1747{ 1772{
1748 unsigned int cpu = smp_processor_id(); 1773 unsigned int cpu = smp_processor_id();
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 6b0c0b74a2a1..15b249e7c673 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -252,6 +252,60 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
252 &msi_domain_ops, info); 252 &msi_domain_ops, info);
253} 253}
254 254
255int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
256 int nvec, msi_alloc_info_t *arg)
257{
258 struct msi_domain_info *info = domain->host_data;
259 struct msi_domain_ops *ops = info->ops;
260 int ret;
261
262 ret = ops->msi_check(domain, info, dev);
263 if (ret == 0)
264 ret = ops->msi_prepare(domain, dev, nvec, arg);
265
266 return ret;
267}
268
269int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
270 int virq, int nvec, msi_alloc_info_t *arg)
271{
272 struct msi_domain_info *info = domain->host_data;
273 struct msi_domain_ops *ops = info->ops;
274 struct msi_desc *desc;
275 int ret = 0;
276
277 for_each_msi_entry(desc, dev) {
278 /* Don't even try the multi-MSI brain damage. */
279 if (WARN_ON(!desc->irq || desc->nvec_used != 1)) {
280 ret = -EINVAL;
281 break;
282 }
283
284 if (!(desc->irq >= virq && desc->irq < (virq + nvec)))
285 continue;
286
287 ops->set_desc(arg, desc);
288 /* Assumes the domain mutex is held! */
289 ret = irq_domain_alloc_irqs_recursive(domain, virq, 1, arg);
290 if (ret)
291 break;
292
293 irq_set_msi_desc_off(virq, 0, desc);
294 }
295
296 if (ret) {
297 /* Mop up the damage */
298 for_each_msi_entry(desc, dev) {
299 if (!(desc->irq >= virq && desc->irq < (virq + nvec)))
300 continue;
301
302 irq_domain_free_irqs_common(domain, desc->irq, 1);
303 }
304 }
305
306 return ret;
307}
308
255/** 309/**
256 * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain 310 * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain
257 * @domain: The domain to allocate from 311 * @domain: The domain to allocate from
@@ -270,9 +324,7 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
270 struct msi_desc *desc; 324 struct msi_desc *desc;
271 int i, ret, virq = -1; 325 int i, ret, virq = -1;
272 326
273 ret = ops->msi_check(domain, info, dev); 327 ret = msi_domain_prepare_irqs(domain, dev, nvec, &arg);
274 if (ret == 0)
275 ret = ops->msi_prepare(domain, dev, nvec, &arg);
276 if (ret) 328 if (ret)
277 return ret; 329 return ret;
278 330