Commit 4bacd796ccd6976b03dd490708a1abc291d5521e

Authored by Paul Mundt
1 parent 742759eae6

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
... ... @@ -478,6 +478,9 @@
478 478  
479 479 void __init plat_irq_setup(void)
480 480 {
  481 + reserve_intc_vectors(vectors_irq, ARRAY_SIZE(vectors_irq));
  482 + reserve_intc_vectors(vectors_irl, ARRAY_SIZE(vectors_irl));
  483 +
481 484 register_intc_controller(&intc_desc);
482 485 }
483 486  
... ... @@ -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