diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c index 102bf56befb41f394eeebf500d1fa1a953ed4bf3..21f1bb67248e10b28f974c0f1334089cc355f89d 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 = { &m66592_usb_peripheral_device, }; +static void __init x3proto_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRL3210); + + /* Set ICR0.LVLMODE */ + __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); +} + static int __init x3proto_devices_setup(void) { + /* + * IRLs are only needed for ILSEL mappings, so flip over the INTC + * pins at a later point to enable the GPIOs to settle. + */ + x3proto_init_irq(); + r8a66597_usb_host_resources[1].start = r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I); @@ -145,14 +159,6 @@ static int __init x3proto_devices_setup(void) } device_initcall(x3proto_devices_setup); -static void __init x3proto_init_irq(void) -{ - plat_irq_setup_pins(IRQ_MODE_IRL3210); - - /* Set ICR0.LVLMODE */ - __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); -} - static void __init x3proto_setup(char **cmdline_p) { register_smp_ops(&shx3_smp_ops); @@ -161,5 +167,4 @@ static void __init x3proto_setup(char **cmdline_p) static struct sh_machine_vector mv_x3proto __initmv = { .mv_name = "x3proto", .mv_setup = x3proto_setup, - .mv_init_irq = x3proto_init_irq, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index f159ea2cebc712a3343c261aab1fd20d2bdcab77..013f0b1444896f434cb8af60914d68a26d0e964c 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) void __init plat_irq_setup(void) { + reserve_intc_vectors(vectors_irq, ARRAY_SIZE(vectors_irq)); + reserve_intc_vectors(vectors_irl, ARRAY_SIZE(vectors_irl)); + register_intc_controller(&intc_desc); } diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index e91a23e5ffd8ad874a8f2e8c6615b5e181a54f8c..4e01d65e5edb36d8581ce6d5fdec8ced1be87d00 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -1377,6 +1377,17 @@ int reserve_irq_vector(unsigned int irq) return ret; } +void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&vector_lock, flags); + for (i = 0; i < nr_vecs; i++) + __set_bit(evt2irq(vectors[i].vect), intc_irq_map); + spin_unlock_irqrestore(&vector_lock, flags); +} + void reserve_irq_legacy(void) { unsigned long flags; diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index 0d6cd38e673ddb2486711517047a3c7fd544ad14..bff2f286ca61105f18745d752b64876b875c977d 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -106,6 +106,7 @@ struct intc_desc symbol __initdata = { \ } int __init register_intc_controller(struct intc_desc *desc); +void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs); int intc_set_priority(unsigned int irq, unsigned int prio); #ifdef CONFIG_INTC_USERIMASK