aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-10-02 09:02:07 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-10-02 09:02:07 -0400
commit4bacd796ccd6976b03dd490708a1abc291d5521e (patch)
tree0c0c1d242940e9fdf83952a821a20e2bdcdf0927
parent742759eae6b58a172d8f79ff0938d1e25dc9abc5 (diff)
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>
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c23
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c3
-rw-r--r--drivers/sh/intc.c11
-rw-r--r--include/linux/sh_intc.h1
4 files changed, 29 insertions, 9 deletions
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 102bf56befb4..21f1bb67248e 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -129,8 +129,22 @@ static struct platform_device *x3proto_devices[] __initdata = {
129 &m66592_usb_peripheral_device, 129 &m66592_usb_peripheral_device,
130}; 130};
131 131
132static 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
132static int __init x3proto_devices_setup(void) 140static 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 r8a66597_usb_host_resources[1].start = 148 r8a66597_usb_host_resources[1].start =
135 r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I); 149 r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
136 150
@@ -145,14 +159,6 @@ static int __init x3proto_devices_setup(void)
145} 159}
146device_initcall(x3proto_devices_setup); 160device_initcall(x3proto_devices_setup);
147 161
148static 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
156static void __init x3proto_setup(char **cmdline_p) 162static void __init x3proto_setup(char **cmdline_p)
157{ 163{
158 register_smp_ops(&shx3_smp_ops); 164 register_smp_ops(&shx3_smp_ops);
@@ -161,5 +167,4 @@ static void __init x3proto_setup(char **cmdline_p)
161static struct sh_machine_vector mv_x3proto __initmv = { 167static struct sh_machine_vector mv_x3proto __initmv = {
162 .mv_name = "x3proto", 168 .mv_name = "x3proto",
163 .mv_setup = x3proto_setup, 169 .mv_setup = x3proto_setup,
164 .mv_init_irq = x3proto_init_irq,
165}; 170};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index f159ea2cebc7..013f0b144489 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -478,6 +478,9 @@ void __init plat_irq_setup_pins(int mode)
478 478
479void __init plat_irq_setup(void) 479void __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 register_intc_controller(&intc_desc); 484 register_intc_controller(&intc_desc);
482} 485}
483 486
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index e91a23e5ffd8..4e01d65e5edb 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -1377,6 +1377,17 @@ int reserve_irq_vector(unsigned int irq)
1377 return ret; 1377 return ret;
1378} 1378}
1379 1379
1380void 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
1380void reserve_irq_legacy(void) 1391void reserve_irq_legacy(void)
1381{ 1392{
1382 unsigned long flags; 1393 unsigned long flags;
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index 0d6cd38e673d..bff2f286ca61 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -106,6 +106,7 @@ struct intc_desc symbol __initdata = { \
106} 106}
107 107
108int __init register_intc_controller(struct intc_desc *desc); 108int __init register_intc_controller(struct intc_desc *desc);
109void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs);
109int intc_set_priority(unsigned int irq, unsigned int prio); 110int intc_set_priority(unsigned int irq, unsigned int prio);
110 111
111#ifdef CONFIG_INTC_USERIMASK 112#ifdef CONFIG_INTC_USERIMASK