X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fparisc%2Fgsc.c;h=16d40f95978d135d8cf310efff612094c1e6d451;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=17960846935edbc0be158c7af75f04820bc24102;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index 179608469..16d40f959 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -38,14 +38,14 @@ int gsc_alloc_irq(struct gsc_irq *i) { - int irq = txn_alloc_irq(); + int irq = txn_alloc_irq(GSC_EIM_WIDTH); if (irq < 0) { printk("cannot get irq\n"); return irq; } i->txn_addr = txn_alloc_addr(irq); - i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH); + i->txn_data = txn_alloc_data(irq); i->irq = irq; return irq; @@ -64,7 +64,7 @@ int gsc_claim_irq(struct gsc_irq *i, int irq) } i->txn_addr = txn_alloc_addr(irq); - i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH); + i->txn_data = txn_alloc_data(irq); i->irq = irq; return irq; @@ -171,20 +171,32 @@ int gsc_assign_irq(struct hw_interrupt_type *type, void *data) void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) { - int irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic); - if (irq == NO_IRQ) - return; - + int irq = asic->global_irq[local_irq]; + + if (irq <= 0) { + irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic); + if (irq == NO_IRQ) + return; + + asic->global_irq[local_irq] = irq; + } *irqp = irq; - asic->global_irq[local_irq] = irq; +} + +static struct device *next_device(struct klist_iter *i) +{ + struct klist_node * n = klist_next(i); + return n ? container_of(n, struct device, knode_parent) : NULL; } void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, void (*choose_irq)(struct parisc_device *, void *)) { struct device *dev; + struct klist_iter i; - list_for_each_entry(dev, &parent->dev.children, node) { + klist_iter_init(&parent->dev.klist_children, &i); + while ((dev = next_device(&i))) { struct parisc_device *padev = to_parisc_device(dev); /* work-around for 715/64 and others which have parent @@ -193,14 +205,21 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, return gsc_fixup_irqs(padev, ctrl, choose_irq); choose_irq(padev, ctrl); } + klist_iter_exit(&i); } int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) { struct resource *res; + int i; gsc_asic->gsc = parent; + /* Initialise local irq -> global irq mapping */ + for (i = 0; i < 32; i++) { + gsc_asic->global_irq[i] = NO_IRQ; + } + /* allocate resource region */ res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name); if (res) {