diff options
author | Martyn Welch <martyn.welch@ge.com> | 2012-03-12 13:12:59 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2012-03-16 12:08:11 -0400 |
commit | 44b24b74abc37e3c0f28c8288178056f10074863 (patch) | |
tree | ea882b1d7aade665ffe54bb335502cba2985ee54 /arch/powerpc/platforms/86xx | |
parent | 6518bb69f463446a1552f52093cc699497f18fe0 (diff) |
powerpc: Move GE PIC drivers
Move the GE PIC drivers to allow these to be used by non-86xx boards.
Signed-off-by: Martyn Welch <martyn.welch@ge.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/86xx')
-rw-r--r-- | arch/powerpc/platforms/86xx/Kconfig | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/gef_pic.c | 252 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/gef_pic.h | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/gef_ppc9a.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/gef_sbc310.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/gef_sbc610.c | 2 |
7 files changed, 3 insertions, 271 deletions
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index abe2c4fff811..7a6279e38213 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -64,10 +64,6 @@ config GEF_SBC610 | |||
64 | help | 64 | help |
65 | This option enables support for the GE SBC610. | 65 | This option enables support for the GE SBC610. |
66 | 66 | ||
67 | config GE_FPGA | ||
68 | bool | ||
69 | default n | ||
70 | |||
71 | endif | 67 | endif |
72 | 68 | ||
73 | config MPC8641 | 69 | config MPC8641 |
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 1ee6ca8e53f7..ede815d6489d 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile | |||
@@ -7,7 +7,6 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o | |||
7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | 7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o |
8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o | 8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o |
9 | obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o | 9 | obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o |
10 | obj-$(CONFIG_GE_FPGA) += gef_pic.o | ||
11 | obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o | 10 | obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o |
12 | obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o | 11 | obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o |
13 | obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o | 12 | obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o |
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c deleted file mode 100644 index 94594e58594c..000000000000 --- a/arch/powerpc/platforms/86xx/gef_pic.c +++ /dev/null | |||
@@ -1,252 +0,0 @@ | |||
1 | /* | ||
2 | * Interrupt handling for GE FPGA based PIC | ||
3 | * | ||
4 | * Author: Martyn Welch <martyn.welch@ge.com> | ||
5 | * | ||
6 | * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/stddef.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | |||
20 | #include <asm/byteorder.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/prom.h> | ||
23 | #include <asm/irq.h> | ||
24 | |||
25 | #include "gef_pic.h" | ||
26 | |||
27 | #define DEBUG | ||
28 | #undef DEBUG | ||
29 | |||
30 | #ifdef DEBUG | ||
31 | #define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0) | ||
32 | #else | ||
33 | #define DBG(fmt...) do { } while (0) | ||
34 | #endif | ||
35 | |||
36 | #define GEF_PIC_NUM_IRQS 32 | ||
37 | |||
38 | /* Interrupt Controller Interface Registers */ | ||
39 | #define GEF_PIC_INTR_STATUS 0x0000 | ||
40 | |||
41 | #define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu)) | ||
42 | #define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0) | ||
43 | #define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1) | ||
44 | |||
45 | #define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu)) | ||
46 | #define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0) | ||
47 | #define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1) | ||
48 | |||
49 | |||
50 | static DEFINE_RAW_SPINLOCK(gef_pic_lock); | ||
51 | |||
52 | static void __iomem *gef_pic_irq_reg_base; | ||
53 | static struct irq_host *gef_pic_irq_host; | ||
54 | static int gef_pic_cascade_irq; | ||
55 | |||
56 | /* | ||
57 | * Interrupt Controller Handling | ||
58 | * | ||
59 | * The interrupt controller handles interrupts for most on board interrupts, | ||
60 | * apart from PCI interrupts. For example on SBC610: | ||
61 | * | ||
62 | * 17:31 RO Reserved | ||
63 | * 16 RO PCI Express Doorbell 3 Status | ||
64 | * 15 RO PCI Express Doorbell 2 Status | ||
65 | * 14 RO PCI Express Doorbell 1 Status | ||
66 | * 13 RO PCI Express Doorbell 0 Status | ||
67 | * 12 RO Real Time Clock Interrupt Status | ||
68 | * 11 RO Temperature Interrupt Status | ||
69 | * 10 RO Temperature Critical Interrupt Status | ||
70 | * 9 RO Ethernet PHY1 Interrupt Status | ||
71 | * 8 RO Ethernet PHY3 Interrupt Status | ||
72 | * 7 RO PEX8548 Interrupt Status | ||
73 | * 6 RO Reserved | ||
74 | * 5 RO Watchdog 0 Interrupt Status | ||
75 | * 4 RO Watchdog 1 Interrupt Status | ||
76 | * 3 RO AXIS Message FIFO A Interrupt Status | ||
77 | * 2 RO AXIS Message FIFO B Interrupt Status | ||
78 | * 1 RO AXIS Message FIFO C Interrupt Status | ||
79 | * 0 RO AXIS Message FIFO D Interrupt Status | ||
80 | * | ||
81 | * Interrupts can be forwarded to one of two output lines. Nothing | ||
82 | * clever is done, so if the masks are incorrectly set, a single input | ||
83 | * interrupt could generate interrupts on both output lines! | ||
84 | * | ||
85 | * The dual lines are there to allow the chained interrupts to be easily | ||
86 | * passed into two different cores. We currently do not use this functionality | ||
87 | * in this driver. | ||
88 | * | ||
89 | * Controller can also be configured to generate Machine checks (MCP), again on | ||
90 | * two lines, to be attached to two different cores. It is suggested that these | ||
91 | * should be masked out. | ||
92 | */ | ||
93 | |||
94 | void gef_pic_cascade(unsigned int irq, struct irq_desc *desc) | ||
95 | { | ||
96 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
97 | unsigned int cascade_irq; | ||
98 | |||
99 | /* | ||
100 | * See if we actually have an interrupt, call generic handling code if | ||
101 | * we do. | ||
102 | */ | ||
103 | cascade_irq = gef_pic_get_irq(); | ||
104 | |||
105 | if (cascade_irq != NO_IRQ) | ||
106 | generic_handle_irq(cascade_irq); | ||
107 | |||
108 | chip->irq_eoi(&desc->irq_data); | ||
109 | } | ||
110 | |||
111 | static void gef_pic_mask(struct irq_data *d) | ||
112 | { | ||
113 | unsigned long flags; | ||
114 | unsigned int hwirq = irqd_to_hwirq(d); | ||
115 | u32 mask; | ||
116 | |||
117 | raw_spin_lock_irqsave(&gef_pic_lock, flags); | ||
118 | mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); | ||
119 | mask &= ~(1 << hwirq); | ||
120 | out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); | ||
121 | raw_spin_unlock_irqrestore(&gef_pic_lock, flags); | ||
122 | } | ||
123 | |||
124 | static void gef_pic_mask_ack(struct irq_data *d) | ||
125 | { | ||
126 | /* Don't think we actually have to do anything to ack an interrupt, | ||
127 | * we just need to clear down the devices interrupt and it will go away | ||
128 | */ | ||
129 | gef_pic_mask(d); | ||
130 | } | ||
131 | |||
132 | static void gef_pic_unmask(struct irq_data *d) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | unsigned int hwirq = irqd_to_hwirq(d); | ||
136 | u32 mask; | ||
137 | |||
138 | raw_spin_lock_irqsave(&gef_pic_lock, flags); | ||
139 | mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); | ||
140 | mask |= (1 << hwirq); | ||
141 | out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); | ||
142 | raw_spin_unlock_irqrestore(&gef_pic_lock, flags); | ||
143 | } | ||
144 | |||
145 | static struct irq_chip gef_pic_chip = { | ||
146 | .name = "gefp", | ||
147 | .irq_mask = gef_pic_mask, | ||
148 | .irq_mask_ack = gef_pic_mask_ack, | ||
149 | .irq_unmask = gef_pic_unmask, | ||
150 | }; | ||
151 | |||
152 | |||
153 | /* When an interrupt is being configured, this call allows some flexibilty | ||
154 | * in deciding which irq_chip structure is used | ||
155 | */ | ||
156 | static int gef_pic_host_map(struct irq_host *h, unsigned int virq, | ||
157 | irq_hw_number_t hwirq) | ||
158 | { | ||
159 | /* All interrupts are LEVEL sensitive */ | ||
160 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
161 | irq_set_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, | ||
167 | const u32 *intspec, unsigned int intsize, | ||
168 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | ||
169 | { | ||
170 | |||
171 | *out_hwirq = intspec[0]; | ||
172 | if (intsize > 1) | ||
173 | *out_flags = intspec[1]; | ||
174 | else | ||
175 | *out_flags = IRQ_TYPE_LEVEL_HIGH; | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static struct irq_host_ops gef_pic_host_ops = { | ||
181 | .map = gef_pic_host_map, | ||
182 | .xlate = gef_pic_host_xlate, | ||
183 | }; | ||
184 | |||
185 | |||
186 | /* | ||
187 | * Initialisation of PIC, this should be called in BSP | ||
188 | */ | ||
189 | void __init gef_pic_init(struct device_node *np) | ||
190 | { | ||
191 | unsigned long flags; | ||
192 | |||
193 | /* Map the devices registers into memory */ | ||
194 | gef_pic_irq_reg_base = of_iomap(np, 0); | ||
195 | |||
196 | raw_spin_lock_irqsave(&gef_pic_lock, flags); | ||
197 | |||
198 | /* Initialise everything as masked. */ | ||
199 | out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0); | ||
200 | out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0); | ||
201 | |||
202 | out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0); | ||
203 | out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0); | ||
204 | |||
205 | raw_spin_unlock_irqrestore(&gef_pic_lock, flags); | ||
206 | |||
207 | /* Map controller */ | ||
208 | gef_pic_cascade_irq = irq_of_parse_and_map(np, 0); | ||
209 | if (gef_pic_cascade_irq == NO_IRQ) { | ||
210 | printk(KERN_ERR "SBC610: failed to map cascade interrupt"); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | /* Setup an irq_host structure */ | ||
215 | gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, | ||
216 | GEF_PIC_NUM_IRQS, | ||
217 | &gef_pic_host_ops, NO_IRQ); | ||
218 | if (gef_pic_irq_host == NULL) | ||
219 | return; | ||
220 | |||
221 | /* Chain with parent controller */ | ||
222 | irq_set_chained_handler(gef_pic_cascade_irq, gef_pic_cascade); | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * This is called when we receive an interrupt with apparently comes from this | ||
227 | * chip - check, returning the highest interrupt generated or return NO_IRQ | ||
228 | */ | ||
229 | unsigned int gef_pic_get_irq(void) | ||
230 | { | ||
231 | u32 cause, mask, active; | ||
232 | unsigned int virq = NO_IRQ; | ||
233 | int hwirq; | ||
234 | |||
235 | cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS); | ||
236 | |||
237 | mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); | ||
238 | |||
239 | active = cause & mask; | ||
240 | |||
241 | if (active) { | ||
242 | for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) { | ||
243 | if (active & (0x1 << hwirq)) | ||
244 | break; | ||
245 | } | ||
246 | virq = irq_linear_revmap(gef_pic_irq_host, | ||
247 | (irq_hw_number_t)hwirq); | ||
248 | } | ||
249 | |||
250 | return virq; | ||
251 | } | ||
252 | |||
diff --git a/arch/powerpc/platforms/86xx/gef_pic.h b/arch/powerpc/platforms/86xx/gef_pic.h deleted file mode 100644 index 6149916da3f4..000000000000 --- a/arch/powerpc/platforms/86xx/gef_pic.h +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | #ifndef __GEF_PIC_H__ | ||
2 | #define __GEF_PIC_H__ | ||
3 | |||
4 | #include <linux/init.h> | ||
5 | |||
6 | void gef_pic_cascade(unsigned int, struct irq_desc *); | ||
7 | unsigned int gef_pic_get_irq(void); | ||
8 | void gef_pic_init(struct device_node *); | ||
9 | |||
10 | #endif /* __GEF_PIC_H__ */ | ||
11 | |||
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 60ce07e39100..ed58b6cfd60c 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c | |||
@@ -37,9 +37,9 @@ | |||
37 | 37 | ||
38 | #include <sysdev/fsl_pci.h> | 38 | #include <sysdev/fsl_pci.h> |
39 | #include <sysdev/fsl_soc.h> | 39 | #include <sysdev/fsl_soc.h> |
40 | #include <sysdev/ge/ge_pic.h> | ||
40 | 41 | ||
41 | #include "mpc86xx.h" | 42 | #include "mpc86xx.h" |
42 | #include "gef_pic.h" | ||
43 | 43 | ||
44 | #undef DEBUG | 44 | #undef DEBUG |
45 | 45 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 3ecee25bf3ed..710db69bd523 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c | |||
@@ -37,9 +37,9 @@ | |||
37 | 37 | ||
38 | #include <sysdev/fsl_pci.h> | 38 | #include <sysdev/fsl_pci.h> |
39 | #include <sysdev/fsl_soc.h> | 39 | #include <sysdev/fsl_soc.h> |
40 | #include <sysdev/ge/ge_pic.h> | ||
40 | 41 | ||
41 | #include "mpc86xx.h" | 42 | #include "mpc86xx.h" |
42 | #include "gef_pic.h" | ||
43 | 43 | ||
44 | #undef DEBUG | 44 | #undef DEBUG |
45 | 45 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 5090d608d9ee..4a13d2f4ac20 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c | |||
@@ -37,9 +37,9 @@ | |||
37 | 37 | ||
38 | #include <sysdev/fsl_pci.h> | 38 | #include <sysdev/fsl_pci.h> |
39 | #include <sysdev/fsl_soc.h> | 39 | #include <sysdev/fsl_soc.h> |
40 | #include <sysdev/ge/ge_pic.h> | ||
40 | 41 | ||
41 | #include "mpc86xx.h" | 42 | #include "mpc86xx.h" |
42 | #include "gef_pic.h" | ||
43 | 43 | ||
44 | #undef DEBUG | 44 | #undef DEBUG |
45 | 45 | ||