aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 22:42:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 22:42:56 -0400
commit407a2c720556e8e340e06f6a7174f5d6d80cf9ea (patch)
treeb78ba543dbef195909611448ca833348581b63a6
parent3a95398f54cbd664c749fe9f1bfc7e7dbace92d0 (diff)
parentf05218651be1ac6a6088e226bd7350fb6c154414 (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 departement delivers: - plug a potential race related to chained interrupt handlers - core updates which address the needs of the x86 irqdomain conversion - new irqchip callback to support affinity settings for VCPUs - the usual pile of updates to interrupt chip drivers - a few helper functions to allow further cleanups and simplifications I have a largish pile of coccinelle scripted/verified cleanups and simplifications pending on top of that, but I prefer to send that towards the end of the merge window when the arch/driver changes have hit your tree to avoid API change wreckage as far as possible" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (34 commits) genirq: Remove bogus restriction in irq_move_mask_irq() irqchip: atmel-aic5: Add sama5d2 support irq: spear-shirq: Fix race in installing chained IRQ handler irq: irq-keystone: Fix race in installing chained IRQ handler gpio: gpio-tegra: Fix race in installing chained IRQ handler gpio: gpio-mxs: Fix race in installing chained IRQ handler gpio: gpio-mxc: Fix race in installing chained IRQ handler ARM: gemini: Fix race in installing GPIO chained IRQ handler GPU: ipu: Fix race in installing IPU chained IRQ handler ARM: sa1100: convert SA11x0 related code to use new chained handler helper irq: Add irq_set_chained_handler_and_data() irqchip: exynos-combiner: Save IRQ enable set on suspend genirq: Introduce helper function irq_data_get_affinity_mask() genirq: Introduce helper function irq_data_get_node() genirq: Introduce struct irq_common_data to host shared irq data genirq: Prevent crash in irq_move_irq() genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain irqchip: gic: Simplify gic_configure_irq by using IRQCHIP_SET_TYPE_MASKED irqchip: renesas: intc-irqpin: Improve binding documentation genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip ...
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt39
-rw-r--r--arch/arm/common/sa1111.c7
-rw-r--r--arch/arm/mach-gemini/gpio.c4
-rw-r--r--arch/arm/mach-sa1100/neponset.c3
-rw-r--r--drivers/gpio/gpio-mxc.c13
-rw-r--r--drivers/gpio/gpio-mxs.c4
-rw-r--r--drivers/gpio/gpio-tegra.c4
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c13
-rw-r--r--drivers/irqchip/Kconfig1
-rw-r--r--drivers/irqchip/exynos-combiner.c66
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c2
-rw-r--r--drivers/irqchip/irq-atmel-aic5.c9
-rw-r--r--drivers/irqchip/irq-bcm2835.c2
-rw-r--r--drivers/irqchip/irq-gic-common.c17
-rw-r--r--drivers/irqchip/irq-gic-v3.c1
-rw-r--r--drivers/irqchip/irq-gic.c1
-rw-r--r--drivers/irqchip/irq-hip04.c1
-rw-r--r--drivers/irqchip/irq-keystone.c5
-rw-r--r--drivers/irqchip/irq-mips-gic.c2
-rw-r--r--drivers/irqchip/irq-mtk-sysirq.c4
-rw-r--r--drivers/irqchip/irq-mxs.c2
-rw-r--r--drivers/irqchip/irq-nvic.c28
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c2
-rw-r--r--drivers/irqchip/irq-renesas-irqc.c19
-rw-r--r--drivers/irqchip/irq-s3c24xx.c4
-rw-r--r--drivers/irqchip/irq-sun4i.c2
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c2
-rw-r--r--drivers/irqchip/irq-vf610-mscm-ir.c28
-rw-r--r--drivers/irqchip/irq-vic.c2
-rw-r--r--drivers/irqchip/irq-vt8500.c2
-rw-r--r--drivers/irqchip/spear-shirq.c3
-rw-r--r--drivers/mfd/ucb1x00-core.c3
-rw-r--r--include/linux/irq.h82
-rw-r--r--include/linux/irqdesc.h3
-rw-r--r--include/linux/irqdomain.h8
-rw-r--r--include/linux/platform_data/irq-renesas-irqc.h27
-rw-r--r--kernel/irq/chip.c73
-rw-r--r--kernel/irq/devres.c4
-rw-r--r--kernel/irq/dummychip.c1
-rw-r--r--kernel/irq/generic-chip.c5
-rw-r--r--kernel/irq/internals.h15
-rw-r--r--kernel/irq/irqdesc.c13
-rw-r--r--kernel/irq/irqdomain.c25
-rw-r--r--kernel/irq/manage.c2
-rw-r--r--kernel/irq/migration.c6
-rw-r--r--kernel/irq/msi.c2
-rw-r--r--kernel/irq/pm.c4
-rw-r--r--kernel/irq/proc.c2
49 files changed, 378 insertions, 191 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
index f292917fa00d..0e9f09a6a2fe 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
@@ -2,7 +2,7 @@
2 2
3Required properties: 3Required properties:
4- compatible: Should be "atmel,<chip>-aic" 4- compatible: Should be "atmel,<chip>-aic"
5 <chip> can be "at91rm9200", "sama5d3" or "sama5d4" 5 <chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4"
6- interrupt-controller: Identifies the node as an interrupt controller. 6- interrupt-controller: Identifies the node as an interrupt controller.
7- interrupt-parent: For single AIC system, it is an empty property. 7- interrupt-parent: For single AIC system, it is an empty property.
8- #interrupt-cells: The number of cells to define the interrupts. It should be 3. 8- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
index 4f7946ae8adc..772c550d3b4b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
@@ -13,9 +13,12 @@ Required properties:
13- reg: Base address and length of each register bank used by the external 13- reg: Base address and length of each register bank used by the external
14 IRQ pins driven by the interrupt controller hardware module. The base 14 IRQ pins driven by the interrupt controller hardware module. The base
15 addresses, length and number of required register banks varies with soctype. 15 addresses, length and number of required register banks varies with soctype.
16 16- interrupt-controller: Identifies the node as an interrupt controller.
17- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in 17- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
18 interrupts.txt in this directory 18 interrupts.txt in this directory.
19- interrupts: Must contain a list of interrupt specifiers. For each interrupt
20 provided by this irqpin controller instance, there must be one entry,
21 referring to the corresponding parent interrupt.
19 22
20Optional properties: 23Optional properties:
21 24
@@ -25,3 +28,35 @@ Optional properties:
25 if different from the default 4 bits 28 if different from the default 4 bits
26- control-parent: disable and enable interrupts on the parent interrupt 29- control-parent: disable and enable interrupts on the parent interrupt
27 controller, needed for some broken implementations 30 controller, needed for some broken implementations
31- clocks: Must contain a reference to the functional clock. This property is
32 mandatory if the hardware implements a controllable functional clock for
33 the irqpin controller instance.
34- power-domains: Must contain a reference to the power domain. This property is
35 mandatory if the irqpin controller instance is part of a controllable power
36 domain.
37
38
39Example
40-------
41
42 irqpin1: interrupt-controller@e6900004 {
43 compatible = "renesas,intc-irqpin-r8a7740",
44 "renesas,intc-irqpin";
45 #interrupt-cells = <2>;
46 interrupt-controller;
47 reg = <0xe6900004 4>,
48 <0xe6900014 4>,
49 <0xe6900024 1>,
50 <0xe6900044 1>,
51 <0xe6900064 1>;
52 interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
53 0 149 IRQ_TYPE_LEVEL_HIGH
54 0 149 IRQ_TYPE_LEVEL_HIGH
55 0 149 IRQ_TYPE_LEVEL_HIGH
56 0 149 IRQ_TYPE_LEVEL_HIGH
57 0 149 IRQ_TYPE_LEVEL_HIGH
58 0 149 IRQ_TYPE_LEVEL_HIGH
59 0 149 IRQ_TYPE_LEVEL_HIGH>;
60 clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
61 power-domains = <&pd_a4s>;
62 };
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 5cc779c8e9c6..93ee70dbbdd3 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -501,8 +501,8 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
501 * Register SA1111 interrupt 501 * Register SA1111 interrupt
502 */ 502 */
503 irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); 503 irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
504 irq_set_handler_data(sachip->irq, sachip); 504 irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler,
505 irq_set_chained_handler(sachip->irq, sa1111_irq_handler); 505 sachip);
506 506
507 dev_info(sachip->dev, "Providing IRQ%u-%u\n", 507 dev_info(sachip->dev, "Providing IRQ%u-%u\n",
508 sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1); 508 sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
@@ -836,8 +836,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
836 clk_unprepare(sachip->clk); 836 clk_unprepare(sachip->clk);
837 837
838 if (sachip->irq != NO_IRQ) { 838 if (sachip->irq != NO_IRQ) {
839 irq_set_chained_handler(sachip->irq, NULL); 839 irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
840 irq_set_handler_data(sachip->irq, NULL);
841 irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); 840 irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
842 841
843 release_mem_region(sachip->phys + SA1111_INTC, 512); 842 release_mem_region(sachip->phys + SA1111_INTC, 512);
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index f8cb5710d6ee..3292f2e6ed6f 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -223,8 +223,8 @@ void __init gemini_gpio_init(void)
223 set_irq_flags(j, IRQF_VALID); 223 set_irq_flags(j, IRQF_VALID);
224 } 224 }
225 225
226 irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler); 226 irq_set_chained_handler_and_data(IRQ_GPIO(i), gpio_irq_handler,
227 irq_set_handler_data(IRQ_GPIO(i), (void *)i); 227 (void *)i);
228 } 228 }
229 229
230 BUG_ON(gpiochip_add(&gemini_gpio_chip)); 230 BUG_ON(gpiochip_add(&gemini_gpio_chip));
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index af868d258e66..99d9a3b1bf34 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -327,8 +327,7 @@ static int neponset_probe(struct platform_device *dev)
327 irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip); 327 irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
328 328
329 irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); 329 irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
330 irq_set_handler_data(irq, d); 330 irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
331 irq_set_chained_handler(irq, neponset_irq_handler);
332 331
333 /* 332 /*
334 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately 333 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 9f7446a7ac64..e4f42c95c320 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -437,14 +437,13 @@ static int mxc_gpio_probe(struct platform_device *pdev)
437 irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); 437 irq_set_chained_handler(port->irq, mx2_gpio_irq_handler);
438 } else { 438 } else {
439 /* setup one handler for each entry */ 439 /* setup one handler for each entry */
440 irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); 440 irq_set_chained_handler_and_data(port->irq,
441 irq_set_handler_data(port->irq, port); 441 mx3_gpio_irq_handler, port);
442 if (port->irq_high > 0) { 442 if (port->irq_high > 0)
443 /* setup handler for GPIO 16 to 31 */ 443 /* setup handler for GPIO 16 to 31 */
444 irq_set_chained_handler(port->irq_high, 444 irq_set_chained_handler_and_data(port->irq_high,
445 mx3_gpio_irq_handler); 445 mx3_gpio_irq_handler,
446 irq_set_handler_data(port->irq_high, port); 446 port);
447 }
448 } 447 }
449 448
450 err = bgpio_init(&port->bgc, &pdev->dev, 4, 449 err = bgpio_init(&port->bgc, &pdev->dev, 4,
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 84cbda6acdda..eac872748ee7 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -320,8 +320,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
320 mxs_gpio_init_gc(port, irq_base); 320 mxs_gpio_init_gc(port, irq_base);
321 321
322 /* setup one handler for each entry */ 322 /* setup one handler for each entry */
323 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); 323 irq_set_chained_handler_and_data(port->irq, mxs_gpio_irq_handler,
324 irq_set_handler_data(port->irq, port); 324 port);
325 325
326 err = bgpio_init(&port->bgc, &pdev->dev, 4, 326 err = bgpio_init(&port->bgc, &pdev->dev, 4,
327 port->base + PINCTRL_DIN(port), 327 port->base + PINCTRL_DIN(port),
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 1741981d53c8..56dcc8ed98de 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -515,8 +515,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
515 for (i = 0; i < tegra_gpio_bank_count; i++) { 515 for (i = 0; i < tegra_gpio_bank_count; i++) {
516 bank = &tegra_gpio_banks[i]; 516 bank = &tegra_gpio_banks[i];
517 517
518 irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler); 518 irq_set_chained_handler_and_data(bank->irq,
519 irq_set_handler_data(bank->irq, bank); 519 tegra_gpio_irq_handler, bank);
520 520
521 for (j = 0; j < 4; j++) 521 for (j = 0; j < 4; j++)
522 spin_lock_init(&bank->lvl_lock[j]); 522 spin_lock_init(&bank->lvl_lock[j]);
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 67bab5c36056..6d2f39d36e44 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1119,10 +1119,9 @@ static int ipu_irq_init(struct ipu_soc *ipu)
1119 ct->regs.mask = IPU_INT_CTRL(i / 32); 1119 ct->regs.mask = IPU_INT_CTRL(i / 32);
1120 } 1120 }
1121 1121
1122 irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler); 1122 irq_set_chained_handler_and_data(ipu->irq_sync, ipu_irq_handler, ipu);
1123 irq_set_handler_data(ipu->irq_sync, ipu); 1123 irq_set_chained_handler_and_data(ipu->irq_err, ipu_err_irq_handler,
1124 irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler); 1124 ipu);
1125 irq_set_handler_data(ipu->irq_err, ipu);
1126 1125
1127 return 0; 1126 return 0;
1128} 1127}
@@ -1131,10 +1130,8 @@ static void ipu_irq_exit(struct ipu_soc *ipu)
1131{ 1130{
1132 int i, irq; 1131 int i, irq;
1133 1132
1134 irq_set_chained_handler(ipu->irq_err, NULL); 1133 irq_set_chained_handler_and_data(ipu->irq_err, NULL, NULL);
1135 irq_set_handler_data(ipu->irq_err, NULL); 1134 irq_set_chained_handler_and_data(ipu->irq_sync, NULL, NULL);
1136 irq_set_chained_handler(ipu->irq_sync, NULL);
1137 irq_set_handler_data(ipu->irq_sync, NULL);
1138 1135
1139 /* TODO: remove irq_domain_generic_chips */ 1136 /* TODO: remove irq_domain_generic_chips */
1140 1137
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 6de62a96e79c..99b9a9792975 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -30,6 +30,7 @@ config ARM_GIC_V3_ITS
30config ARM_NVIC 30config ARM_NVIC
31 bool 31 bool
32 select IRQ_DOMAIN 32 select IRQ_DOMAIN
33 select IRQ_DOMAIN_HIERARCHY
33 select GENERIC_IRQ_CHIP 34 select GENERIC_IRQ_CHIP
34 35
35config ARM_VIC 36config ARM_VIC
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 5945223b73fa..5c82e3bdafdf 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/syscore_ops.h>
16#include <linux/irqdomain.h> 17#include <linux/irqdomain.h>
17#include <linux/irqchip/chained_irq.h> 18#include <linux/irqchip/chained_irq.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -34,9 +35,14 @@ struct combiner_chip_data {
34 unsigned int irq_mask; 35 unsigned int irq_mask;
35 void __iomem *base; 36 void __iomem *base;
36 unsigned int parent_irq; 37 unsigned int parent_irq;
38#ifdef CONFIG_PM
39 u32 pm_save;
40#endif
37}; 41};
38 42
43static struct combiner_chip_data *combiner_data;
39static struct irq_domain *combiner_irq_domain; 44static struct irq_domain *combiner_irq_domain;
45static unsigned int max_nr = 20;
40 46
41static inline void __iomem *combiner_base(struct irq_data *data) 47static inline void __iomem *combiner_base(struct irq_data *data)
42{ 48{
@@ -164,18 +170,16 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
164 return 0; 170 return 0;
165} 171}
166 172
167static struct irq_domain_ops combiner_irq_domain_ops = { 173static const struct irq_domain_ops combiner_irq_domain_ops = {
168 .xlate = combiner_irq_domain_xlate, 174 .xlate = combiner_irq_domain_xlate,
169 .map = combiner_irq_domain_map, 175 .map = combiner_irq_domain_map,
170}; 176};
171 177
172static void __init combiner_init(void __iomem *combiner_base, 178static void __init combiner_init(void __iomem *combiner_base,
173 struct device_node *np, 179 struct device_node *np)
174 unsigned int max_nr)
175{ 180{
176 int i, irq; 181 int i, irq;
177 unsigned int nr_irq; 182 unsigned int nr_irq;
178 struct combiner_chip_data *combiner_data;
179 183
180 nr_irq = max_nr * IRQ_IN_COMBINER; 184 nr_irq = max_nr * IRQ_IN_COMBINER;
181 185
@@ -201,11 +205,59 @@ static void __init combiner_init(void __iomem *combiner_base,
201 } 205 }
202} 206}
203 207
208#ifdef CONFIG_PM
209
210/**
211 * combiner_suspend - save interrupt combiner state before suspend
212 *
213 * Save the interrupt enable set register for all combiner groups since
214 * the state is lost when the system enters into a sleep state.
215 *
216 */
217static int combiner_suspend(void)
218{
219 int i;
220
221 for (i = 0; i < max_nr; i++)
222 combiner_data[i].pm_save =
223 __raw_readl(combiner_data[i].base + COMBINER_ENABLE_SET);
224
225 return 0;
226}
227
228/**
229 * combiner_resume - restore interrupt combiner state after resume
230 *
231 * Restore the interrupt enable set register for all combiner groups since
232 * the state is lost when the system enters into a sleep state on suspend.
233 *
234 */
235static void combiner_resume(void)
236{
237 int i;
238
239 for (i = 0; i < max_nr; i++) {
240 __raw_writel(combiner_data[i].irq_mask,
241 combiner_data[i].base + COMBINER_ENABLE_CLEAR);
242 __raw_writel(combiner_data[i].pm_save,
243 combiner_data[i].base + COMBINER_ENABLE_SET);
244 }
245}
246
247#else
248#define combiner_suspend NULL
249#define combiner_resume NULL
250#endif
251
252static struct syscore_ops combiner_syscore_ops = {
253 .suspend = combiner_suspend,
254 .resume = combiner_resume,
255};
256
204static int __init combiner_of_init(struct device_node *np, 257static int __init combiner_of_init(struct device_node *np,
205 struct device_node *parent) 258 struct device_node *parent)
206{ 259{
207 void __iomem *combiner_base; 260 void __iomem *combiner_base;
208 unsigned int max_nr = 20;
209 261
210 combiner_base = of_iomap(np, 0); 262 combiner_base = of_iomap(np, 0);
211 if (!combiner_base) { 263 if (!combiner_base) {
@@ -219,7 +271,9 @@ static int __init combiner_of_init(struct device_node *np,
219 __func__, max_nr); 271 __func__, max_nr);
220 } 272 }
221 273
222 combiner_init(combiner_base, np, max_nr); 274 combiner_init(combiner_base, np);
275
276 register_syscore_ops(&combiner_syscore_ops);
223 277
224 return 0; 278 return 0;
225} 279}
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index daccc8bdbb42..0d3b0fe2f175 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -409,7 +409,7 @@ static struct notifier_block mpic_cascaded_cpu_notifier = {
409}; 409};
410#endif /* CONFIG_SMP */ 410#endif /* CONFIG_SMP */
411 411
412static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 412static const struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
413 .map = armada_370_xp_mpic_irq_map, 413 .map = armada_370_xp_mpic_irq_map,
414 .xlate = irq_domain_xlate_onecell, 414 .xlate = irq_domain_xlate_onecell,
415}; 415};
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
index a2e8c3f876cb..459bf4429d36 100644
--- a/drivers/irqchip/irq-atmel-aic5.c
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -339,6 +339,15 @@ static int __init aic5_of_init(struct device_node *node,
339 return 0; 339 return 0;
340} 340}
341 341
342#define NR_SAMA5D2_IRQS 77
343
344static int __init sama5d2_aic5_of_init(struct device_node *node,
345 struct device_node *parent)
346{
347 return aic5_of_init(node, parent, NR_SAMA5D2_IRQS);
348}
349IRQCHIP_DECLARE(sama5d2_aic5, "atmel,sama5d2-aic", sama5d2_aic5_of_init);
350
342#define NR_SAMA5D3_IRQS 48 351#define NR_SAMA5D3_IRQS 48
343 352
344static int __init sama5d3_aic5_of_init(struct device_node *node, 353static int __init sama5d3_aic5_of_init(struct device_node *node,
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index 5916d6cdafa1..e68c3b60a681 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -135,7 +135,7 @@ static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
135 return 0; 135 return 0;
136} 136}
137 137
138static struct irq_domain_ops armctrl_ops = { 138static const struct irq_domain_ops armctrl_ops = {
139 .xlate = armctrl_xlate 139 .xlate = armctrl_xlate
140}; 140};
141 141
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index ad96ebb0c7ab..9448e391cb71 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -24,11 +24,8 @@
24int gic_configure_irq(unsigned int irq, unsigned int type, 24int gic_configure_irq(unsigned int irq, unsigned int type,
25 void __iomem *base, void (*sync_access)(void)) 25 void __iomem *base, void (*sync_access)(void))
26{ 26{
27 u32 enablemask = 1 << (irq % 32);
28 u32 enableoff = (irq / 32) * 4;
29 u32 confmask = 0x2 << ((irq % 16) * 2); 27 u32 confmask = 0x2 << ((irq % 16) * 2);
30 u32 confoff = (irq / 16) * 4; 28 u32 confoff = (irq / 16) * 4;
31 bool enabled = false;
32 u32 val, oldval; 29 u32 val, oldval;
33 int ret = 0; 30 int ret = 0;
34 31
@@ -43,17 +40,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
43 val |= confmask; 40 val |= confmask;
44 41
45 /* 42 /*
46 * As recommended by the spec, disable the interrupt before changing
47 * the configuration
48 */
49 if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
50 writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
51 if (sync_access)
52 sync_access();
53 enabled = true;
54 }
55
56 /*
57 * Write back the new configuration, and possibly re-enable 43 * Write back the new configuration, and possibly re-enable
58 * the interrupt. If we tried to write a new configuration and failed, 44 * the interrupt. If we tried to write a new configuration and failed,
59 * return an error. 45 * return an error.
@@ -62,9 +48,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
62 if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval) 48 if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
63 ret = -EINVAL; 49 ret = -EINVAL;
64 50
65 if (enabled)
66 writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
67
68 if (sync_access) 51 if (sync_access)
69 sync_access(); 52 sync_access();
70 53
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 49875adb6b44..c52f7ba205b4 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -658,6 +658,7 @@ static struct irq_chip gic_chip = {
658 .irq_set_affinity = gic_set_affinity, 658 .irq_set_affinity = gic_set_affinity,
659 .irq_get_irqchip_state = gic_irq_get_irqchip_state, 659 .irq_get_irqchip_state = gic_irq_get_irqchip_state,
660 .irq_set_irqchip_state = gic_irq_set_irqchip_state, 660 .irq_set_irqchip_state = gic_irq_set_irqchip_state,
661 .flags = IRQCHIP_SET_TYPE_MASKED,
661}; 662};
662 663
663#define GIC_ID_NR (1U << gic_data.rdists.id_bits) 664#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 01999d74bd3a..8d7e1c8b6d56 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -324,6 +324,7 @@ static struct irq_chip gic_chip = {
324#endif 324#endif
325 .irq_get_irqchip_state = gic_irq_get_irqchip_state, 325 .irq_get_irqchip_state = gic_irq_get_irqchip_state,
326 .irq_set_irqchip_state = gic_irq_set_irqchip_state, 326 .irq_set_irqchip_state = gic_irq_set_irqchip_state,
327 .flags = IRQCHIP_SET_TYPE_MASKED,
327}; 328};
328 329
329void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) 330void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 7d6ffb5de84f..0cae45d10695 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -202,6 +202,7 @@ static struct irq_chip hip04_irq_chip = {
202#ifdef CONFIG_SMP 202#ifdef CONFIG_SMP
203 .irq_set_affinity = hip04_irq_set_affinity, 203 .irq_set_affinity = hip04_irq_set_affinity,
204#endif 204#endif
205 .flags = IRQCHIP_SET_TYPE_MASKED,
205}; 206};
206 207
207static u16 hip04_get_cpumask(struct hip04_irq_data *intc) 208static u16 hip04_get_cpumask(struct hip04_irq_data *intc)
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
index 78e8b3ce5252..81e3cf5b9a1f 100644
--- a/drivers/irqchip/irq-keystone.c
+++ b/drivers/irqchip/irq-keystone.c
@@ -131,7 +131,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
131 return 0; 131 return 0;
132} 132}
133 133
134static struct irq_domain_ops keystone_irq_ops = { 134static const struct irq_domain_ops keystone_irq_ops = {
135 .map = keystone_irq_map, 135 .map = keystone_irq_map,
136 .xlate = irq_domain_xlate_onecell, 136 .xlate = irq_domain_xlate_onecell,
137}; 137};
@@ -184,8 +184,7 @@ static int keystone_irq_probe(struct platform_device *pdev)
184 184
185 platform_set_drvdata(pdev, kirq); 185 platform_set_drvdata(pdev, kirq);
186 186
187 irq_set_chained_handler(kirq->irq, keystone_irq_handler); 187 irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq);
188 irq_set_handler_data(kirq->irq, kirq);
189 188
190 /* clear all source bits */ 189 /* clear all source bits */
191 keystone_irq_writel(kirq, ~0x0); 190 keystone_irq_writel(kirq, ~0x0);
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 269c2354c431..4400edd1a6c7 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -746,7 +746,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
746 return 0; 746 return 0;
747} 747}
748 748
749static struct irq_domain_ops gic_irq_domain_ops = { 749static const struct irq_domain_ops gic_irq_domain_ops = {
750 .map = gic_irq_domain_map, 750 .map = gic_irq_domain_map,
751 .xlate = gic_irq_domain_xlate, 751 .xlate = gic_irq_domain_xlate,
752}; 752};
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index eaf0a710e98a..15c13039bba2 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -111,7 +111,7 @@ static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
111 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); 111 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
112} 112}
113 113
114static struct irq_domain_ops sysirq_domain_ops = { 114static const struct irq_domain_ops sysirq_domain_ops = {
115 .xlate = mtk_sysirq_domain_xlate, 115 .xlate = mtk_sysirq_domain_xlate,
116 .alloc = mtk_sysirq_domain_alloc, 116 .alloc = mtk_sysirq_domain_alloc,
117 .free = irq_domain_free_irqs_common, 117 .free = irq_domain_free_irqs_common,
@@ -144,7 +144,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
144 chip_data->intpol_base = ioremap(res.start, size); 144 chip_data->intpol_base = ioremap(res.start, size);
145 if (!chip_data->intpol_base) { 145 if (!chip_data->intpol_base) {
146 pr_err("mtk_sysirq: unable to map sysirq register\n"); 146 pr_err("mtk_sysirq: unable to map sysirq register\n");
147 ret = PTR_ERR(chip_data->intpol_base); 147 ret = -ENXIO;
148 goto out_free; 148 goto out_free;
149 } 149 }
150 150
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index e4acf1e3f8e3..04bf97b289cf 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -90,7 +90,7 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
90 return 0; 90 return 0;
91} 91}
92 92
93static struct irq_domain_ops icoll_irq_domain_ops = { 93static const struct irq_domain_ops icoll_irq_domain_ops = {
94 .map = icoll_irq_domain_map, 94 .map = icoll_irq_domain_map,
95 .xlate = irq_domain_xlate_onecell, 95 .xlate = irq_domain_xlate_onecell,
96}; 96};
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index 4ff0805fca01..5fac9100f6cb 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -49,6 +49,31 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
49 handle_IRQ(irq, regs); 49 handle_IRQ(irq, regs);
50} 50}
51 51
52static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
53 unsigned int nr_irqs, void *arg)
54{
55 int i, ret;
56 irq_hw_number_t hwirq;
57 unsigned int type = IRQ_TYPE_NONE;
58 struct of_phandle_args *irq_data = arg;
59
60 ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args,
61 irq_data->args_count, &hwirq, &type);
62 if (ret)
63 return ret;
64
65 for (i = 0; i < nr_irqs; i++)
66 irq_map_generic_chip(domain, virq + i, hwirq + i);
67
68 return 0;
69}
70
71static const struct irq_domain_ops nvic_irq_domain_ops = {
72 .xlate = irq_domain_xlate_onecell,
73 .alloc = nvic_irq_domain_alloc,
74 .free = irq_domain_free_irqs_top,
75};
76
52static int __init nvic_of_init(struct device_node *node, 77static int __init nvic_of_init(struct device_node *node,
53 struct device_node *parent) 78 struct device_node *parent)
54{ 79{
@@ -70,7 +95,8 @@ static int __init nvic_of_init(struct device_node *node,
70 irqs = NVIC_MAX_IRQ; 95 irqs = NVIC_MAX_IRQ;
71 96
72 nvic_irq_domain = 97 nvic_irq_domain =
73 irq_domain_add_linear(node, irqs, &irq_generic_chip_ops, NULL); 98 irq_domain_add_linear(node, irqs, &nvic_irq_domain_ops, NULL);
99
74 if (!nvic_irq_domain) { 100 if (!nvic_irq_domain) {
75 pr_warn("Failed to allocate irq domain\n"); 101 pr_warn("Failed to allocate irq domain\n");
76 return -ENOMEM; 102 return -ENOMEM;
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 9a0767b9c89d..0670ab4e3897 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -347,7 +347,7 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq,
347 return 0; 347 return 0;
348} 348}
349 349
350static struct irq_domain_ops intc_irqpin_irq_domain_ops = { 350static const struct irq_domain_ops intc_irqpin_irq_domain_ops = {
351 .map = intc_irqpin_irq_domain_map, 351 .map = intc_irqpin_irq_domain_map,
352 .xlate = irq_domain_xlate_twocell, 352 .xlate = irq_domain_xlate_twocell,
353}; 353};
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index cdf80b7794cd..778bd076aeea 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -29,7 +29,6 @@
29#include <linux/err.h> 29#include <linux/err.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/platform_data/irq-renesas-irqc.h>
33#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
34 33
35#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ 34#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */
@@ -62,7 +61,6 @@ struct irqc_priv {
62 void __iomem *iomem; 61 void __iomem *iomem;
63 void __iomem *cpu_int_base; 62 void __iomem *cpu_int_base;
64 struct irqc_irq irq[IRQC_IRQ_MAX]; 63 struct irqc_irq irq[IRQC_IRQ_MAX];
65 struct renesas_irqc_config config;
66 unsigned int number_of_irqs; 64 unsigned int number_of_irqs;
67 struct platform_device *pdev; 65 struct platform_device *pdev;
68 struct irq_chip irq_chip; 66 struct irq_chip irq_chip;
@@ -168,14 +166,13 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq,
168 return 0; 166 return 0;
169} 167}
170 168
171static struct irq_domain_ops irqc_irq_domain_ops = { 169static const struct irq_domain_ops irqc_irq_domain_ops = {
172 .map = irqc_irq_domain_map, 170 .map = irqc_irq_domain_map,
173 .xlate = irq_domain_xlate_twocell, 171 .xlate = irq_domain_xlate_twocell,
174}; 172};
175 173
176static int irqc_probe(struct platform_device *pdev) 174static int irqc_probe(struct platform_device *pdev)
177{ 175{
178 struct renesas_irqc_config *pdata = pdev->dev.platform_data;
179 struct irqc_priv *p; 176 struct irqc_priv *p;
180 struct resource *io; 177 struct resource *io;
181 struct resource *irq; 178 struct resource *irq;
@@ -191,10 +188,6 @@ static int irqc_probe(struct platform_device *pdev)
191 goto err0; 188 goto err0;
192 } 189 }
193 190
194 /* deal with driver instance configuration */
195 if (pdata)
196 memcpy(&p->config, pdata, sizeof(*pdata));
197
198 p->pdev = pdev; 191 p->pdev = pdev;
199 platform_set_drvdata(pdev, p); 192 platform_set_drvdata(pdev, p);
200 193
@@ -251,8 +244,7 @@ static int irqc_probe(struct platform_device *pdev)
251 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; 244 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
252 245
253 p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, 246 p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
254 p->number_of_irqs, 247 p->number_of_irqs, 0,
255 p->config.irq_base,
256 &irqc_irq_domain_ops, p); 248 &irqc_irq_domain_ops, p);
257 if (!p->irq_domain) { 249 if (!p->irq_domain) {
258 ret = -ENXIO; 250 ret = -ENXIO;
@@ -272,13 +264,6 @@ static int irqc_probe(struct platform_device *pdev)
272 264
273 dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); 265 dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs);
274 266
275 /* warn in case of mismatch if irq base is specified */
276 if (p->config.irq_base) {
277 if (p->config.irq_base != p->irq[0].domain_irq)
278 dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n",
279 p->config.irq_base, p->irq[0].domain_irq);
280 }
281
282 return 0; 267 return 0;
283err3: 268err3:
284 while (--k >= 0) 269 while (--k >= 0)
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index c8d373fcd823..e96717f45ea1 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -502,7 +502,7 @@ err:
502 return -EINVAL; 502 return -EINVAL;
503} 503}
504 504
505static struct irq_domain_ops s3c24xx_irq_ops = { 505static const struct irq_domain_ops s3c24xx_irq_ops = {
506 .map = s3c24xx_irq_map, 506 .map = s3c24xx_irq_map,
507 .xlate = irq_domain_xlate_twocell, 507 .xlate = irq_domain_xlate_twocell,
508}; 508};
@@ -1228,7 +1228,7 @@ static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
1228 return 0; 1228 return 0;
1229} 1229}
1230 1230
1231static struct irq_domain_ops s3c24xx_irq_ops_of = { 1231static const struct irq_domain_ops s3c24xx_irq_ops_of = {
1232 .map = s3c24xx_irq_map_of, 1232 .map = s3c24xx_irq_map_of,
1233 .xlate = s3c24xx_irq_xlate_of, 1233 .xlate = s3c24xx_irq_xlate_of,
1234}; 1234};
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
index 64155b686081..83d6aa6464ee 100644
--- a/drivers/irqchip/irq-sun4i.c
+++ b/drivers/irqchip/irq-sun4i.c
@@ -89,7 +89,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
89 return 0; 89 return 0;
90} 90}
91 91
92static struct irq_domain_ops sun4i_irq_ops = { 92static const struct irq_domain_ops sun4i_irq_ops = {
93 .map = sun4i_irq_map, 93 .map = sun4i_irq_map,
94 .xlate = irq_domain_xlate_onecell, 94 .xlate = irq_domain_xlate_onecell,
95}; 95};
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 1ab451729a5c..888111b76ea0 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -132,7 +132,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct irq_domain_ops fpga_irqdomain_ops = { 135static const struct irq_domain_ops fpga_irqdomain_ops = {
136 .map = fpga_irqdomain_map, 136 .map = fpga_irqdomain_map,
137 .xlate = irq_domain_xlate_onetwocell, 137 .xlate = irq_domain_xlate_onetwocell,
138}; 138};
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c
index 9521057d4744..f5c01cbcc73a 100644
--- a/drivers/irqchip/irq-vf610-mscm-ir.c
+++ b/drivers/irqchip/irq-vf610-mscm-ir.c
@@ -47,6 +47,7 @@ struct vf610_mscm_ir_chip_data {
47 void __iomem *mscm_ir_base; 47 void __iomem *mscm_ir_base;
48 u16 cpu_mask; 48 u16 cpu_mask;
49 u16 saved_irsprc[MSCM_IRSPRC_NUM]; 49 u16 saved_irsprc[MSCM_IRSPRC_NUM];
50 bool is_nvic;
50}; 51};
51 52
52static struct vf610_mscm_ir_chip_data *mscm_ir_data; 53static struct vf610_mscm_ir_chip_data *mscm_ir_data;
@@ -101,7 +102,7 @@ static void vf610_mscm_ir_enable(struct irq_data *data)
101 writew_relaxed(chip_data->cpu_mask, 102 writew_relaxed(chip_data->cpu_mask,
102 chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); 103 chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
103 104
104 irq_chip_unmask_parent(data); 105 irq_chip_enable_parent(data);
105} 106}
106 107
107static void vf610_mscm_ir_disable(struct irq_data *data) 108static void vf610_mscm_ir_disable(struct irq_data *data)
@@ -111,7 +112,7 @@ static void vf610_mscm_ir_disable(struct irq_data *data)
111 112
112 writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); 113 writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
113 114
114 irq_chip_mask_parent(data); 115 irq_chip_disable_parent(data);
115} 116}
116 117
117static struct irq_chip vf610_mscm_ir_irq_chip = { 118static struct irq_chip vf610_mscm_ir_irq_chip = {
@@ -143,10 +144,17 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi
143 domain->host_data); 144 domain->host_data);
144 145
145 gic_data.np = domain->parent->of_node; 146 gic_data.np = domain->parent->of_node;
146 gic_data.args_count = 3; 147
147 gic_data.args[0] = GIC_SPI; 148 if (mscm_ir_data->is_nvic) {
148 gic_data.args[1] = irq_data->args[0]; 149 gic_data.args_count = 1;
149 gic_data.args[2] = irq_data->args[1]; 150 gic_data.args[0] = irq_data->args[0];
151 } else {
152 gic_data.args_count = 3;
153 gic_data.args[0] = GIC_SPI;
154 gic_data.args[1] = irq_data->args[0];
155 gic_data.args[2] = irq_data->args[1];
156 }
157
150 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); 158 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
151} 159}
152 160
@@ -174,10 +182,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
174 return -ENOMEM; 182 return -ENOMEM;
175 183
176 mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir"); 184 mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir");
177 185 if (IS_ERR(mscm_ir_data->mscm_ir_base)) {
178 if (!mscm_ir_data->mscm_ir_base) {
179 pr_err("vf610_mscm_ir: unable to map mscm register\n"); 186 pr_err("vf610_mscm_ir: unable to map mscm register\n");
180 ret = -ENOMEM; 187 ret = PTR_ERR(mscm_ir_data->mscm_ir_base);
181 goto out_free; 188 goto out_free;
182 } 189 }
183 190
@@ -199,6 +206,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
199 goto out_unmap; 206 goto out_unmap;
200 } 207 }
201 208
209 if (of_device_is_compatible(domain->parent->of_node, "arm,armv7m-nvic"))
210 mscm_ir_data->is_nvic = true;
211
202 cpu_pm_register_notifier(&mscm_ir_notifier_block); 212 cpu_pm_register_notifier(&mscm_ir_notifier_block);
203 213
204 return 0; 214 return 0;
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 54089debf2dc..d4ce331ea4a0 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -256,7 +256,7 @@ static void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
256 } while (handled); 256 } while (handled);
257} 257}
258 258
259static struct irq_domain_ops vic_irqdomain_ops = { 259static const struct irq_domain_ops vic_irqdomain_ops = {
260 .map = vic_irqdomain_map, 260 .map = vic_irqdomain_map,
261 .xlate = irq_domain_xlate_onetwocell, 261 .xlate = irq_domain_xlate_onetwocell,
262}; 262};
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
index b7af816f2769..0b297009b856 100644
--- a/drivers/irqchip/irq-vt8500.c
+++ b/drivers/irqchip/irq-vt8500.c
@@ -173,7 +173,7 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
173 return 0; 173 return 0;
174} 174}
175 175
176static struct irq_domain_ops vt8500_irq_domain_ops = { 176static const struct irq_domain_ops vt8500_irq_domain_ops = {
177 .map = vt8500_irq_map, 177 .map = vt8500_irq_map,
178 .xlate = irq_domain_xlate_onecell, 178 .xlate = irq_domain_xlate_onecell,
179}; 179};
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 9c145a7cb056..a45121546caf 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -207,8 +207,7 @@ static void __init spear_shirq_register(struct spear_shirq *shirq,
207 if (!shirq->irq_chip) 207 if (!shirq->irq_chip)
208 return; 208 return;
209 209
210 irq_set_chained_handler(parent_irq, shirq_handler); 210 irq_set_chained_handler_and_data(parent_irq, shirq_handler, shirq);
211 irq_set_handler_data(parent_irq, shirq);
212 211
213 for (i = 0; i < shirq->nr_irqs; i++) { 212 for (i = 0; i < shirq->nr_irqs; i++) {
214 irq_set_chip_and_handler(shirq->virq_base + i, 213 irq_set_chip_and_handler(shirq->virq_base + i,
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 58ea9fdd3a15..3591550598ad 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -566,8 +566,7 @@ static int ucb1x00_probe(struct mcp *mcp)
566 } 566 }
567 567
568 irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING); 568 irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
569 irq_set_handler_data(ucb->irq, ucb); 569 irq_set_chained_handler_and_data(ucb->irq, ucb1x00_irq, ucb);
570 irq_set_chained_handler(ucb->irq, ucb1x00_irq);
571 570
572 if (pdata && pdata->gpio_base) { 571 if (pdata && pdata->gpio_base) {
573 ucb->gpio.label = dev_name(&ucb->dev); 572 ucb->gpio.label = dev_name(&ucb->dev);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 48cb7d1aa58f..812149160d3b 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -126,13 +126,21 @@ struct msi_desc;
126struct irq_domain; 126struct irq_domain;
127 127
128/** 128/**
129 * struct irq_data - per irq and irq chip data passed down to chip functions 129 * struct irq_common_data - per irq data shared by all irqchips
130 * @state_use_accessors: status information for irq chip functions.
131 * Use accessor functions to deal with it
132 */
133struct irq_common_data {
134 unsigned int state_use_accessors;
135};
136
137/**
138 * struct irq_data - per irq chip data passed down to chip functions
130 * @mask: precomputed bitmask for accessing the chip registers 139 * @mask: precomputed bitmask for accessing the chip registers
131 * @irq: interrupt number 140 * @irq: interrupt number
132 * @hwirq: hardware interrupt number, local to the interrupt domain 141 * @hwirq: hardware interrupt number, local to the interrupt domain
133 * @node: node index useful for balancing 142 * @node: node index useful for balancing
134 * @state_use_accessors: status information for irq chip functions. 143 * @common: point to data shared by all irqchips
135 * Use accessor functions to deal with it
136 * @chip: low level interrupt hardware access 144 * @chip: low level interrupt hardware access
137 * @domain: Interrupt translation domain; responsible for mapping 145 * @domain: Interrupt translation domain; responsible for mapping
138 * between hwirq number and linux irq number. 146 * between hwirq number and linux irq number.
@@ -153,7 +161,7 @@ struct irq_data {
153 unsigned int irq; 161 unsigned int irq;
154 unsigned long hwirq; 162 unsigned long hwirq;
155 unsigned int node; 163 unsigned int node;
156 unsigned int state_use_accessors; 164 struct irq_common_data *common;
157 struct irq_chip *chip; 165 struct irq_chip *chip;
158 struct irq_domain *domain; 166 struct irq_domain *domain;
159#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 167#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -166,7 +174,7 @@ struct irq_data {
166}; 174};
167 175
168/* 176/*
169 * Bit masks for irq_data.state 177 * Bit masks for irq_common_data.state_use_accessors
170 * 178 *
171 * IRQD_TRIGGER_MASK - Mask for the trigger type bits 179 * IRQD_TRIGGER_MASK - Mask for the trigger type bits
172 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending 180 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
@@ -198,34 +206,36 @@ enum {
198 IRQD_WAKEUP_ARMED = (1 << 19), 206 IRQD_WAKEUP_ARMED = (1 << 19),
199}; 207};
200 208
209#define __irqd_to_state(d) ((d)->common->state_use_accessors)
210
201static inline bool irqd_is_setaffinity_pending(struct irq_data *d) 211static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
202{ 212{
203 return d->state_use_accessors & IRQD_SETAFFINITY_PENDING; 213 return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
204} 214}
205 215
206static inline bool irqd_is_per_cpu(struct irq_data *d) 216static inline bool irqd_is_per_cpu(struct irq_data *d)
207{ 217{
208 return d->state_use_accessors & IRQD_PER_CPU; 218 return __irqd_to_state(d) & IRQD_PER_CPU;
209} 219}
210 220
211static inline bool irqd_can_balance(struct irq_data *d) 221static inline bool irqd_can_balance(struct irq_data *d)
212{ 222{
213 return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING)); 223 return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
214} 224}
215 225
216static inline bool irqd_affinity_was_set(struct irq_data *d) 226static inline bool irqd_affinity_was_set(struct irq_data *d)
217{ 227{
218 return d->state_use_accessors & IRQD_AFFINITY_SET; 228 return __irqd_to_state(d) & IRQD_AFFINITY_SET;
219} 229}
220 230
221static inline void irqd_mark_affinity_was_set(struct irq_data *d) 231static inline void irqd_mark_affinity_was_set(struct irq_data *d)
222{ 232{
223 d->state_use_accessors |= IRQD_AFFINITY_SET; 233 __irqd_to_state(d) |= IRQD_AFFINITY_SET;
224} 234}
225 235
226static inline u32 irqd_get_trigger_type(struct irq_data *d) 236static inline u32 irqd_get_trigger_type(struct irq_data *d)
227{ 237{
228 return d->state_use_accessors & IRQD_TRIGGER_MASK; 238 return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
229} 239}
230 240
231/* 241/*
@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
233 */ 243 */
234static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) 244static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
235{ 245{
236 d->state_use_accessors &= ~IRQD_TRIGGER_MASK; 246 __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
237 d->state_use_accessors |= type & IRQD_TRIGGER_MASK; 247 __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
238} 248}
239 249
240static inline bool irqd_is_level_type(struct irq_data *d) 250static inline bool irqd_is_level_type(struct irq_data *d)
241{ 251{
242 return d->state_use_accessors & IRQD_LEVEL; 252 return __irqd_to_state(d) & IRQD_LEVEL;
243} 253}
244 254
245static inline bool irqd_is_wakeup_set(struct irq_data *d) 255static inline bool irqd_is_wakeup_set(struct irq_data *d)
246{ 256{
247 return d->state_use_accessors & IRQD_WAKEUP_STATE; 257 return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
248} 258}
249 259
250static inline bool irqd_can_move_in_process_context(struct irq_data *d) 260static inline bool irqd_can_move_in_process_context(struct irq_data *d)
251{ 261{
252 return d->state_use_accessors & IRQD_MOVE_PCNTXT; 262 return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
253} 263}
254 264
255static inline bool irqd_irq_disabled(struct irq_data *d) 265static inline bool irqd_irq_disabled(struct irq_data *d)
256{ 266{
257 return d->state_use_accessors & IRQD_IRQ_DISABLED; 267 return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
258} 268}
259 269
260static inline bool irqd_irq_masked(struct irq_data *d) 270static inline bool irqd_irq_masked(struct irq_data *d)
261{ 271{
262 return d->state_use_accessors & IRQD_IRQ_MASKED; 272 return __irqd_to_state(d) & IRQD_IRQ_MASKED;
263} 273}
264 274
265static inline bool irqd_irq_inprogress(struct irq_data *d) 275static inline bool irqd_irq_inprogress(struct irq_data *d)
266{ 276{
267 return d->state_use_accessors & IRQD_IRQ_INPROGRESS; 277 return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
268} 278}
269 279
270static inline bool irqd_is_wakeup_armed(struct irq_data *d) 280static inline bool irqd_is_wakeup_armed(struct irq_data *d)
271{ 281{
272 return d->state_use_accessors & IRQD_WAKEUP_ARMED; 282 return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
273} 283}
274 284
275 285
@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
280 */ 290 */
281static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) 291static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
282{ 292{
283 d->state_use_accessors |= IRQD_IRQ_INPROGRESS; 293 __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
284} 294}
285 295
286static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) 296static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
287{ 297{
288 d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; 298 __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
289} 299}
290 300
291static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 301static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -462,6 +472,8 @@ extern void handle_nested_irq(unsigned int irq);
462 472
463extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); 473extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
464#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 474#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
475extern void irq_chip_enable_parent(struct irq_data *data);
476extern void irq_chip_disable_parent(struct irq_data *data);
465extern void irq_chip_ack_parent(struct irq_data *data); 477extern void irq_chip_ack_parent(struct irq_data *data);
466extern int irq_chip_retrigger_hierarchy(struct irq_data *data); 478extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
467extern void irq_chip_mask_parent(struct irq_data *data); 479extern void irq_chip_mask_parent(struct irq_data *data);
@@ -523,6 +535,15 @@ irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
523 __irq_set_handler(irq, handle, 1, NULL); 535 __irq_set_handler(irq, handle, 1, NULL);
524} 536}
525 537
538/*
539 * Set a highlevel chained flow handler and its data for a given IRQ.
540 * (a chained handler is automatically enabled and set to
541 * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
542 */
543void
544irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
545 void *data);
546
526void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); 547void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
527 548
528static inline void irq_set_status_flags(unsigned int irq, unsigned long set) 549static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
@@ -630,6 +651,23 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
630 return d ? irqd_get_trigger_type(d) : 0; 651 return d ? irqd_get_trigger_type(d) : 0;
631} 652}
632 653
654static inline int irq_data_get_node(struct irq_data *d)
655{
656 return d->node;
657}
658
659static inline struct cpumask *irq_get_affinity_mask(int irq)
660{
661 struct irq_data *d = irq_get_irq_data(irq);
662
663 return d ? d->affinity : NULL;
664}
665
666static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
667{
668 return d->affinity;
669}
670
633unsigned int arch_dynirq_lower_bound(unsigned int from); 671unsigned int arch_dynirq_lower_bound(unsigned int from);
634 672
635int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, 673int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index a113a8dc7438..c52d1480f272 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,7 +17,7 @@ struct pt_regs;
17 17
18/** 18/**
19 * struct irq_desc - interrupt descriptor 19 * struct irq_desc - interrupt descriptor
20 * @irq_data: per irq and chip data passed down to chip functions 20 * @irq_common_data: per irq and chip data passed down to chip functions
21 * @kstat_irqs: irq stats per cpu 21 * @kstat_irqs: irq stats per cpu
22 * @handle_irq: highlevel irq-events handler 22 * @handle_irq: highlevel irq-events handler
23 * @preflow_handler: handler called before the flow handler (currently used by sparc) 23 * @preflow_handler: handler called before the flow handler (currently used by sparc)
@@ -47,6 +47,7 @@ struct pt_regs;
47 * @name: flow handler name for /proc/interrupts output 47 * @name: flow handler name for /proc/interrupts output
48 */ 48 */
49struct irq_desc { 49struct irq_desc {
50 struct irq_common_data irq_common_data;
50 struct irq_data irq_data; 51 struct irq_data irq_data;
51 unsigned int __percpu *kstat_irqs; 52 unsigned int __percpu *kstat_irqs;
52 irq_flow_handler_t handle_irq; 53 irq_flow_handler_t handle_irq;
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 676d7306a360..744ac0ec98eb 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -258,6 +258,10 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
258/* V2 interfaces to support hierarchy IRQ domains. */ 258/* V2 interfaces to support hierarchy IRQ domains. */
259extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, 259extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
260 unsigned int virq); 260 unsigned int virq);
261extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
262 irq_hw_number_t hwirq, struct irq_chip *chip,
263 void *chip_data, irq_flow_handler_t handler,
264 void *handler_data, const char *handler_name);
261#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 265#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
262extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent, 266extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
263 unsigned int flags, unsigned int size, 267 unsigned int flags, unsigned int size,
@@ -281,10 +285,6 @@ extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
281 irq_hw_number_t hwirq, 285 irq_hw_number_t hwirq,
282 struct irq_chip *chip, 286 struct irq_chip *chip,
283 void *chip_data); 287 void *chip_data);
284extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
285 irq_hw_number_t hwirq, struct irq_chip *chip,
286 void *chip_data, irq_flow_handler_t handler,
287 void *handler_data, const char *handler_name);
288extern void irq_domain_reset_irq_data(struct irq_data *irq_data); 288extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
289extern void irq_domain_free_irqs_common(struct irq_domain *domain, 289extern void irq_domain_free_irqs_common(struct irq_domain *domain,
290 unsigned int virq, 290 unsigned int virq,
diff --git a/include/linux/platform_data/irq-renesas-irqc.h b/include/linux/platform_data/irq-renesas-irqc.h
deleted file mode 100644
index 3ae17b3e00ed..000000000000
--- a/include/linux/platform_data/irq-renesas-irqc.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * Renesas IRQC 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_IRQC_H__
21#define __IRQ_RENESAS_IRQC_H__
22
23struct renesas_irqc_config {
24 unsigned int irq_base;
25};
26
27#endif /* __IRQ_RENESAS_IRQC_H__ */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 55016b2151f3..27f4332c7f84 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -719,15 +719,9 @@ void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
719} 719}
720 720
721void 721void
722__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 722__irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
723 const char *name) 723 int is_chained, const char *name)
724{ 724{
725 unsigned long flags;
726 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
727
728 if (!desc)
729 return;
730
731 if (!handle) { 725 if (!handle) {
732 handle = handle_bad_irq; 726 handle = handle_bad_irq;
733 } else { 727 } else {
@@ -749,13 +743,13 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
749 * right away. 743 * right away.
750 */ 744 */
751 if (WARN_ON(is_chained)) 745 if (WARN_ON(is_chained))
752 goto out; 746 return;
753 /* Try the parent */ 747 /* Try the parent */
754 irq_data = irq_data->parent_data; 748 irq_data = irq_data->parent_data;
755 } 749 }
756#endif 750#endif
757 if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip)) 751 if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip))
758 goto out; 752 return;
759 } 753 }
760 754
761 /* Uninstall? */ 755 /* Uninstall? */
@@ -774,12 +768,41 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
774 irq_settings_set_nothread(desc); 768 irq_settings_set_nothread(desc);
775 irq_startup(desc, true); 769 irq_startup(desc, true);
776 } 770 }
777out: 771}
772
773void
774__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
775 const char *name)
776{
777 unsigned long flags;
778 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
779
780 if (!desc)
781 return;
782
783 __irq_do_set_handler(desc, handle, is_chained, name);
778 irq_put_desc_busunlock(desc, flags); 784 irq_put_desc_busunlock(desc, flags);
779} 785}
780EXPORT_SYMBOL_GPL(__irq_set_handler); 786EXPORT_SYMBOL_GPL(__irq_set_handler);
781 787
782void 788void
789irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
790 void *data)
791{
792 unsigned long flags;
793 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
794
795 if (!desc)
796 return;
797
798 __irq_do_set_handler(desc, handle, 1, NULL);
799 desc->irq_data.handler_data = data;
800
801 irq_put_desc_busunlock(desc, flags);
802}
803EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
804
805void
783irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, 806irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
784 irq_flow_handler_t handle, const char *name) 807 irq_flow_handler_t handle, const char *name)
785{ 808{
@@ -876,6 +899,34 @@ void irq_cpu_offline(void)
876 899
877#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 900#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
878/** 901/**
902 * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
903 * NULL)
904 * @data: Pointer to interrupt specific data
905 */
906void irq_chip_enable_parent(struct irq_data *data)
907{
908 data = data->parent_data;
909 if (data->chip->irq_enable)
910 data->chip->irq_enable(data);
911 else
912 data->chip->irq_unmask(data);
913}
914
915/**
916 * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
917 * NULL)
918 * @data: Pointer to interrupt specific data
919 */
920void irq_chip_disable_parent(struct irq_data *data)
921{
922 data = data->parent_data;
923 if (data->chip->irq_disable)
924 data->chip->irq_disable(data);
925 else
926 data->chip->irq_mask(data);
927}
928
929/**
879 * irq_chip_ack_parent - Acknowledge the parent interrupt 930 * irq_chip_ack_parent - Acknowledge the parent interrupt
880 * @data: Pointer to interrupt specific data 931 * @data: Pointer to interrupt specific data
881 */ 932 */
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index d5d0f7345c54..74d90a754268 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -104,7 +104,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq,
104 return -ENOMEM; 104 return -ENOMEM;
105 105
106 rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id); 106 rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
107 if (rc) { 107 if (rc < 0) {
108 devres_free(dr); 108 devres_free(dr);
109 return rc; 109 return rc;
110 } 110 }
@@ -113,7 +113,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq,
113 dr->dev_id = dev_id; 113 dr->dev_id = dev_id;
114 devres_add(dev, dr); 114 devres_add(dev, dr);
115 115
116 return 0; 116 return rc;
117} 117}
118EXPORT_SYMBOL(devm_request_any_context_irq); 118EXPORT_SYMBOL(devm_request_any_context_irq);
119 119
diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c
index 2feb6feca0cc..326a67f2410b 100644
--- a/kernel/irq/dummychip.c
+++ b/kernel/irq/dummychip.c
@@ -42,6 +42,7 @@ struct irq_chip no_irq_chip = {
42 .irq_enable = noop, 42 .irq_enable = noop,
43 .irq_disable = noop, 43 .irq_disable = noop,
44 .irq_ack = ack_bad, 44 .irq_ack = ack_bad,
45 .flags = IRQCHIP_SKIP_SET_WAKE,
45}; 46};
46 47
47/* 48/*
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index 61024e8abdef..15b370daf234 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -360,7 +360,7 @@ static struct lock_class_key irq_nested_lock_class;
360int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, 360int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
361 irq_hw_number_t hw_irq) 361 irq_hw_number_t hw_irq)
362{ 362{
363 struct irq_data *data = irq_get_irq_data(virq); 363 struct irq_data *data = irq_domain_get_irq_data(d, virq);
364 struct irq_domain_chip_generic *dgc = d->gc; 364 struct irq_domain_chip_generic *dgc = d->gc;
365 struct irq_chip_generic *gc; 365 struct irq_chip_generic *gc;
366 struct irq_chip_type *ct; 366 struct irq_chip_type *ct;
@@ -405,8 +405,7 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
405 else 405 else
406 data->mask = 1 << idx; 406 data->mask = 1 << idx;
407 407
408 irq_set_chip_and_handler(virq, chip, ct->handler); 408 irq_domain_set_info(d, virq, hw_irq, chip, gc, ct->handler, NULL, NULL);
409 irq_set_chip_data(virq, gc);
410 irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set); 409 irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set);
411 return 0; 410 return 0;
412} 411}
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b93d434e70bd..4834ee828c41 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
168 */ 168 */
169static inline void irqd_set_move_pending(struct irq_data *d) 169static inline void irqd_set_move_pending(struct irq_data *d)
170{ 170{
171 d->state_use_accessors |= IRQD_SETAFFINITY_PENDING; 171 __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
172} 172}
173 173
174static inline void irqd_clr_move_pending(struct irq_data *d) 174static inline void irqd_clr_move_pending(struct irq_data *d)
175{ 175{
176 d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING; 176 __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
177} 177}
178 178
179static inline void irqd_clear(struct irq_data *d, unsigned int mask) 179static inline void irqd_clear(struct irq_data *d, unsigned int mask)
180{ 180{
181 d->state_use_accessors &= ~mask; 181 __irqd_to_state(d) &= ~mask;
182} 182}
183 183
184static inline void irqd_set(struct irq_data *d, unsigned int mask) 184static inline void irqd_set(struct irq_data *d, unsigned int mask)
185{ 185{
186 d->state_use_accessors |= mask; 186 __irqd_to_state(d) |= mask;
187} 187}
188 188
189static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) 189static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
190{ 190{
191 return d->state_use_accessors & mask; 191 return __irqd_to_state(d) & mask;
192} 192}
193 193
194static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) 194static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
@@ -197,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
197 __this_cpu_inc(kstat.irqs_sum); 197 __this_cpu_inc(kstat.irqs_sum);
198} 198}
199 199
200static inline int irq_desc_get_node(struct irq_desc *desc)
201{
202 return irq_data_get_node(&desc->irq_data);
203}
204
200#ifdef CONFIG_PM_SLEEP 205#ifdef CONFIG_PM_SLEEP
201bool irq_pm_check_wakeup(struct irq_desc *desc); 206bool irq_pm_check_wakeup(struct irq_desc *desc);
202void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action); 207void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 99793b9b6d23..4afc457613dd 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node)
59#endif 59#endif
60} 60}
61 61
62static inline int desc_node(struct irq_desc *desc)
63{
64 return desc->irq_data.node;
65}
66
67#else 62#else
68static inline int 63static inline int
69alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; } 64alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
70static inline void desc_smp_init(struct irq_desc *desc, int node) { } 65static inline void desc_smp_init(struct irq_desc *desc, int node) { }
71static inline int desc_node(struct irq_desc *desc) { return 0; }
72#endif 66#endif
73 67
74static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, 68static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
@@ -76,6 +70,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
76{ 70{
77 int cpu; 71 int cpu;
78 72
73 desc->irq_data.common = &desc->irq_common_data;
79 desc->irq_data.irq = irq; 74 desc->irq_data.irq = irq;
80 desc->irq_data.chip = &no_irq_chip; 75 desc->irq_data.chip = &no_irq_chip;
81 desc->irq_data.chip_data = NULL; 76 desc->irq_data.chip_data = NULL;
@@ -299,7 +294,7 @@ static void free_desc(unsigned int irq)
299 unsigned long flags; 294 unsigned long flags;
300 295
301 raw_spin_lock_irqsave(&desc->lock, flags); 296 raw_spin_lock_irqsave(&desc->lock, flags);
302 desc_set_defaults(irq, desc, desc_node(desc), NULL); 297 desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
303 raw_spin_unlock_irqrestore(&desc->lock, flags); 298 raw_spin_unlock_irqrestore(&desc->lock, flags);
304} 299}
305 300
@@ -619,7 +614,7 @@ unsigned int kstat_irqs(unsigned int irq)
619{ 614{
620 struct irq_desc *desc = irq_to_desc(irq); 615 struct irq_desc *desc = irq_to_desc(irq);
621 int cpu; 616 int cpu;
622 int sum = 0; 617 unsigned int sum = 0;
623 618
624 if (!desc || !desc->kstat_irqs) 619 if (!desc || !desc->kstat_irqs)
625 return 0; 620 return 0;
@@ -639,7 +634,7 @@ unsigned int kstat_irqs(unsigned int irq)
639 */ 634 */
640unsigned int kstat_irqs_usr(unsigned int irq) 635unsigned int kstat_irqs_usr(unsigned int irq)
641{ 636{
642 int sum; 637 unsigned int sum;
643 638
644 irq_lock_sparse(); 639 irq_lock_sparse();
645 sum = kstat_irqs(irq); 640 sum = kstat_irqs(irq);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7fac311057b8..8c3577fef78c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -830,10 +830,12 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
830{ 830{
831 struct irq_data *irq_data; 831 struct irq_data *irq_data;
832 832
833 irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node); 833 irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
834 irq_data_get_node(child));
834 if (irq_data) { 835 if (irq_data) {
835 child->parent_data = irq_data; 836 child->parent_data = irq_data;
836 irq_data->irq = child->irq; 837 irq_data->irq = child->irq;
838 irq_data->common = child->common;
837 irq_data->node = child->node; 839 irq_data->node = child->node;
838 irq_data->domain = domain; 840 irq_data->domain = domain;
839 } 841 }
@@ -1232,6 +1234,27 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
1232 return (irq_data && irq_data->domain == domain) ? irq_data : NULL; 1234 return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
1233} 1235}
1234 1236
1237/**
1238 * irq_domain_set_info - Set the complete data for a @virq in @domain
1239 * @domain: Interrupt domain to match
1240 * @virq: IRQ number
1241 * @hwirq: The hardware interrupt number
1242 * @chip: The associated interrupt chip
1243 * @chip_data: The associated interrupt chip data
1244 * @handler: The interrupt flow handler
1245 * @handler_data: The interrupt flow handler data
1246 * @handler_name: The interrupt handler name
1247 */
1248void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
1249 irq_hw_number_t hwirq, struct irq_chip *chip,
1250 void *chip_data, irq_flow_handler_t handler,
1251 void *handler_data, const char *handler_name)
1252{
1253 irq_set_chip_and_handler_name(virq, chip, handler, handler_name);
1254 irq_set_chip_data(virq, chip_data);
1255 irq_set_handler_data(virq, handler_data);
1256}
1257
1235static void irq_domain_check_hierarchy(struct irq_domain *domain) 1258static void irq_domain_check_hierarchy(struct irq_domain *domain)
1236{ 1259{
1237} 1260}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b1c7e8f46bfb..f9744853b656 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -363,7 +363,7 @@ static int
363setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) 363setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
364{ 364{
365 struct cpumask *set = irq_default_affinity; 365 struct cpumask *set = irq_default_affinity;
366 int node = desc->irq_data.node; 366 int node = irq_desc_get_node(desc);
367 367
368 /* Excludes PER_CPU and NO_BALANCE interrupts */ 368 /* Excludes PER_CPU and NO_BALANCE interrupts */
369 if (!irq_can_set_affinity(irq)) 369 if (!irq_can_set_affinity(irq))
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index dd203e276b07..37ddb7bda651 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -12,16 +12,16 @@ void irq_move_masked_irq(struct irq_data *idata)
12 if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) 12 if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
13 return; 13 return;
14 14
15 irqd_clr_move_pending(&desc->irq_data);
16
15 /* 17 /*
16 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway. 18 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway.
17 */ 19 */
18 if (!irqd_can_balance(&desc->irq_data)) { 20 if (irqd_is_per_cpu(&desc->irq_data)) {
19 WARN_ON(1); 21 WARN_ON(1);
20 return; 22 return;
21 } 23 }
22 24
23 irqd_clr_move_pending(&desc->irq_data);
24
25 if (unlikely(cpumask_empty(desc->pending_mask))) 25 if (unlikely(cpumask_empty(desc->pending_mask)))
26 return; 26 return;
27 27
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 474de5cb394d..7bf1f1bbb7fa 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -124,7 +124,7 @@ static void msi_domain_free(struct irq_domain *domain, unsigned int virq,
124 irq_domain_free_irqs_top(domain, virq, nr_irqs); 124 irq_domain_free_irqs_top(domain, virq, nr_irqs);
125} 125}
126 126
127static struct irq_domain_ops msi_domain_ops = { 127static const struct irq_domain_ops msi_domain_ops = {
128 .alloc = msi_domain_alloc, 128 .alloc = msi_domain_alloc,
129 .free = msi_domain_free, 129 .free = msi_domain_free,
130 .activate = msi_domain_activate, 130 .activate = msi_domain_activate,
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index 5204a6d1b985..d22786a6dbde 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -123,6 +123,8 @@ void suspend_device_irqs(void)
123 unsigned long flags; 123 unsigned long flags;
124 bool sync; 124 bool sync;
125 125
126 if (irq_settings_is_nested_thread(desc))
127 continue;
126 raw_spin_lock_irqsave(&desc->lock, flags); 128 raw_spin_lock_irqsave(&desc->lock, flags);
127 sync = suspend_device_irq(desc, irq); 129 sync = suspend_device_irq(desc, irq);
128 raw_spin_unlock_irqrestore(&desc->lock, flags); 130 raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -163,6 +165,8 @@ static void resume_irqs(bool want_early)
163 165
164 if (!is_early && want_early) 166 if (!is_early && want_early)
165 continue; 167 continue;
168 if (irq_settings_is_nested_thread(desc))
169 continue;
166 170
167 raw_spin_lock_irqsave(&desc->lock, flags); 171 raw_spin_lock_irqsave(&desc->lock, flags);
168 resume_irq(desc, irq); 172 resume_irq(desc, irq);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index df2f4642d1e7..0e97c142ce40 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
241{ 241{
242 struct irq_desc *desc = irq_to_desc((long) m->private); 242 struct irq_desc *desc = irq_to_desc((long) m->private);
243 243
244 seq_printf(m, "%d\n", desc->irq_data.node); 244 seq_printf(m, "%d\n", irq_desc_get_node(desc));
245 return 0; 245 return 0;
246} 246}
247 247