Commit | Line | Data |
---|---|---|
4dc9783e GL |
1 | /* |
2 | * Interrupt controller driver for Xilinx Virtex FPGAs | |
3 | * | |
4 | * Copyright (C) 2007 Secret Lab Technologies Ltd. | |
5 | * | |
6 | * This file is licensed under the terms of the GNU General Public License | |
7 | * version 2. This program is licensed "as is" without any warranty of any | |
8 | * kind, whether express or implied. | |
9 | * | |
10 | */ | |
11 | ||
12 | /* | |
13 | * This is a driver for the interrupt controller typically found in | |
14 | * Xilinx Virtex FPGA designs. | |
15 | * | |
16 | * The interrupt sense levels are hard coded into the FPGA design with | |
17 | * typically a 1:1 relationship between irq lines and devices (no shared | |
18 | * irq lines). Therefore, this driver does not attempt to handle edge | |
19 | * and level interrupts differently. | |
20 | */ | |
21 | #undef DEBUG | |
22 | ||
23 | #include <linux/kernel.h> | |
24 | #include <linux/irq.h> | |
25 | #include <linux/of.h> | |
26a2056e | 26 | #include <linux/of_address.h> |
c11eede6 | 27 | #include <linux/of_irq.h> |
4dc9783e GL |
28 | #include <asm/io.h> |
29 | #include <asm/processor.h> | |
1745fbc7 | 30 | #include <asm/i8259.h> |
4dc9783e | 31 | #include <asm/irq.h> |
8328255f | 32 | #include <linux/irqchip.h> |
4dc9783e | 33 | |
1745fbc7 GL |
34 | #if defined(CONFIG_PPC_I8259) |
35 | /* | |
36 | * Support code for cascading to 8259 interrupt controllers | |
37 | */ | |
bd0b9ac4 | 38 | static void xilinx_i8259_cascade(struct irq_desc *desc) |
1745fbc7 | 39 | { |
ec775d0e | 40 | struct irq_chip *chip = irq_desc_get_chip(desc); |
1745fbc7 | 41 | unsigned int cascade_irq = i8259_irq(); |
73909af7 | 42 | |
1745fbc7 GL |
43 | if (cascade_irq) |
44 | generic_handle_irq(cascade_irq); | |
45 | ||
46 | /* Let xilinx_intc end the interrupt */ | |
73909af7 | 47 | chip->irq_unmask(&desc->irq_data); |
1745fbc7 GL |
48 | } |
49 | ||
50 | static void __init xilinx_i8259_setup_cascade(void) | |
51 | { | |
52 | struct device_node *cascade_node; | |
53 | int cascade_irq; | |
54 | ||
55 | /* Initialize i8259 controller */ | |
56 | cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic"); | |
57 | if (!cascade_node) | |
58 | return; | |
59 | ||
60 | cascade_irq = irq_of_parse_and_map(cascade_node, 0); | |
61 | if (!cascade_irq) { | |
62 | pr_err("virtex_ml510: Failed to map cascade interrupt\n"); | |
63 | goto out; | |
64 | } | |
65 | ||
66 | i8259_init(cascade_node, 0); | |
ec775d0e | 67 | irq_set_chained_handler(cascade_irq, xilinx_i8259_cascade); |
1745fbc7 | 68 | |
e52ba9c5 RC |
69 | /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */ |
70 | /* This looks like a dirty hack to me --gcl */ | |
71 | outb(0xc0, 0x4d0); | |
72 | outb(0xc0, 0x4d1); | |
73 | ||
1745fbc7 GL |
74 | out: |
75 | of_node_put(cascade_node); | |
76 | } | |
77 | #else | |
78 | static inline void xilinx_i8259_setup_cascade(void) { return; } | |
79 | #endif /* defined(CONFIG_PPC_I8259) */ | |
80 | ||
1745fbc7 GL |
81 | /* |
82 | * Initialize master Xilinx interrupt controller | |
83 | */ | |
4dc9783e GL |
84 | void __init xilinx_intc_init_tree(void) |
85 | { | |
8328255f | 86 | irqchip_init(); |
1745fbc7 | 87 | xilinx_i8259_setup_cascade(); |
4dc9783e | 88 | } |