Commit 4bacd796ccd6976b03dd490708a1abc291d5521e
1 parent
742759eae6
Exists in
master
and in
4 other branches
sh: Support early IRQ vector map reservation for delayed controllers.
Some controllers will need to be initialized lazily due to pinmux constraints, while others may simply have no need to be brought online if there are no backing devices for them attached. In this case it's still necessary to be able to reserve their hardware vector map before dynamic IRQs get a hold of them. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Showing 4 changed files with 29 additions and 9 deletions Side-by-side Diff
arch/sh/boards/mach-x3proto/setup.c
... | ... | @@ -129,8 +129,22 @@ |
129 | 129 | &m66592_usb_peripheral_device, |
130 | 130 | }; |
131 | 131 | |
132 | +static void __init x3proto_init_irq(void) | |
133 | +{ | |
134 | + plat_irq_setup_pins(IRQ_MODE_IRL3210); | |
135 | + | |
136 | + /* Set ICR0.LVLMODE */ | |
137 | + __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); | |
138 | +} | |
139 | + | |
132 | 140 | static int __init x3proto_devices_setup(void) |
133 | 141 | { |
142 | + /* | |
143 | + * IRLs are only needed for ILSEL mappings, so flip over the INTC | |
144 | + * pins at a later point to enable the GPIOs to settle. | |
145 | + */ | |
146 | + x3proto_init_irq(); | |
147 | + | |
134 | 148 | r8a66597_usb_host_resources[1].start = |
135 | 149 | r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I); |
136 | 150 | |
... | ... | @@ -145,14 +159,6 @@ |
145 | 159 | } |
146 | 160 | device_initcall(x3proto_devices_setup); |
147 | 161 | |
148 | -static void __init x3proto_init_irq(void) | |
149 | -{ | |
150 | - plat_irq_setup_pins(IRQ_MODE_IRL3210); | |
151 | - | |
152 | - /* Set ICR0.LVLMODE */ | |
153 | - __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); | |
154 | -} | |
155 | - | |
156 | 162 | static void __init x3proto_setup(char **cmdline_p) |
157 | 163 | { |
158 | 164 | register_smp_ops(&shx3_smp_ops); |
... | ... | @@ -161,6 +167,5 @@ |
161 | 167 | static struct sh_machine_vector mv_x3proto __initmv = { |
162 | 168 | .mv_name = "x3proto", |
163 | 169 | .mv_setup = x3proto_setup, |
164 | - .mv_init_irq = x3proto_init_irq, | |
165 | 170 | }; |
arch/sh/kernel/cpu/sh4a/setup-shx3.c
drivers/sh/intc.c
... | ... | @@ -1377,6 +1377,17 @@ |
1377 | 1377 | return ret; |
1378 | 1378 | } |
1379 | 1379 | |
1380 | +void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) | |
1381 | +{ | |
1382 | + unsigned long flags; | |
1383 | + int i; | |
1384 | + | |
1385 | + spin_lock_irqsave(&vector_lock, flags); | |
1386 | + for (i = 0; i < nr_vecs; i++) | |
1387 | + __set_bit(evt2irq(vectors[i].vect), intc_irq_map); | |
1388 | + spin_unlock_irqrestore(&vector_lock, flags); | |
1389 | +} | |
1390 | + | |
1380 | 1391 | void reserve_irq_legacy(void) |
1381 | 1392 | { |
1382 | 1393 | unsigned long flags; |
include/linux/sh_intc.h
... | ... | @@ -106,6 +106,7 @@ |
106 | 106 | } |
107 | 107 | |
108 | 108 | int __init register_intc_controller(struct intc_desc *desc); |
109 | +void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs); | |
109 | 110 | int intc_set_priority(unsigned int irq, unsigned int prio); |
110 | 111 | |
111 | 112 | #ifdef CONFIG_INTC_USERIMASK |