10509cfdeSRalf Baechle /* 20509cfdeSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public 30509cfdeSRalf Baechle * License. See the file "COPYING" in the main directory of this archive 40509cfdeSRalf Baechle * for more details. 50509cfdeSRalf Baechle * 60509cfdeSRalf Baechle * Code to handle x86 style IRQs plus some generic interrupt stuff. 70509cfdeSRalf Baechle * 80509cfdeSRalf Baechle * Copyright (C) 1992 Linus Torvalds 90509cfdeSRalf Baechle * Copyright (C) 1994 - 2000 Ralf Baechle 100509cfdeSRalf Baechle */ 110509cfdeSRalf Baechle #include <linux/delay.h> 120509cfdeSRalf Baechle #include <linux/init.h> 130509cfdeSRalf Baechle #include <linux/ioport.h> 140509cfdeSRalf Baechle #include <linux/interrupt.h> 150509cfdeSRalf Baechle #include <linux/irqchip.h> 160509cfdeSRalf Baechle #include <linux/irqdomain.h> 170509cfdeSRalf Baechle #include <linux/kernel.h> 180509cfdeSRalf Baechle #include <linux/of_irq.h> 190509cfdeSRalf Baechle #include <linux/spinlock.h> 200509cfdeSRalf Baechle #include <linux/syscore_ops.h> 210509cfdeSRalf Baechle #include <linux/irq.h> 220509cfdeSRalf Baechle 230509cfdeSRalf Baechle #include <asm/i8259.h> 240509cfdeSRalf Baechle #include <asm/io.h> 250509cfdeSRalf Baechle 260509cfdeSRalf Baechle /* 270509cfdeSRalf Baechle * This is the 'legacy' 8259A Programmable Interrupt Controller, 280509cfdeSRalf Baechle * present in the majority of PC/AT boxes. 290509cfdeSRalf Baechle * plus some generic x86 specific things if generic specifics makes 300509cfdeSRalf Baechle * any sense at all. 310509cfdeSRalf Baechle * this file should become arch/i386/kernel/irq.c when the old irq.c 320509cfdeSRalf Baechle * moves to arch independent land 330509cfdeSRalf Baechle */ 340509cfdeSRalf Baechle 350509cfdeSRalf Baechle static int i8259A_auto_eoi = -1; 360509cfdeSRalf Baechle DEFINE_RAW_SPINLOCK(i8259A_lock); 370509cfdeSRalf Baechle static void disable_8259A_irq(struct irq_data *d); 380509cfdeSRalf Baechle static void enable_8259A_irq(struct irq_data *d); 390509cfdeSRalf Baechle static void mask_and_ack_8259A(struct irq_data *d); 400509cfdeSRalf Baechle static void init_8259A(int auto_eoi); 4119afc3d2SPaul Burton static int (*i8259_poll)(void) = i8259_irq; 420509cfdeSRalf Baechle 430509cfdeSRalf Baechle static struct irq_chip i8259A_chip = { 440509cfdeSRalf Baechle .name = "XT-PIC", 450509cfdeSRalf Baechle .irq_mask = disable_8259A_irq, 460509cfdeSRalf Baechle .irq_disable = disable_8259A_irq, 470509cfdeSRalf Baechle .irq_unmask = enable_8259A_irq, 480509cfdeSRalf Baechle .irq_mask_ack = mask_and_ack_8259A, 490509cfdeSRalf Baechle }; 500509cfdeSRalf Baechle 510509cfdeSRalf Baechle /* 520509cfdeSRalf Baechle * 8259A PIC functions to handle ISA devices: 530509cfdeSRalf Baechle */ 540509cfdeSRalf Baechle 5519afc3d2SPaul Burton void i8259_set_poll(int (*poll)(void)) 5619afc3d2SPaul Burton { 5719afc3d2SPaul Burton i8259_poll = poll; 5819afc3d2SPaul Burton } 5919afc3d2SPaul Burton 600509cfdeSRalf Baechle /* 610509cfdeSRalf Baechle * This contains the irq mask for both 8259A irq controllers, 620509cfdeSRalf Baechle */ 630509cfdeSRalf Baechle static unsigned int cached_irq_mask = 0xffff; 640509cfdeSRalf Baechle 650509cfdeSRalf Baechle #define cached_master_mask (cached_irq_mask) 660509cfdeSRalf Baechle #define cached_slave_mask (cached_irq_mask >> 8) 670509cfdeSRalf Baechle 680509cfdeSRalf Baechle static void disable_8259A_irq(struct irq_data *d) 690509cfdeSRalf Baechle { 700509cfdeSRalf Baechle unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; 710509cfdeSRalf Baechle unsigned long flags; 720509cfdeSRalf Baechle 730509cfdeSRalf Baechle mask = 1 << irq; 740509cfdeSRalf Baechle raw_spin_lock_irqsave(&i8259A_lock, flags); 750509cfdeSRalf Baechle cached_irq_mask |= mask; 760509cfdeSRalf Baechle if (irq & 8) 770509cfdeSRalf Baechle outb(cached_slave_mask, PIC_SLAVE_IMR); 780509cfdeSRalf Baechle else 790509cfdeSRalf Baechle outb(cached_master_mask, PIC_MASTER_IMR); 800509cfdeSRalf Baechle raw_spin_unlock_irqrestore(&i8259A_lock, flags); 810509cfdeSRalf Baechle } 820509cfdeSRalf Baechle 830509cfdeSRalf Baechle static void enable_8259A_irq(struct irq_data *d) 840509cfdeSRalf Baechle { 850509cfdeSRalf Baechle unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; 860509cfdeSRalf Baechle unsigned long flags; 870509cfdeSRalf Baechle 880509cfdeSRalf Baechle mask = ~(1 << irq); 890509cfdeSRalf Baechle raw_spin_lock_irqsave(&i8259A_lock, flags); 900509cfdeSRalf Baechle cached_irq_mask &= mask; 910509cfdeSRalf Baechle if (irq & 8) 920509cfdeSRalf Baechle outb(cached_slave_mask, PIC_SLAVE_IMR); 930509cfdeSRalf Baechle else 940509cfdeSRalf Baechle outb(cached_master_mask, PIC_MASTER_IMR); 950509cfdeSRalf Baechle raw_spin_unlock_irqrestore(&i8259A_lock, flags); 960509cfdeSRalf Baechle } 970509cfdeSRalf Baechle 980509cfdeSRalf Baechle void make_8259A_irq(unsigned int irq) 990509cfdeSRalf Baechle { 1000509cfdeSRalf Baechle disable_irq_nosync(irq); 1010509cfdeSRalf Baechle irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); 1020509cfdeSRalf Baechle enable_irq(irq); 1030509cfdeSRalf Baechle } 1040509cfdeSRalf Baechle 1050509cfdeSRalf Baechle /* 1060509cfdeSRalf Baechle * This function assumes to be called rarely. Switching between 1070509cfdeSRalf Baechle * 8259A registers is slow. 1080509cfdeSRalf Baechle * This has to be protected by the irq controller spinlock 1090509cfdeSRalf Baechle * before being called. 1100509cfdeSRalf Baechle */ 1110509cfdeSRalf Baechle static inline int i8259A_irq_real(unsigned int irq) 1120509cfdeSRalf Baechle { 1130509cfdeSRalf Baechle int value; 1140509cfdeSRalf Baechle int irqmask = 1 << irq; 1150509cfdeSRalf Baechle 1160509cfdeSRalf Baechle if (irq < 8) { 1170509cfdeSRalf Baechle outb(0x0B, PIC_MASTER_CMD); /* ISR register */ 1180509cfdeSRalf Baechle value = inb(PIC_MASTER_CMD) & irqmask; 1190509cfdeSRalf Baechle outb(0x0A, PIC_MASTER_CMD); /* back to the IRR register */ 1200509cfdeSRalf Baechle return value; 1210509cfdeSRalf Baechle } 1220509cfdeSRalf Baechle outb(0x0B, PIC_SLAVE_CMD); /* ISR register */ 1230509cfdeSRalf Baechle value = inb(PIC_SLAVE_CMD) & (irqmask >> 8); 1240509cfdeSRalf Baechle outb(0x0A, PIC_SLAVE_CMD); /* back to the IRR register */ 1250509cfdeSRalf Baechle return value; 1260509cfdeSRalf Baechle } 1270509cfdeSRalf Baechle 1280509cfdeSRalf Baechle /* 1290509cfdeSRalf Baechle * Careful! The 8259A is a fragile beast, it pretty 1300509cfdeSRalf Baechle * much _has_ to be done exactly like this (mask it 1310509cfdeSRalf Baechle * first, _then_ send the EOI, and the order of EOI 1320509cfdeSRalf Baechle * to the two 8259s is important! 1330509cfdeSRalf Baechle */ 1340509cfdeSRalf Baechle static void mask_and_ack_8259A(struct irq_data *d) 1350509cfdeSRalf Baechle { 1360509cfdeSRalf Baechle unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE; 1370509cfdeSRalf Baechle unsigned long flags; 1380509cfdeSRalf Baechle 1390509cfdeSRalf Baechle irqmask = 1 << irq; 1400509cfdeSRalf Baechle raw_spin_lock_irqsave(&i8259A_lock, flags); 1410509cfdeSRalf Baechle /* 1420509cfdeSRalf Baechle * Lightweight spurious IRQ detection. We do not want 1430509cfdeSRalf Baechle * to overdo spurious IRQ handling - it's usually a sign 1440509cfdeSRalf Baechle * of hardware problems, so we only do the checks we can 1450509cfdeSRalf Baechle * do without slowing down good hardware unnecessarily. 1460509cfdeSRalf Baechle * 1470509cfdeSRalf Baechle * Note that IRQ7 and IRQ15 (the two spurious IRQs 1480509cfdeSRalf Baechle * usually resulting from the 8259A-1|2 PICs) occur 1490509cfdeSRalf Baechle * even if the IRQ is masked in the 8259A. Thus we 1500509cfdeSRalf Baechle * can check spurious 8259A IRQs without doing the 1510509cfdeSRalf Baechle * quite slow i8259A_irq_real() call for every IRQ. 1520509cfdeSRalf Baechle * This does not cover 100% of spurious interrupts, 1530509cfdeSRalf Baechle * but should be enough to warn the user that there 1540509cfdeSRalf Baechle * is something bad going on ... 1550509cfdeSRalf Baechle */ 1560509cfdeSRalf Baechle if (cached_irq_mask & irqmask) 1570509cfdeSRalf Baechle goto spurious_8259A_irq; 1580509cfdeSRalf Baechle cached_irq_mask |= irqmask; 1590509cfdeSRalf Baechle 1600509cfdeSRalf Baechle handle_real_irq: 1610509cfdeSRalf Baechle if (irq & 8) { 1620509cfdeSRalf Baechle inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */ 1630509cfdeSRalf Baechle outb(cached_slave_mask, PIC_SLAVE_IMR); 1640509cfdeSRalf Baechle outb(0x60+(irq&7), PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ 1650509cfdeSRalf Baechle outb(0x60+PIC_CASCADE_IR, PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ 1660509cfdeSRalf Baechle } else { 1670509cfdeSRalf Baechle inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ 1680509cfdeSRalf Baechle outb(cached_master_mask, PIC_MASTER_IMR); 1690509cfdeSRalf Baechle outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */ 1700509cfdeSRalf Baechle } 1710509cfdeSRalf Baechle raw_spin_unlock_irqrestore(&i8259A_lock, flags); 1720509cfdeSRalf Baechle return; 1730509cfdeSRalf Baechle 1740509cfdeSRalf Baechle spurious_8259A_irq: 1750509cfdeSRalf Baechle /* 1760509cfdeSRalf Baechle * this is the slow path - should happen rarely. 1770509cfdeSRalf Baechle */ 1780509cfdeSRalf Baechle if (i8259A_irq_real(irq)) 1790509cfdeSRalf Baechle /* 1800509cfdeSRalf Baechle * oops, the IRQ _is_ in service according to the 1810509cfdeSRalf Baechle * 8259A - not spurious, go handle it. 1820509cfdeSRalf Baechle */ 1830509cfdeSRalf Baechle goto handle_real_irq; 1840509cfdeSRalf Baechle 1850509cfdeSRalf Baechle { 1860509cfdeSRalf Baechle static int spurious_irq_mask; 1870509cfdeSRalf Baechle /* 1880509cfdeSRalf Baechle * At this point we can be sure the IRQ is spurious, 1890509cfdeSRalf Baechle * lets ACK and report it. [once per IRQ] 1900509cfdeSRalf Baechle */ 1910509cfdeSRalf Baechle if (!(spurious_irq_mask & irqmask)) { 1920509cfdeSRalf Baechle printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq); 1930509cfdeSRalf Baechle spurious_irq_mask |= irqmask; 1940509cfdeSRalf Baechle } 1950509cfdeSRalf Baechle atomic_inc(&irq_err_count); 1960509cfdeSRalf Baechle /* 1970509cfdeSRalf Baechle * Theoretically we do not have to handle this IRQ, 1980509cfdeSRalf Baechle * but in Linux this does not cause problems and is 1990509cfdeSRalf Baechle * simpler for us. 2000509cfdeSRalf Baechle */ 2010509cfdeSRalf Baechle goto handle_real_irq; 2020509cfdeSRalf Baechle } 2030509cfdeSRalf Baechle } 2040509cfdeSRalf Baechle 2050509cfdeSRalf Baechle static void i8259A_resume(void) 2060509cfdeSRalf Baechle { 2070509cfdeSRalf Baechle if (i8259A_auto_eoi >= 0) 2080509cfdeSRalf Baechle init_8259A(i8259A_auto_eoi); 2090509cfdeSRalf Baechle } 2100509cfdeSRalf Baechle 2110509cfdeSRalf Baechle static void i8259A_shutdown(void) 2120509cfdeSRalf Baechle { 2130509cfdeSRalf Baechle /* Put the i8259A into a quiescent state that 2140509cfdeSRalf Baechle * the kernel initialization code can get it 2150509cfdeSRalf Baechle * out of. 2160509cfdeSRalf Baechle */ 2170509cfdeSRalf Baechle if (i8259A_auto_eoi >= 0) { 2180509cfdeSRalf Baechle outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 2190509cfdeSRalf Baechle outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ 2200509cfdeSRalf Baechle } 2210509cfdeSRalf Baechle } 2220509cfdeSRalf Baechle 2230509cfdeSRalf Baechle static struct syscore_ops i8259_syscore_ops = { 2240509cfdeSRalf Baechle .resume = i8259A_resume, 2250509cfdeSRalf Baechle .shutdown = i8259A_shutdown, 2260509cfdeSRalf Baechle }; 2270509cfdeSRalf Baechle 2280509cfdeSRalf Baechle static void init_8259A(int auto_eoi) 2290509cfdeSRalf Baechle { 2300509cfdeSRalf Baechle unsigned long flags; 2310509cfdeSRalf Baechle 2320509cfdeSRalf Baechle i8259A_auto_eoi = auto_eoi; 2330509cfdeSRalf Baechle 2340509cfdeSRalf Baechle raw_spin_lock_irqsave(&i8259A_lock, flags); 2350509cfdeSRalf Baechle 2360509cfdeSRalf Baechle outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 2370509cfdeSRalf Baechle outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ 2380509cfdeSRalf Baechle 2390509cfdeSRalf Baechle /* 2400509cfdeSRalf Baechle * outb_p - this has to work on a wide range of PC hardware. 2410509cfdeSRalf Baechle */ 2420509cfdeSRalf Baechle outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ 2430509cfdeSRalf Baechle outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */ 2440509cfdeSRalf Baechle outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ 2450509cfdeSRalf Baechle if (auto_eoi) /* master does Auto EOI */ 2460509cfdeSRalf Baechle outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); 2470509cfdeSRalf Baechle else /* master expects normal EOI */ 2480509cfdeSRalf Baechle outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); 2490509cfdeSRalf Baechle 2500509cfdeSRalf Baechle outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ 2510509cfdeSRalf Baechle outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */ 2520509cfdeSRalf Baechle outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */ 2530509cfdeSRalf Baechle outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ 2540509cfdeSRalf Baechle if (auto_eoi) 2550509cfdeSRalf Baechle /* 2560509cfdeSRalf Baechle * In AEOI mode we just have to mask the interrupt 2570509cfdeSRalf Baechle * when acking. 2580509cfdeSRalf Baechle */ 2590509cfdeSRalf Baechle i8259A_chip.irq_mask_ack = disable_8259A_irq; 2600509cfdeSRalf Baechle else 2610509cfdeSRalf Baechle i8259A_chip.irq_mask_ack = mask_and_ack_8259A; 2620509cfdeSRalf Baechle 2630509cfdeSRalf Baechle udelay(100); /* wait for 8259A to initialize */ 2640509cfdeSRalf Baechle 2650509cfdeSRalf Baechle outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ 2660509cfdeSRalf Baechle outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ 2670509cfdeSRalf Baechle 2680509cfdeSRalf Baechle raw_spin_unlock_irqrestore(&i8259A_lock, flags); 2690509cfdeSRalf Baechle } 2700509cfdeSRalf Baechle 2710509cfdeSRalf Baechle static struct resource pic1_io_resource = { 2720509cfdeSRalf Baechle .name = "pic1", 2730509cfdeSRalf Baechle .start = PIC_MASTER_CMD, 2740509cfdeSRalf Baechle .end = PIC_MASTER_IMR, 2756a9d42edSBjorn Helgaas .flags = IORESOURCE_IO | IORESOURCE_BUSY 2760509cfdeSRalf Baechle }; 2770509cfdeSRalf Baechle 2780509cfdeSRalf Baechle static struct resource pic2_io_resource = { 2790509cfdeSRalf Baechle .name = "pic2", 2800509cfdeSRalf Baechle .start = PIC_SLAVE_CMD, 2810509cfdeSRalf Baechle .end = PIC_SLAVE_IMR, 2826a9d42edSBjorn Helgaas .flags = IORESOURCE_IO | IORESOURCE_BUSY 2830509cfdeSRalf Baechle }; 2840509cfdeSRalf Baechle 2850509cfdeSRalf Baechle static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq, 2860509cfdeSRalf Baechle irq_hw_number_t hw) 2870509cfdeSRalf Baechle { 2880509cfdeSRalf Baechle irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq); 2890509cfdeSRalf Baechle irq_set_probe(virq); 2900509cfdeSRalf Baechle return 0; 2910509cfdeSRalf Baechle } 2920509cfdeSRalf Baechle 29353ccf331STobias Klauser static const struct irq_domain_ops i8259A_ops = { 2940509cfdeSRalf Baechle .map = i8259A_irq_domain_map, 2950509cfdeSRalf Baechle .xlate = irq_domain_xlate_onecell, 2960509cfdeSRalf Baechle }; 2970509cfdeSRalf Baechle 2980509cfdeSRalf Baechle /* 2990509cfdeSRalf Baechle * On systems with i8259-style interrupt controllers we assume for 3000509cfdeSRalf Baechle * driver compatibility reasons interrupts 0 - 15 to be the i8259 3010509cfdeSRalf Baechle * interrupts even if the hardware uses a different interrupt numbering. 3020509cfdeSRalf Baechle */ 3030509cfdeSRalf Baechle struct irq_domain * __init __init_i8259_irqs(struct device_node *node) 3040509cfdeSRalf Baechle { 3052ef1cb76Safzal mohammed /* 3062ef1cb76Safzal mohammed * PIC_CASCADE_IR is cascade interrupt to second interrupt controller 3072ef1cb76Safzal mohammed */ 3082ef1cb76Safzal mohammed int irq = I8259A_IRQ_BASE + PIC_CASCADE_IR; 3090509cfdeSRalf Baechle struct irq_domain *domain; 3100509cfdeSRalf Baechle 3110509cfdeSRalf Baechle insert_resource(&ioport_resource, &pic1_io_resource); 3120509cfdeSRalf Baechle insert_resource(&ioport_resource, &pic2_io_resource); 3130509cfdeSRalf Baechle 3140509cfdeSRalf Baechle init_8259A(0); 3150509cfdeSRalf Baechle 3160509cfdeSRalf Baechle domain = irq_domain_add_legacy(node, 16, I8259A_IRQ_BASE, 0, 3170509cfdeSRalf Baechle &i8259A_ops, NULL); 3180509cfdeSRalf Baechle if (!domain) 3190509cfdeSRalf Baechle panic("Failed to add i8259 IRQ domain"); 3200509cfdeSRalf Baechle 3212ef1cb76Safzal mohammed if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) 3222ef1cb76Safzal mohammed pr_err("Failed to register cascade interrupt\n"); 323518bfe84SAaro Koskinen register_syscore_ops(&i8259_syscore_ops); 3240509cfdeSRalf Baechle return domain; 3250509cfdeSRalf Baechle } 3260509cfdeSRalf Baechle 3270509cfdeSRalf Baechle void __init init_i8259_irqs(void) 3280509cfdeSRalf Baechle { 3290509cfdeSRalf Baechle __init_i8259_irqs(NULL); 3300509cfdeSRalf Baechle } 3310509cfdeSRalf Baechle 332bd0b9ac4SThomas Gleixner static void i8259_irq_dispatch(struct irq_desc *desc) 3330509cfdeSRalf Baechle { 3344ba37501SThomas Gleixner struct irq_domain *domain = irq_desc_get_handler_data(desc); 33519afc3d2SPaul Burton int hwirq = i8259_poll(); 3364ba37501SThomas Gleixner unsigned int irq; 3370509cfdeSRalf Baechle 3380509cfdeSRalf Baechle if (hwirq < 0) 3390509cfdeSRalf Baechle return; 3400509cfdeSRalf Baechle 3410509cfdeSRalf Baechle irq = irq_linear_revmap(domain, hwirq); 3420509cfdeSRalf Baechle generic_handle_irq(irq); 3430509cfdeSRalf Baechle } 3440509cfdeSRalf Baechle 3450509cfdeSRalf Baechle int __init i8259_of_init(struct device_node *node, struct device_node *parent) 3460509cfdeSRalf Baechle { 3470509cfdeSRalf Baechle struct irq_domain *domain; 3480509cfdeSRalf Baechle unsigned int parent_irq; 3490509cfdeSRalf Baechle 350690803acSPaul Burton domain = __init_i8259_irqs(node); 351690803acSPaul Burton 3520509cfdeSRalf Baechle parent_irq = irq_of_parse_and_map(node, 0); 3530509cfdeSRalf Baechle if (!parent_irq) { 3540509cfdeSRalf Baechle pr_err("Failed to map i8259 parent IRQ\n"); 355690803acSPaul Burton irq_domain_remove(domain); 3560509cfdeSRalf Baechle return -ENODEV; 3570509cfdeSRalf Baechle } 3580509cfdeSRalf Baechle 359a51e80d0SAxel Lin irq_set_chained_handler_and_data(parent_irq, i8259_irq_dispatch, 360a51e80d0SAxel Lin domain); 3610509cfdeSRalf Baechle return 0; 3620509cfdeSRalf Baechle } 3630509cfdeSRalf Baechle IRQCHIP_DECLARE(i8259, "intel,i8259", i8259_of_init); 364