diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 7aa89fac1f81..e1913f28f418 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -263,6 +263,12 @@ void __init init_IRQ(void) { plat_irq_setup(); + /* + * Pin any of the legacy IRQ vectors that haven't already been + * grabbed by the platform + */ + reserve_irq_legacy(); + /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq) sh_mv.mv_init_irq(); diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 4789df43c0f9..a7e5c2e9986c 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -928,3 +928,28 @@ void destroy_irq(unsigned int irq) __clear_bit(irq, intc_irq_map); spin_unlock_irqrestore(&vector_lock, flags); } + +int reserve_irq_vector(unsigned int irq) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&vector_lock, flags); + if (test_and_set_bit(irq, intc_irq_map)) + ret = -EBUSY; + spin_unlock_irqrestore(&vector_lock, flags); + + return ret; +} + +void reserve_irq_legacy(void) +{ + unsigned long flags; + int i, j; + + spin_lock_irqsave(&vector_lock, flags); + j = find_first_bit(intc_irq_map, nr_irqs); + for (i = 0; i < j; i++) + __set_bit(i, intc_irq_map); + spin_unlock_irqrestore(&vector_lock, flags); +} diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index 4e4b22d50164..4ef246f14654 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -84,4 +84,7 @@ struct intc_desc symbol __initdata = { \ void __init register_intc_controller(struct intc_desc *desc); int intc_set_priority(unsigned int irq, unsigned int prio); +int reserve_irq_vector(unsigned int irq); +void reserve_irq_legacy(void); + #endif /* __SH_INTC_H */