diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-16 18:20:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-16 18:20:40 -0500 |
commit | 3c6847eaa3da59f3bbe15eb3004ddab41ae6a201 (patch) | |
tree | 9a33b100efeaa63fab23662eb0db42385b8d1f10 | |
parent | 37507717de51a8332a34ee07fd88700be88df5bf (diff) | |
parent | 4fe7ffb7e17ca6ad9173b8de35f260c9c8fc2f79 (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irqchip updates from Ingo Molnar:
"Various irqchip driver updates, plus a genirq core update that allows
the initial spreading of irqs amonst CPUs without having to do it from
user-space"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq: Fix null pointer reference in irq_set_affinity_hint()
irqchip: gic: Allow interrupt level to be set for PPIs
irqchip: mips-gic: Handle pending interrupts once in __gic_irq_dispatch()
irqchip: Conexant CX92755 interrupts controller driver
irqchip: Devicetree: document Conexant Digicolor irq binding
irqchip: omap-intc: Remove unused legacy interface for omap2
irqchip: omap-intc: Fix support for dm814 and dm816
irqchip: mtk-sysirq: Get irq number from register resource size
irqchip: renesas-intc-irqpin: r8a7779 IRLM setup support
genirq: Set initial affinity in irq_set_affinity_hint()
-rw-r--r-- | Documentation/devicetree/bindings/arm/gic.txt | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt | 21 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt | 5 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt | 28 | ||||
-rw-r--r-- | drivers/irqchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-digicolor.c | 120 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-common.c | 18 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-common.h | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 8 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 9 | ||||
-rw-r--r-- | drivers/irqchip/irq-hip04.c | 9 | ||||
-rw-r--r-- | drivers/irqchip/irq-mips-gic.c | 44 | ||||
-rw-r--r-- | drivers/irqchip/irq-mtk-sysirq.c | 18 | ||||
-rw-r--r-- | drivers/irqchip/irq-omap-intc.c | 22 | ||||
-rw-r--r-- | drivers/irqchip/irq-renesas-intc-irqpin.c | 50 | ||||
-rw-r--r-- | include/linux/irqchip/irq-omap-intc.h | 2 | ||||
-rw-r--r-- | kernel/irq/manage.c | 3 |
17 files changed, 296 insertions, 72 deletions
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index 8112d0c3675a..c97484b73e72 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt | |||
@@ -32,12 +32,16 @@ Main node required properties: | |||
32 | The 3rd cell is the flags, encoded as follows: | 32 | The 3rd cell is the flags, encoded as follows: |
33 | bits[3:0] trigger type and level flags. | 33 | bits[3:0] trigger type and level flags. |
34 | 1 = low-to-high edge triggered | 34 | 1 = low-to-high edge triggered |
35 | 2 = high-to-low edge triggered | 35 | 2 = high-to-low edge triggered (invalid for SPIs) |
36 | 4 = active high level-sensitive | 36 | 4 = active high level-sensitive |
37 | 8 = active low level-sensitive | 37 | 8 = active low level-sensitive (invalid for SPIs). |
38 | bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of | 38 | bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of |
39 | the 8 possible cpus attached to the GIC. A bit set to '1' indicated | 39 | the 8 possible cpus attached to the GIC. A bit set to '1' indicated |
40 | the interrupt is wired to that CPU. Only valid for PPI interrupts. | 40 | the interrupt is wired to that CPU. Only valid for PPI interrupts. |
41 | Also note that the configurability of PPI interrupts is IMPLEMENTATION | ||
42 | DEFINED and as such not guaranteed to be present (most SoC available | ||
43 | in 2014 seem to ignore the setting of this flag and use the hardware | ||
44 | default value). | ||
41 | 45 | ||
42 | - reg : Specifies base physical address(s) and size of the GIC registers. The | 46 | - reg : Specifies base physical address(s) and size of the GIC registers. The |
43 | first region is the GIC distributor register base and size. The 2nd region is | 47 | first region is the GIC distributor register base and size. The 2nd region is |
diff --git a/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt new file mode 100644 index 000000000000..42d41ec84c7b --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | Conexant Digicolor Interrupt Controller | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : should be "cnxt,cx92755-ic" | ||
6 | - reg : Specifies base physical address and size of the interrupt controller | ||
7 | registers (IC) area | ||
8 | - interrupt-controller : Identifies the node as an interrupt controller | ||
9 | - #interrupt-cells : Specifies the number of cells needed to encode an | ||
10 | interrupt source. The value shall be 1. | ||
11 | - syscon: A phandle to the syscon node describing UC registers | ||
12 | |||
13 | Example: | ||
14 | |||
15 | intc: interrupt-controller@f0000040 { | ||
16 | compatible = "cnxt,cx92755-ic"; | ||
17 | interrupt-controller; | ||
18 | #interrupt-cells = <1>; | ||
19 | reg = <0xf0000040 0x40>; | ||
20 | syscon = <&uc_regs>; | ||
21 | }; | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt index c73acd060093..4f7946ae8adc 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt | |||
@@ -9,6 +9,11 @@ Required properties: | |||
9 | - "renesas,intc-irqpin-r8a7778" (R-Car M1A) | 9 | - "renesas,intc-irqpin-r8a7778" (R-Car M1A) |
10 | - "renesas,intc-irqpin-r8a7779" (R-Car H1) | 10 | - "renesas,intc-irqpin-r8a7779" (R-Car H1) |
11 | - "renesas,intc-irqpin-sh73a0" (SH-Mobile AG5) | 11 | - "renesas,intc-irqpin-sh73a0" (SH-Mobile AG5) |
12 | |||
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 | ||
15 | addresses, length and number of required register banks varies with soctype. | ||
16 | |||
12 | - #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 |
13 | interrupts.txt in this directory | 18 | interrupts.txt in this directory |
14 | 19 | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt new file mode 100644 index 000000000000..38ce5d037722 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Omap2/3 intc controller | ||
2 | |||
3 | On TI omap2 and 3 the intc interrupt controller can provide | ||
4 | 96 or 128 IRQ signals to the ARM host depending on the SoC. | ||
5 | |||
6 | Required Properties: | ||
7 | - compatible: should be one of | ||
8 | "ti,omap2-intc" | ||
9 | "ti,omap3-intc" | ||
10 | "ti,dm814-intc" | ||
11 | "ti,dm816-intc" | ||
12 | "ti,am33xx-intc" | ||
13 | |||
14 | - interrupt-controller : Identifies the node as an interrupt controller | ||
15 | - #interrupt-cells : Specifies the number of cells needed to encode interrupt | ||
16 | source, should be 1 for intc | ||
17 | - interrupts: interrupt reference to primary interrupt controller | ||
18 | |||
19 | Please refer to interrupts.txt in this directory for details of the common | ||
20 | Interrupt Controllers bindings used by client devices. | ||
21 | |||
22 | Example: | ||
23 | intc: interrupt-controller@48200000 { | ||
24 | compatible = "ti,omap3-intc"; | ||
25 | interrupt-controller; | ||
26 | #interrupt-cells = <1>; | ||
27 | reg = <0x48200000 0x1000>; | ||
28 | }; | ||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 9516a324be6d..42965d2476bb 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -42,3 +42,4 @@ obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o | |||
42 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o | 42 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o |
43 | obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o | 43 | obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o |
44 | obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o | 44 | obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o |
45 | obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o | ||
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c new file mode 100644 index 000000000000..930a2a2fac7f --- /dev/null +++ b/drivers/irqchip/irq-digicolor.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Conexant Digicolor SoCs IRQ chip driver | ||
3 | * | ||
4 | * Author: Baruch Siach <baruch@tkos.co.il> | ||
5 | * | ||
6 | * Copyright (C) 2014 Paradox Innovation Ltd. | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | ||
18 | #include <linux/mfd/syscon.h> | ||
19 | #include <linux/regmap.h> | ||
20 | |||
21 | #include <asm/exception.h> | ||
22 | |||
23 | #include "irqchip.h" | ||
24 | |||
25 | #define UC_IRQ_CONTROL 0x04 | ||
26 | |||
27 | #define IC_FLAG_CLEAR_LO 0x00 | ||
28 | #define IC_FLAG_CLEAR_XLO 0x04 | ||
29 | #define IC_INT0ENABLE_LO 0x10 | ||
30 | #define IC_INT0ENABLE_XLO 0x14 | ||
31 | #define IC_INT0STATUS_LO 0x18 | ||
32 | #define IC_INT0STATUS_XLO 0x1c | ||
33 | |||
34 | static struct irq_domain *digicolor_irq_domain; | ||
35 | |||
36 | static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs) | ||
37 | { | ||
38 | struct irq_domain_chip_generic *dgc = digicolor_irq_domain->gc; | ||
39 | struct irq_chip_generic *gc = dgc->gc[0]; | ||
40 | u32 status, hwirq; | ||
41 | |||
42 | do { | ||
43 | status = irq_reg_readl(gc, IC_INT0STATUS_LO); | ||
44 | if (status) { | ||
45 | hwirq = ffs(status) - 1; | ||
46 | } else { | ||
47 | status = irq_reg_readl(gc, IC_INT0STATUS_XLO); | ||
48 | if (status) | ||
49 | hwirq = ffs(status) - 1 + 32; | ||
50 | else | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | handle_domain_irq(digicolor_irq_domain, hwirq, regs); | ||
55 | } while (1); | ||
56 | } | ||
57 | |||
58 | static void digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, | ||
59 | unsigned en_reg, unsigned ack_reg) | ||
60 | { | ||
61 | struct irq_chip_generic *gc; | ||
62 | |||
63 | gc = irq_get_domain_generic_chip(digicolor_irq_domain, irq_base); | ||
64 | gc->reg_base = reg_base; | ||
65 | gc->chip_types[0].regs.ack = ack_reg; | ||
66 | gc->chip_types[0].regs.mask = en_reg; | ||
67 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; | ||
68 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | ||
69 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | ||
70 | } | ||
71 | |||
72 | static int __init digicolor_of_init(struct device_node *node, | ||
73 | struct device_node *parent) | ||
74 | { | ||
75 | static void __iomem *reg_base; | ||
76 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
77 | struct regmap *ucregs; | ||
78 | int ret; | ||
79 | |||
80 | reg_base = of_iomap(node, 0); | ||
81 | if (!reg_base) { | ||
82 | pr_err("%s: unable to map IC registers\n", node->full_name); | ||
83 | return -ENXIO; | ||
84 | } | ||
85 | |||
86 | /* disable all interrupts */ | ||
87 | writel(0, reg_base + IC_INT0ENABLE_LO); | ||
88 | writel(0, reg_base + IC_INT0ENABLE_XLO); | ||
89 | |||
90 | ucregs = syscon_regmap_lookup_by_phandle(node, "syscon"); | ||
91 | if (IS_ERR(ucregs)) { | ||
92 | pr_err("%s: unable to map UC registers\n", node->full_name); | ||
93 | return PTR_ERR(ucregs); | ||
94 | } | ||
95 | /* channel 1, regular IRQs */ | ||
96 | regmap_write(ucregs, UC_IRQ_CONTROL, 1); | ||
97 | |||
98 | digicolor_irq_domain = | ||
99 | irq_domain_add_linear(node, 64, &irq_generic_chip_ops, NULL); | ||
100 | if (!digicolor_irq_domain) { | ||
101 | pr_err("%s: unable to create IRQ domain\n", node->full_name); | ||
102 | return -ENOMEM; | ||
103 | } | ||
104 | |||
105 | ret = irq_alloc_domain_generic_chips(digicolor_irq_domain, 32, 1, | ||
106 | "digicolor_irq", handle_level_irq, | ||
107 | clr, 0, 0); | ||
108 | if (ret) { | ||
109 | pr_err("%s: unable to allocate IRQ gc\n", node->full_name); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | digicolor_set_gc(reg_base, 0, IC_INT0ENABLE_LO, IC_FLAG_CLEAR_LO); | ||
114 | digicolor_set_gc(reg_base, 32, IC_INT0ENABLE_XLO, IC_FLAG_CLEAR_XLO); | ||
115 | |||
116 | set_handle_irq(digicolor_handle_irq); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | IRQCHIP_DECLARE(conexant_digicolor_ic, "cnxt,cx92755-ic", digicolor_of_init); | ||
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 61541ff24397..ad96ebb0c7ab 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "irq-gic-common.h" | 22 | #include "irq-gic-common.h" |
23 | 23 | ||
24 | void 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); | 27 | u32 enablemask = 1 << (irq % 32); |
@@ -29,16 +29,17 @@ void gic_configure_irq(unsigned int irq, unsigned int type, | |||
29 | u32 confmask = 0x2 << ((irq % 16) * 2); | 29 | u32 confmask = 0x2 << ((irq % 16) * 2); |
30 | u32 confoff = (irq / 16) * 4; | 30 | u32 confoff = (irq / 16) * 4; |
31 | bool enabled = false; | 31 | bool enabled = false; |
32 | u32 val; | 32 | u32 val, oldval; |
33 | int ret = 0; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Read current configuration register, and insert the config | 36 | * Read current configuration register, and insert the config |
36 | * for "irq", depending on "type". | 37 | * for "irq", depending on "type". |
37 | */ | 38 | */ |
38 | val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); | 39 | val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); |
39 | if (type == IRQ_TYPE_LEVEL_HIGH) | 40 | if (type & IRQ_TYPE_LEVEL_MASK) |
40 | val &= ~confmask; | 41 | val &= ~confmask; |
41 | else if (type == IRQ_TYPE_EDGE_RISING) | 42 | else if (type & IRQ_TYPE_EDGE_BOTH) |
42 | val |= confmask; | 43 | val |= confmask; |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -54,15 +55,20 @@ void gic_configure_irq(unsigned int irq, unsigned int type, | |||
54 | 55 | ||
55 | /* | 56 | /* |
56 | * Write back the new configuration, and possibly re-enable | 57 | * Write back the new configuration, and possibly re-enable |
57 | * the interrupt. | 58 | * the interrupt. If we tried to write a new configuration and failed, |
59 | * return an error. | ||
58 | */ | 60 | */ |
59 | writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); | 61 | writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); |
62 | if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval) | ||
63 | ret = -EINVAL; | ||
60 | 64 | ||
61 | if (enabled) | 65 | if (enabled) |
62 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | 66 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); |
63 | 67 | ||
64 | if (sync_access) | 68 | if (sync_access) |
65 | sync_access(); | 69 | sync_access(); |
70 | |||
71 | return ret; | ||
66 | } | 72 | } |
67 | 73 | ||
68 | void __init gic_dist_config(void __iomem *base, int gic_irqs, | 74 | void __init gic_dist_config(void __iomem *base, int gic_irqs, |
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index b41f02481c3a..35a9884778bd 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/irqdomain.h> | 21 | #include <linux/irqdomain.h> |
22 | 22 | ||
23 | void gic_configure_irq(unsigned int irq, unsigned int type, | 23 | int gic_configure_irq(unsigned int irq, unsigned int type, |
24 | void __iomem *base, void (*sync_access)(void)); | 24 | void __iomem *base, void (*sync_access)(void)); |
25 | void gic_dist_config(void __iomem *base, int gic_irqs, | 25 | void gic_dist_config(void __iomem *base, int gic_irqs, |
26 | void (*sync_access)(void)); | 26 | void (*sync_access)(void)); |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 2ab290bec655..1c6dea2fbc34 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -238,7 +238,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
238 | if (irq < 16) | 238 | if (irq < 16) |
239 | return -EINVAL; | 239 | return -EINVAL; |
240 | 240 | ||
241 | if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) | 241 | /* SPIs have restrictions on the supported types */ |
242 | if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && | ||
243 | type != IRQ_TYPE_EDGE_RISING) | ||
242 | return -EINVAL; | 244 | return -EINVAL; |
243 | 245 | ||
244 | if (gic_irq_in_rdist(d)) { | 246 | if (gic_irq_in_rdist(d)) { |
@@ -249,9 +251,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
249 | rwp_wait = gic_dist_wait_for_rwp; | 251 | rwp_wait = gic_dist_wait_for_rwp; |
250 | } | 252 | } |
251 | 253 | ||
252 | gic_configure_irq(irq, type, base, rwp_wait); | 254 | return gic_configure_irq(irq, type, base, rwp_wait); |
253 | |||
254 | return 0; | ||
255 | } | 255 | } |
256 | 256 | ||
257 | static u64 gic_mpidr_to_affinity(u64 mpidr) | 257 | static u64 gic_mpidr_to_affinity(u64 mpidr) |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d617ee5a3d8a..4634cf7d0ec3 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -188,12 +188,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
188 | { | 188 | { |
189 | void __iomem *base = gic_dist_base(d); | 189 | void __iomem *base = gic_dist_base(d); |
190 | unsigned int gicirq = gic_irq(d); | 190 | unsigned int gicirq = gic_irq(d); |
191 | int ret; | ||
191 | 192 | ||
192 | /* Interrupt configuration for SGIs can't be changed */ | 193 | /* Interrupt configuration for SGIs can't be changed */ |
193 | if (gicirq < 16) | 194 | if (gicirq < 16) |
194 | return -EINVAL; | 195 | return -EINVAL; |
195 | 196 | ||
196 | if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) | 197 | /* SPIs have restrictions on the supported types */ |
198 | if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && | ||
199 | type != IRQ_TYPE_EDGE_RISING) | ||
197 | return -EINVAL; | 200 | return -EINVAL; |
198 | 201 | ||
199 | raw_spin_lock(&irq_controller_lock); | 202 | raw_spin_lock(&irq_controller_lock); |
@@ -201,11 +204,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
201 | if (gic_arch_extn.irq_set_type) | 204 | if (gic_arch_extn.irq_set_type) |
202 | gic_arch_extn.irq_set_type(d, type); | 205 | gic_arch_extn.irq_set_type(d, type); |
203 | 206 | ||
204 | gic_configure_irq(gicirq, type, base, NULL); | 207 | ret = gic_configure_irq(gicirq, type, base, NULL); |
205 | 208 | ||
206 | raw_spin_unlock(&irq_controller_lock); | 209 | raw_spin_unlock(&irq_controller_lock); |
207 | 210 | ||
208 | return 0; | 211 | return ret; |
209 | } | 212 | } |
210 | 213 | ||
211 | static int gic_retrigger(struct irq_data *d) | 214 | static int gic_retrigger(struct irq_data *d) |
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 6bc2deb73d53..7d6ffb5de84f 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c | |||
@@ -120,21 +120,24 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type) | |||
120 | { | 120 | { |
121 | void __iomem *base = hip04_dist_base(d); | 121 | void __iomem *base = hip04_dist_base(d); |
122 | unsigned int irq = hip04_irq(d); | 122 | unsigned int irq = hip04_irq(d); |
123 | int ret; | ||
123 | 124 | ||
124 | /* Interrupt configuration for SGIs can't be changed */ | 125 | /* Interrupt configuration for SGIs can't be changed */ |
125 | if (irq < 16) | 126 | if (irq < 16) |
126 | return -EINVAL; | 127 | return -EINVAL; |
127 | 128 | ||
128 | if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) | 129 | /* SPIs have restrictions on the supported types */ |
130 | if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && | ||
131 | type != IRQ_TYPE_EDGE_RISING) | ||
129 | return -EINVAL; | 132 | return -EINVAL; |
130 | 133 | ||
131 | raw_spin_lock(&irq_controller_lock); | 134 | raw_spin_lock(&irq_controller_lock); |
132 | 135 | ||
133 | gic_configure_irq(irq, type, base, NULL); | 136 | ret = gic_configure_irq(irq, type, base, NULL); |
134 | 137 | ||
135 | raw_spin_unlock(&irq_controller_lock); | 138 | raw_spin_unlock(&irq_controller_lock); |
136 | 139 | ||
137 | return 0; | 140 | return ret; |
138 | } | 141 | } |
139 | 142 | ||
140 | #ifdef CONFIG_SMP | 143 | #ifdef CONFIG_SMP |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 56b96c63dc4b..1daa7ca04577 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -235,9 +235,9 @@ int gic_get_c0_perfcount_int(void) | |||
235 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR)); | 235 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR)); |
236 | } | 236 | } |
237 | 237 | ||
238 | static unsigned int gic_get_int(void) | 238 | static void gic_handle_shared_int(void) |
239 | { | 239 | { |
240 | unsigned int i; | 240 | unsigned int i, intr, virq; |
241 | unsigned long *pcpu_mask; | 241 | unsigned long *pcpu_mask; |
242 | unsigned long pending_reg, intrmask_reg; | 242 | unsigned long pending_reg, intrmask_reg; |
243 | DECLARE_BITMAP(pending, GIC_MAX_INTRS); | 243 | DECLARE_BITMAP(pending, GIC_MAX_INTRS); |
@@ -259,7 +259,16 @@ static unsigned int gic_get_int(void) | |||
259 | bitmap_and(pending, pending, intrmask, gic_shared_intrs); | 259 | bitmap_and(pending, pending, intrmask, gic_shared_intrs); |
260 | bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); | 260 | bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); |
261 | 261 | ||
262 | return find_first_bit(pending, gic_shared_intrs); | 262 | intr = find_first_bit(pending, gic_shared_intrs); |
263 | while (intr != gic_shared_intrs) { | ||
264 | virq = irq_linear_revmap(gic_irq_domain, | ||
265 | GIC_SHARED_TO_HWIRQ(intr)); | ||
266 | do_IRQ(virq); | ||
267 | |||
268 | /* go to next pending bit */ | ||
269 | bitmap_clear(pending, intr, 1); | ||
270 | intr = find_first_bit(pending, gic_shared_intrs); | ||
271 | } | ||
263 | } | 272 | } |
264 | 273 | ||
265 | static void gic_mask_irq(struct irq_data *d) | 274 | static void gic_mask_irq(struct irq_data *d) |
@@ -386,16 +395,26 @@ static struct irq_chip gic_edge_irq_controller = { | |||
386 | #endif | 395 | #endif |
387 | }; | 396 | }; |
388 | 397 | ||
389 | static unsigned int gic_get_local_int(void) | 398 | static void gic_handle_local_int(void) |
390 | { | 399 | { |
391 | unsigned long pending, masked; | 400 | unsigned long pending, masked; |
401 | unsigned int intr, virq; | ||
392 | 402 | ||
393 | pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); | 403 | pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); |
394 | masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK)); | 404 | masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK)); |
395 | 405 | ||
396 | bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); | 406 | bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); |
397 | 407 | ||
398 | return find_first_bit(&pending, GIC_NUM_LOCAL_INTRS); | 408 | intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS); |
409 | while (intr != GIC_NUM_LOCAL_INTRS) { | ||
410 | virq = irq_linear_revmap(gic_irq_domain, | ||
411 | GIC_LOCAL_TO_HWIRQ(intr)); | ||
412 | do_IRQ(virq); | ||
413 | |||
414 | /* go to next pending bit */ | ||
415 | bitmap_clear(&pending, intr, 1); | ||
416 | intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS); | ||
417 | } | ||
399 | } | 418 | } |
400 | 419 | ||
401 | static void gic_mask_local_irq(struct irq_data *d) | 420 | static void gic_mask_local_irq(struct irq_data *d) |
@@ -454,19 +473,8 @@ static struct irq_chip gic_all_vpes_local_irq_controller = { | |||
454 | 473 | ||
455 | static void __gic_irq_dispatch(void) | 474 | static void __gic_irq_dispatch(void) |
456 | { | 475 | { |
457 | unsigned int intr, virq; | 476 | gic_handle_local_int(); |
458 | 477 | gic_handle_shared_int(); | |
459 | while ((intr = gic_get_local_int()) != GIC_NUM_LOCAL_INTRS) { | ||
460 | virq = irq_linear_revmap(gic_irq_domain, | ||
461 | GIC_LOCAL_TO_HWIRQ(intr)); | ||
462 | do_IRQ(virq); | ||
463 | } | ||
464 | |||
465 | while ((intr = gic_get_int()) != gic_shared_intrs) { | ||
466 | virq = irq_linear_revmap(gic_irq_domain, | ||
467 | GIC_SHARED_TO_HWIRQ(intr)); | ||
468 | do_IRQ(virq); | ||
469 | } | ||
470 | } | 478 | } |
471 | 479 | ||
472 | static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) | 480 | static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 0b0d2c00a2df..eaf0a710e98a 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include "irqchip.h" | 24 | #include "irqchip.h" |
25 | 25 | ||
26 | #define MT6577_SYS_INTPOL_NUM (224) | ||
27 | |||
28 | struct mtk_sysirq_chip_data { | 26 | struct mtk_sysirq_chip_data { |
29 | spinlock_t lock; | 27 | spinlock_t lock; |
30 | void __iomem *intpol_base; | 28 | void __iomem *intpol_base; |
@@ -124,7 +122,8 @@ static int __init mtk_sysirq_of_init(struct device_node *node, | |||
124 | { | 122 | { |
125 | struct irq_domain *domain, *domain_parent; | 123 | struct irq_domain *domain, *domain_parent; |
126 | struct mtk_sysirq_chip_data *chip_data; | 124 | struct mtk_sysirq_chip_data *chip_data; |
127 | int ret = 0; | 125 | int ret, size, intpol_num; |
126 | struct resource res; | ||
128 | 127 | ||
129 | domain_parent = irq_find_host(parent); | 128 | domain_parent = irq_find_host(parent); |
130 | if (!domain_parent) { | 129 | if (!domain_parent) { |
@@ -132,19 +131,24 @@ static int __init mtk_sysirq_of_init(struct device_node *node, | |||
132 | return -EINVAL; | 131 | return -EINVAL; |
133 | } | 132 | } |
134 | 133 | ||
134 | ret = of_address_to_resource(node, 0, &res); | ||
135 | if (ret) | ||
136 | return ret; | ||
137 | |||
135 | chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); | 138 | chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); |
136 | if (!chip_data) | 139 | if (!chip_data) |
137 | return -ENOMEM; | 140 | return -ENOMEM; |
138 | 141 | ||
139 | chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); | 142 | size = resource_size(&res); |
140 | if (IS_ERR(chip_data->intpol_base)) { | 143 | intpol_num = size * 8; |
144 | chip_data->intpol_base = ioremap(res.start, size); | ||
145 | if (!chip_data->intpol_base) { | ||
141 | pr_err("mtk_sysirq: unable to map sysirq register\n"); | 146 | pr_err("mtk_sysirq: unable to map sysirq register\n"); |
142 | ret = PTR_ERR(chip_data->intpol_base); | 147 | ret = PTR_ERR(chip_data->intpol_base); |
143 | goto out_free; | 148 | goto out_free; |
144 | } | 149 | } |
145 | 150 | ||
146 | domain = irq_domain_add_hierarchy(domain_parent, 0, | 151 | domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node, |
147 | MT6577_SYS_INTPOL_NUM, node, | ||
148 | &sysirq_domain_ops, chip_data); | 152 | &sysirq_domain_ops, chip_data); |
149 | if (!domain) { | 153 | if (!domain) { |
150 | ret = -ENOMEM; | 154 | ret = -ENOMEM; |
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index c03f140acbae..a569c6dbd1d1 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c | |||
@@ -364,14 +364,6 @@ out: | |||
364 | omap_ack_irq(NULL); | 364 | omap_ack_irq(NULL); |
365 | } | 365 | } |
366 | 366 | ||
367 | void __init omap2_init_irq(void) | ||
368 | { | ||
369 | omap_nr_irqs = 96; | ||
370 | omap_nr_pending = 3; | ||
371 | omap_init_irq(OMAP24XX_IC_BASE, NULL); | ||
372 | set_handle_irq(omap_intc_handle_irq); | ||
373 | } | ||
374 | |||
375 | void __init omap3_init_irq(void) | 367 | void __init omap3_init_irq(void) |
376 | { | 368 | { |
377 | omap_nr_irqs = 96; | 369 | omap_nr_irqs = 96; |
@@ -380,14 +372,6 @@ void __init omap3_init_irq(void) | |||
380 | set_handle_irq(omap_intc_handle_irq); | 372 | set_handle_irq(omap_intc_handle_irq); |
381 | } | 373 | } |
382 | 374 | ||
383 | void __init ti81xx_init_irq(void) | ||
384 | { | ||
385 | omap_nr_irqs = 96; | ||
386 | omap_nr_pending = 4; | ||
387 | omap_init_irq(OMAP34XX_IC_BASE, NULL); | ||
388 | set_handle_irq(omap_intc_handle_irq); | ||
389 | } | ||
390 | |||
391 | static int __init intc_of_init(struct device_node *node, | 375 | static int __init intc_of_init(struct device_node *node, |
392 | struct device_node *parent) | 376 | struct device_node *parent) |
393 | { | 377 | { |
@@ -399,7 +383,9 @@ static int __init intc_of_init(struct device_node *node, | |||
399 | if (WARN_ON(!node)) | 383 | if (WARN_ON(!node)) |
400 | return -ENODEV; | 384 | return -ENODEV; |
401 | 385 | ||
402 | if (of_device_is_compatible(node, "ti,am33xx-intc")) { | 386 | if (of_device_is_compatible(node, "ti,dm814-intc") || |
387 | of_device_is_compatible(node, "ti,dm816-intc") || | ||
388 | of_device_is_compatible(node, "ti,am33xx-intc")) { | ||
403 | omap_nr_irqs = 128; | 389 | omap_nr_irqs = 128; |
404 | omap_nr_pending = 4; | 390 | omap_nr_pending = 4; |
405 | } | 391 | } |
@@ -415,4 +401,6 @@ static int __init intc_of_init(struct device_node *node, | |||
415 | 401 | ||
416 | IRQCHIP_DECLARE(omap2_intc, "ti,omap2-intc", intc_of_init); | 402 | IRQCHIP_DECLARE(omap2_intc, "ti,omap2-intc", intc_of_init); |
417 | IRQCHIP_DECLARE(omap3_intc, "ti,omap3-intc", intc_of_init); | 403 | IRQCHIP_DECLARE(omap3_intc, "ti,omap3-intc", intc_of_init); |
404 | IRQCHIP_DECLARE(dm814x_intc, "ti,dm814-intc", intc_of_init); | ||
405 | IRQCHIP_DECLARE(dm816x_intc, "ti,dm816-intc", intc_of_init); | ||
418 | IRQCHIP_DECLARE(am33xx_intc, "ti,am33xx-intc", intc_of_init); | 406 | IRQCHIP_DECLARE(am33xx_intc, "ti,am33xx-intc", intc_of_init); |
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 078cac5e2d08..9a0767b9c89d 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/of_device.h> | ||
33 | #include <linux/platform_data/irq-renesas-intc-irqpin.h> | 34 | #include <linux/platform_data/irq-renesas-intc-irqpin.h> |
34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
35 | 36 | ||
@@ -40,7 +41,9 @@ | |||
40 | #define INTC_IRQPIN_REG_SOURCE 2 /* INTREQnn */ | 41 | #define INTC_IRQPIN_REG_SOURCE 2 /* INTREQnn */ |
41 | #define INTC_IRQPIN_REG_MASK 3 /* INTMSKnn */ | 42 | #define INTC_IRQPIN_REG_MASK 3 /* INTMSKnn */ |
42 | #define INTC_IRQPIN_REG_CLEAR 4 /* INTMSKCLRnn */ | 43 | #define INTC_IRQPIN_REG_CLEAR 4 /* INTMSKCLRnn */ |
43 | #define INTC_IRQPIN_REG_NR 5 | 44 | #define INTC_IRQPIN_REG_NR_MANDATORY 5 |
45 | #define INTC_IRQPIN_REG_IRLM 5 /* ICR0 with IRLM bit (optional) */ | ||
46 | #define INTC_IRQPIN_REG_NR 6 | ||
44 | 47 | ||
45 | /* INTC external IRQ PIN hardware register access: | 48 | /* INTC external IRQ PIN hardware register access: |
46 | * | 49 | * |
@@ -82,6 +85,10 @@ struct intc_irqpin_priv { | |||
82 | u8 shared_irq_mask; | 85 | u8 shared_irq_mask; |
83 | }; | 86 | }; |
84 | 87 | ||
88 | struct intc_irqpin_irlm_config { | ||
89 | unsigned int irlm_bit; | ||
90 | }; | ||
91 | |||
85 | static unsigned long intc_irqpin_read32(void __iomem *iomem) | 92 | static unsigned long intc_irqpin_read32(void __iomem *iomem) |
86 | { | 93 | { |
87 | return ioread32(iomem); | 94 | return ioread32(iomem); |
@@ -345,10 +352,23 @@ static struct irq_domain_ops intc_irqpin_irq_domain_ops = { | |||
345 | .xlate = irq_domain_xlate_twocell, | 352 | .xlate = irq_domain_xlate_twocell, |
346 | }; | 353 | }; |
347 | 354 | ||
355 | static const struct intc_irqpin_irlm_config intc_irqpin_irlm_r8a7779 = { | ||
356 | .irlm_bit = 23, /* ICR0.IRLM0 */ | ||
357 | }; | ||
358 | |||
359 | static const struct of_device_id intc_irqpin_dt_ids[] = { | ||
360 | { .compatible = "renesas,intc-irqpin", }, | ||
361 | { .compatible = "renesas,intc-irqpin-r8a7779", | ||
362 | .data = &intc_irqpin_irlm_r8a7779 }, | ||
363 | {}, | ||
364 | }; | ||
365 | MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); | ||
366 | |||
348 | static int intc_irqpin_probe(struct platform_device *pdev) | 367 | static int intc_irqpin_probe(struct platform_device *pdev) |
349 | { | 368 | { |
350 | struct device *dev = &pdev->dev; | 369 | struct device *dev = &pdev->dev; |
351 | struct renesas_intc_irqpin_config *pdata = dev->platform_data; | 370 | struct renesas_intc_irqpin_config *pdata = dev->platform_data; |
371 | const struct of_device_id *of_id; | ||
352 | struct intc_irqpin_priv *p; | 372 | struct intc_irqpin_priv *p; |
353 | struct intc_irqpin_iomem *i; | 373 | struct intc_irqpin_iomem *i; |
354 | struct resource *io[INTC_IRQPIN_REG_NR]; | 374 | struct resource *io[INTC_IRQPIN_REG_NR]; |
@@ -391,10 +411,11 @@ static int intc_irqpin_probe(struct platform_device *pdev) | |||
391 | pm_runtime_enable(dev); | 411 | pm_runtime_enable(dev); |
392 | pm_runtime_get_sync(dev); | 412 | pm_runtime_get_sync(dev); |
393 | 413 | ||
394 | /* get hold of manadatory IOMEM */ | 414 | /* get hold of register banks */ |
415 | memset(io, 0, sizeof(io)); | ||
395 | for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { | 416 | for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { |
396 | io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k); | 417 | io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k); |
397 | if (!io[k]) { | 418 | if (!io[k] && k < INTC_IRQPIN_REG_NR_MANDATORY) { |
398 | dev_err(dev, "not enough IOMEM resources\n"); | 419 | dev_err(dev, "not enough IOMEM resources\n"); |
399 | ret = -EINVAL; | 420 | ret = -EINVAL; |
400 | goto err0; | 421 | goto err0; |
@@ -422,6 +443,10 @@ static int intc_irqpin_probe(struct platform_device *pdev) | |||
422 | for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { | 443 | for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { |
423 | i = &p->iomem[k]; | 444 | i = &p->iomem[k]; |
424 | 445 | ||
446 | /* handle optional registers */ | ||
447 | if (!io[k]) | ||
448 | continue; | ||
449 | |||
425 | switch (resource_size(io[k])) { | 450 | switch (resource_size(io[k])) { |
426 | case 1: | 451 | case 1: |
427 | i->width = 8; | 452 | i->width = 8; |
@@ -448,6 +473,19 @@ static int intc_irqpin_probe(struct platform_device *pdev) | |||
448 | } | 473 | } |
449 | } | 474 | } |
450 | 475 | ||
476 | /* configure "individual IRQ mode" where needed */ | ||
477 | of_id = of_match_device(intc_irqpin_dt_ids, dev); | ||
478 | if (of_id && of_id->data) { | ||
479 | const struct intc_irqpin_irlm_config *irlm_config = of_id->data; | ||
480 | |||
481 | if (io[INTC_IRQPIN_REG_IRLM]) | ||
482 | intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM, | ||
483 | irlm_config->irlm_bit, | ||
484 | 1, 1); | ||
485 | else | ||
486 | dev_warn(dev, "unable to select IRLM mode\n"); | ||
487 | } | ||
488 | |||
451 | /* mask all interrupts using priority */ | 489 | /* mask all interrupts using priority */ |
452 | for (k = 0; k < p->number_of_irqs; k++) | 490 | for (k = 0; k < p->number_of_irqs; k++) |
453 | intc_irqpin_mask_unmask_prio(p, k, 1); | 491 | intc_irqpin_mask_unmask_prio(p, k, 1); |
@@ -550,12 +588,6 @@ static int intc_irqpin_remove(struct platform_device *pdev) | |||
550 | return 0; | 588 | return 0; |
551 | } | 589 | } |
552 | 590 | ||
553 | static const struct of_device_id intc_irqpin_dt_ids[] = { | ||
554 | { .compatible = "renesas,intc-irqpin", }, | ||
555 | {}, | ||
556 | }; | ||
557 | MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); | ||
558 | |||
559 | static struct platform_driver intc_irqpin_device_driver = { | 591 | static struct platform_driver intc_irqpin_device_driver = { |
560 | .probe = intc_irqpin_probe, | 592 | .probe = intc_irqpin_probe, |
561 | .remove = intc_irqpin_remove, | 593 | .remove = intc_irqpin_remove, |
diff --git a/include/linux/irqchip/irq-omap-intc.h b/include/linux/irqchip/irq-omap-intc.h index e06b370cfc0d..2e3d1afeb674 100644 --- a/include/linux/irqchip/irq-omap-intc.h +++ b/include/linux/irqchip/irq-omap-intc.h | |||
@@ -18,9 +18,7 @@ | |||
18 | #ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H | 18 | #ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H |
19 | #define __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H | 19 | #define __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H |
20 | 20 | ||
21 | void omap2_init_irq(void); | ||
22 | void omap3_init_irq(void); | 21 | void omap3_init_irq(void); |
23 | void ti81xx_init_irq(void); | ||
24 | 22 | ||
25 | int omap_irq_pending(void); | 23 | int omap_irq_pending(void); |
26 | void omap_intc_save_context(void); | 24 | void omap_intc_save_context(void); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 80692373abd6..196a06fbc122 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -243,6 +243,9 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) | |||
243 | return -EINVAL; | 243 | return -EINVAL; |
244 | desc->affinity_hint = m; | 244 | desc->affinity_hint = m; |
245 | irq_put_desc_unlock(desc, flags); | 245 | irq_put_desc_unlock(desc, flags); |
246 | /* set the initial affinity to prevent every interrupt being on CPU0 */ | ||
247 | if (m) | ||
248 | __irq_set_affinity(irq, m, false); | ||
246 | return 0; | 249 | return 0; |
247 | } | 250 | } |
248 | EXPORT_SYMBOL_GPL(irq_set_affinity_hint); | 251 | EXPORT_SYMBOL_GPL(irq_set_affinity_hint); |