Ticket #21318: 0401-fix-irq-chip-for-exins.patch

File 0401-fix-irq-chip-for-exins.patch, 2.5 KB (added by pgid69, 2 years ago)
  • arch/mips/lantiq/irq.c

    a b  
    126126{ 
    127127        int i; 
    128128 
    129         for (i = 0; i < MAX_EIU; i++) { 
    130                 if (d->hwirq == ltq_eiu_irq[i].start) { 
     129        for (i = 0; i < exin_avail; i++) { 
     130                if (d->irq == ltq_eiu_irq[i].start) { 
    131131                        int val = 0; 
    132132                        int edge = 0; 
    133133 
     
    153153                                val = 6; 
    154154                                break; 
    155155                        default: 
    156                                 pr_err("invalid type %d for irq %ld\n", 
    157                                         type, d->hwirq); 
     156                                pr_err("invalid type %d for irq %u\n", 
     157                                        type, d->irq); 
    158158                                return -EINVAL; 
    159159                        } 
    160160 
    161161                        if (edge) 
    162                                 irq_set_handler(d->hwirq, handle_edge_irq); 
     162                                irq_set_handler(d->irq, handle_edge_irq); 
    163163 
    164164                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | 
    165165                                (val << (i * 4)), LTQ_EIU_EXIN_C); 
     166 
     167                        break; 
    166168                } 
    167169        } 
    168170 
     
    174176        int i; 
    175177 
    176178        ltq_enable_irq(d); 
    177         for (i = 0; i < MAX_EIU; i++) { 
    178                 if (d->hwirq == ltq_eiu_irq[i].start) { 
     179        for (i = 0; i < exin_avail; i++) { 
     180                if (d->irq == ltq_eiu_irq[i].start) { 
    179181                        /* by default we are low level triggered */ 
    180182                        ltq_eiu_settype(d, IRQF_TRIGGER_LOW); 
    181183                        /* clear all pending */ 
     
    196198        int i; 
    197199 
    198200        ltq_disable_irq(d); 
    199         for (i = 0; i < MAX_EIU; i++) { 
    200                 if (d->hwirq == ltq_eiu_irq[i].start) { 
     201        for (i = 0; i < exin_avail; i++) { 
     202                if (d->irq == ltq_eiu_irq[i].start) { 
    201203                        /* disable */ 
    202204                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), 
    203205                                LTQ_EIU_EXIN_INEN); 
     
    341343        if (hw < MIPS_CPU_IRQ_CASCADE) 
    342344                return 0; 
    343345 
    344         for (i = 0; i < exin_avail; i++) 
    345                 if (hw == ltq_eiu_irq[i].start) 
     346        for (i = 0; i < exin_avail; i++) { 
     347                if (irq == ltq_eiu_irq[i].start) { 
    346348                        chip = &ltq_eiu_type; 
     349                        break; 
     350                } 
     351        } 
    347352 
    348         irq_set_chip_and_handler(hw, chip, handle_level_irq); 
     353        irq_set_chip_and_handler(irq, chip, handle_level_irq); 
    349354 
    350355        return 0; 
    351356} 
     
    366371        struct resource res; 
    367372        int i, ret; 
    368373 
     374        exin_avail = 0; 
     375        memset(ltq_eiu_irq, 0, sizeof(ltq_eiu_irq)); 
     376 
    369377        for (i = 0; i < MAX_IM; i++) { 
    370378                if (of_address_to_resource(node, i, &res)) 
    371379                        panic("Failed to get icu memory range"); 
     
    450458                if (ret != exin_avail) 
    451459                        panic("failed to load external irq resources"); 
    452460 
     461                /* 
     462                 * FIX : 
     463                 * If icu_map() is called during execution of function 
     464                 * of_irq_to_resource_table() above, as ltq_eiu_irq[] is not set, 
     465                 * icu_map() calls irq_set_chip_and_handler() with wrong chip. 
     466                 * We set the correct chip now. 
     467                */ 
     468                for (i = 0; (i < exin_avail); i += 1) { 
     469                        irq_set_chip(ltq_eiu_irq[i].start, &ltq_eiu_type); 
     470                } 
     471 
    453472                if (request_mem_region(res.start, resource_size(&res), 
    454473                                                        res.name) < 0) 
    455474                        pr_err("Failed to request eiu memory");