diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-22 22:42:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-22 22:42:56 -0400 |
commit | 407a2c720556e8e340e06f6a7174f5d6d80cf9ea (patch) | |
tree | b78ba543dbef195909611448ca833348581b63a6 | |
parent | 3a95398f54cbd664c749fe9f1bfc7e7dbace92d0 (diff) | |
parent | f05218651be1ac6a6088e226bd7350fb6c154414 (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
...
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 | ||
3 | Required properties: | 3 | Required 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 | ||
20 | Optional properties: | 23 | Optional 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 | |||
39 | Example | ||
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 | |||
30 | config ARM_NVIC | 30 | config 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 | ||
35 | config ARM_VIC | 36 | config 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 | ||
43 | static struct combiner_chip_data *combiner_data; | ||
39 | static struct irq_domain *combiner_irq_domain; | 44 | static struct irq_domain *combiner_irq_domain; |
45 | static unsigned int max_nr = 20; | ||
40 | 46 | ||
41 | static inline void __iomem *combiner_base(struct irq_data *data) | 47 | static 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 | ||
167 | static struct irq_domain_ops combiner_irq_domain_ops = { | 173 | static 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 | ||
172 | static void __init combiner_init(void __iomem *combiner_base, | 178 | static 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 | */ | ||
217 | static 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 | */ | ||
235 | static 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 | |||
252 | static struct syscore_ops combiner_syscore_ops = { | ||
253 | .suspend = combiner_suspend, | ||
254 | .resume = combiner_resume, | ||
255 | }; | ||
256 | |||
204 | static int __init combiner_of_init(struct device_node *np, | 257 | static 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 | ||
412 | static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { | 412 | static 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 | |||
344 | static 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 | } | ||
349 | IRQCHIP_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 | ||
344 | static int __init sama5d3_aic5_of_init(struct device_node *node, | 353 | static 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 | ||
138 | static struct irq_domain_ops armctrl_ops = { | 138 | static 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 @@ | |||
24 | int gic_configure_irq(unsigned int irq, unsigned int type, | 24 | int 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 | ||
329 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | 330 | void __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 | ||
207 | static u16 hip04_get_cpumask(struct hip04_irq_data *intc) | 208 | static 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 | ||
134 | static struct irq_domain_ops keystone_irq_ops = { | 134 | static 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 | ||
749 | static struct irq_domain_ops gic_irq_domain_ops = { | 749 | static 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 | ||
114 | static struct irq_domain_ops sysirq_domain_ops = { | 114 | static 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 | ||
93 | static struct irq_domain_ops icoll_irq_domain_ops = { | 93 | static 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 | ||
52 | static 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 | |||
71 | static 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 | |||
52 | static int __init nvic_of_init(struct device_node *node, | 77 | static 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 | ||
350 | static struct irq_domain_ops intc_irqpin_irq_domain_ops = { | 350 | static 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 | ||
171 | static struct irq_domain_ops irqc_irq_domain_ops = { | 169 | static 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 | ||
176 | static int irqc_probe(struct platform_device *pdev) | 174 | static 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; |
283 | err3: | 268 | err3: |
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 | ||
505 | static struct irq_domain_ops s3c24xx_irq_ops = { | 505 | static 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 | ||
1231 | static struct irq_domain_ops s3c24xx_irq_ops_of = { | 1231 | static 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 | ||
92 | static struct irq_domain_ops sun4i_irq_ops = { | 92 | static 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 | ||
135 | static struct irq_domain_ops fpga_irqdomain_ops = { | 135 | static 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 | ||
52 | static struct vf610_mscm_ir_chip_data *mscm_ir_data; | 53 | static 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 | ||
107 | static void vf610_mscm_ir_disable(struct irq_data *data) | 108 | static 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 | ||
117 | static struct irq_chip vf610_mscm_ir_irq_chip = { | 118 | static 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 | ||
259 | static struct irq_domain_ops vic_irqdomain_ops = { | 259 | static 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 | ||
176 | static struct irq_domain_ops vt8500_irq_domain_ops = { | 176 | static 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; | |||
126 | struct irq_domain; | 126 | struct 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 | */ | ||
133 | struct 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 | |||
201 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) | 211 | static 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 | ||
206 | static inline bool irqd_is_per_cpu(struct irq_data *d) | 216 | static 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 | ||
211 | static inline bool irqd_can_balance(struct irq_data *d) | 221 | static 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 | ||
216 | static inline bool irqd_affinity_was_set(struct irq_data *d) | 226 | static 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 | ||
221 | static inline void irqd_mark_affinity_was_set(struct irq_data *d) | 231 | static 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 | ||
226 | static inline u32 irqd_get_trigger_type(struct irq_data *d) | 236 | static 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 | */ |
234 | static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) | 244 | static 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 | ||
240 | static inline bool irqd_is_level_type(struct irq_data *d) | 250 | static 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 | ||
245 | static inline bool irqd_is_wakeup_set(struct irq_data *d) | 255 | static 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 | ||
250 | static inline bool irqd_can_move_in_process_context(struct irq_data *d) | 260 | static 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 | ||
255 | static inline bool irqd_irq_disabled(struct irq_data *d) | 265 | static 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 | ||
260 | static inline bool irqd_irq_masked(struct irq_data *d) | 270 | static 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 | ||
265 | static inline bool irqd_irq_inprogress(struct irq_data *d) | 275 | static 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 | ||
270 | static inline bool irqd_is_wakeup_armed(struct irq_data *d) | 280 | static 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 | */ |
281 | static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) | 291 | static 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 | ||
286 | static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) | 296 | static 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 | ||
291 | static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) | 301 | static 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 | ||
463 | extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); | 473 | extern 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 |
475 | extern void irq_chip_enable_parent(struct irq_data *data); | ||
476 | extern void irq_chip_disable_parent(struct irq_data *data); | ||
465 | extern void irq_chip_ack_parent(struct irq_data *data); | 477 | extern void irq_chip_ack_parent(struct irq_data *data); |
466 | extern int irq_chip_retrigger_hierarchy(struct irq_data *data); | 478 | extern int irq_chip_retrigger_hierarchy(struct irq_data *data); |
467 | extern void irq_chip_mask_parent(struct irq_data *data); | 479 | extern 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 | */ | ||
543 | void | ||
544 | irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, | ||
545 | void *data); | ||
546 | |||
526 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); | 547 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); |
527 | 548 | ||
528 | static inline void irq_set_status_flags(unsigned int irq, unsigned long set) | 549 | static 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 | ||
654 | static inline int irq_data_get_node(struct irq_data *d) | ||
655 | { | ||
656 | return d->node; | ||
657 | } | ||
658 | |||
659 | static 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 | |||
666 | static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d) | ||
667 | { | ||
668 | return d->affinity; | ||
669 | } | ||
670 | |||
633 | unsigned int arch_dynirq_lower_bound(unsigned int from); | 671 | unsigned int arch_dynirq_lower_bound(unsigned int from); |
634 | 672 | ||
635 | int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, | 673 | int __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 | */ |
49 | struct irq_desc { | 49 | struct 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. */ |
259 | extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, | 259 | extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, |
260 | unsigned int virq); | 260 | unsigned int virq); |
261 | extern 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 |
262 | extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent, | 266 | extern 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); |
284 | extern 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); | ||
288 | extern void irq_domain_reset_irq_data(struct irq_data *irq_data); | 288 | extern void irq_domain_reset_irq_data(struct irq_data *irq_data); |
289 | extern void irq_domain_free_irqs_common(struct irq_domain *domain, | 289 | extern 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 | |||
23 | struct 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 | ||
721 | void | 721 | void |
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 | } |
777 | out: | 771 | } |
772 | |||
773 | void | ||
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 | } |
780 | EXPORT_SYMBOL_GPL(__irq_set_handler); | 786 | EXPORT_SYMBOL_GPL(__irq_set_handler); |
781 | 787 | ||
782 | void | 788 | void |
789 | irq_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 | } | ||
803 | EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data); | ||
804 | |||
805 | void | ||
783 | irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, | 806 | irq_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 | */ | ||
906 | void 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 | */ | ||
920 | void 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 | } |
118 | EXPORT_SYMBOL(devm_request_any_context_irq); | 118 | EXPORT_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; | |||
360 | int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, | 360 | int 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 | */ |
169 | static inline void irqd_set_move_pending(struct irq_data *d) | 169 | static 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 | ||
174 | static inline void irqd_clr_move_pending(struct irq_data *d) | 174 | static 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 | ||
179 | static inline void irqd_clear(struct irq_data *d, unsigned int mask) | 179 | static 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 | ||
184 | static inline void irqd_set(struct irq_data *d, unsigned int mask) | 184 | static 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 | ||
189 | static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) | 189 | static 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 | ||
194 | static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) | 194 | static 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 | ||
200 | static 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 |
201 | bool irq_pm_check_wakeup(struct irq_desc *desc); | 206 | bool irq_pm_check_wakeup(struct irq_desc *desc); |
202 | void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action); | 207 | void 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 | ||
62 | static inline int desc_node(struct irq_desc *desc) | ||
63 | { | ||
64 | return desc->irq_data.node; | ||
65 | } | ||
66 | |||
67 | #else | 62 | #else |
68 | static inline int | 63 | static inline int |
69 | alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; } | 64 | alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; } |
70 | static inline void desc_smp_init(struct irq_desc *desc, int node) { } | 65 | static inline void desc_smp_init(struct irq_desc *desc, int node) { } |
71 | static inline int desc_node(struct irq_desc *desc) { return 0; } | ||
72 | #endif | 66 | #endif |
73 | 67 | ||
74 | static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, | 68 | static 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 | */ |
640 | unsigned int kstat_irqs_usr(unsigned int irq) | 635 | unsigned 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 | */ | ||
1248 | void 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 | |||
1235 | static void irq_domain_check_hierarchy(struct irq_domain *domain) | 1258 | static 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 | |||
363 | setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) | 363 | setup_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 | ||
127 | static struct irq_domain_ops msi_domain_ops = { | 127 | static 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 | ||