Commit 05ff3004 authored by Paul Mundt's avatar Paul Mundt

sh: irq: Teach ipr and intc about dynamically allocating irq_descs.

This hooks in irq_to_desc_alloc_cpu() to the necessary code paths in the
intc and ipr controller registration paths. As these are the primary call
paths for all SH CPUs, this alone will make all CPUs sparse IRQ ready.

There is the added benefit now that each CPU contains specific IPR and
INTC tables, so only the vectors with interrupt sources backing them will
ever see an irq_desc instantiation. This effectively packs irq_desc
down to match the CPU, rather than padding NR_IRQS out to cover the valid
vector range.

Boards with extra sources will still have to fiddle with the nr_irqs
setting, but they can continue doing so through the machvec as before.
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent fa1d43ab
...@@ -59,10 +59,18 @@ void register_ipr_controller(struct ipr_desc *desc) ...@@ -59,10 +59,18 @@ void register_ipr_controller(struct ipr_desc *desc)
for (i = 0; i < desc->nr_irqs; i++) { for (i = 0; i < desc->nr_irqs; i++) {
struct ipr_data *p = desc->ipr_data + i; struct ipr_data *p = desc->ipr_data + i;
struct irq_desc *irq_desc;
BUG_ON(p->ipr_idx >= desc->nr_offsets); BUG_ON(p->ipr_idx >= desc->nr_offsets);
BUG_ON(!desc->ipr_offsets[p->ipr_idx]); BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
irq_desc = irq_to_desc_alloc_cpu(p->irq, smp_processor_id());
if (unlikely(!irq_desc)) {
printk(KERN_INFO "can not get irq_desc for %d\n",
p->irq);
continue;
}
disable_irq_nosync(p->irq); disable_irq_nosync(p->irq);
set_irq_chip_and_handler_name(p->irq, &desc->chip, set_irq_chip_and_handler_name(p->irq, &desc->chip,
handle_level_irq, "level"); handle_level_irq, "level");
......
...@@ -671,7 +671,7 @@ unsigned int intc_evt2irq(unsigned int vector) ...@@ -671,7 +671,7 @@ unsigned int intc_evt2irq(unsigned int vector)
void __init register_intc_controller(struct intc_desc *desc) void __init register_intc_controller(struct intc_desc *desc)
{ {
unsigned int i, k, smp; unsigned int i, k, smp, cpu = smp_processor_id();
struct intc_desc_int *d; struct intc_desc_int *d;
d = alloc_bootmem(sizeof(*d)); d = alloc_bootmem(sizeof(*d));
...@@ -770,11 +770,19 @@ void __init register_intc_controller(struct intc_desc *desc) ...@@ -770,11 +770,19 @@ void __init register_intc_controller(struct intc_desc *desc)
/* register the vectors one by one */ /* register the vectors one by one */
for (i = 0; i < desc->nr_vectors; i++) { for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i; struct intc_vect *vect = desc->vectors + i;
unsigned int irq = evt2irq(vect->vect);
struct irq_desc *irq_desc;
if (!vect->enum_id) if (!vect->enum_id)
continue; continue;
intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); irq_desc = irq_to_desc_alloc_cpu(irq, cpu);
if (unlikely(!irq_desc)) {
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
continue;
}
intc_register_irq(desc, d, vect->enum_id, irq);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment