1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2008 Freescale Semiconductor, Inc. 4 */ 5 6 #include <linux/stddef.h> 7 #include <linux/kernel.h> 8 #include <linux/interrupt.h> 9 #include <linux/of_irq.h> 10 #include <linux/of_platform.h> 11 12 #include <asm/mpic.h> 13 #include <asm/i8259.h> 14 15 #ifdef CONFIG_PPC_I8259 16 static void mpc86xx_8259_cascade(struct irq_desc *desc) 17 { 18 struct irq_chip *chip = irq_desc_get_chip(desc); 19 unsigned int cascade_irq = i8259_irq(); 20 21 if (cascade_irq) 22 generic_handle_irq(cascade_irq); 23 24 chip->irq_eoi(&desc->irq_data); 25 } 26 #endif /* CONFIG_PPC_I8259 */ 27 28 void __init mpc86xx_init_irq(void) 29 { 30 #ifdef CONFIG_PPC_I8259 31 struct device_node *np; 32 struct device_node *cascade_node = NULL; 33 int cascade_irq; 34 #endif 35 36 struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | 37 MPIC_SINGLE_DEST_CPU, 38 0, 256, " MPIC "); 39 BUG_ON(mpic == NULL); 40 41 mpic_init(mpic); 42 43 #ifdef CONFIG_PPC_I8259 44 /* Initialize i8259 controller */ 45 for_each_node_by_type(np, "interrupt-controller") 46 if (of_device_is_compatible(np, "chrp,iic")) { 47 cascade_node = np; 48 break; 49 } 50 51 if (cascade_node == NULL) { 52 printk(KERN_DEBUG "Could not find i8259 PIC\n"); 53 return; 54 } 55 56 cascade_irq = irq_of_parse_and_map(cascade_node, 0); 57 if (!cascade_irq) { 58 printk(KERN_ERR "Failed to map cascade interrupt\n"); 59 return; 60 } 61 62 i8259_init(cascade_node, 0); 63 of_node_put(cascade_node); 64 65 irq_set_chained_handler(cascade_irq, mpc86xx_8259_cascade); 66 #endif 67 } 68