aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/iSeries_irq.c
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2005-06-21 20:15:50 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:30 -0400
commit89ef68f0be53df6c4f1552fc329fe5abb1d5ed33 (patch)
tree2ee77b31b09869057eaf9830e3aba68f53128217 /arch/ppc64/kernel/iSeries_irq.c
parent0c3b4f1a8e06584d8a1051a74ed79cf8b41f703e (diff)
[PATCH] ppc64 iSeries: remove XmPciLpEvent.c
This patch just merges XmPciLpEvent.c into iSeries_irq.c (the only caller of its only external function). XmPciLpEvent.c just contained the lowlevel iSeries irq code. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/iSeries_irq.c')
-rw-r--r--arch/ppc64/kernel/iSeries_irq.c170
1 files changed, 168 insertions, 2 deletions
diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c
index 41902e358e76..96a1f8cd67e7 100644
--- a/arch/ppc64/kernel/iSeries_irq.c
+++ b/arch/ppc64/kernel/iSeries_irq.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * This module supports the iSeries PCI bus interrupt handling 2 * This module supports the iSeries PCI bus interrupt handling
3 * Copyright (C) 20yy <Robert L Holtorf> <IBM Corp> 3 * Copyright (C) 20yy <Robert L Holtorf> <IBM Corp>
4 * Copyright (C) 2004-2005 IBM Corporation
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -22,6 +23,7 @@
22 * Created, December 13, 2000 by Wayne Holm 23 * Created, December 13, 2000 by Wayne Holm
23 * End Change Activity 24 * End Change Activity
24 */ 25 */
26#include <linux/config.h>
25#include <linux/pci.h> 27#include <linux/pci.h>
26#include <linux/init.h> 28#include <linux/init.h>
27#include <linux/threads.h> 29#include <linux/threads.h>
@@ -30,11 +32,12 @@
30#include <linux/string.h> 32#include <linux/string.h>
31#include <linux/bootmem.h> 33#include <linux/bootmem.h>
32#include <linux/ide.h> 34#include <linux/ide.h>
33
34#include <linux/irq.h> 35#include <linux/irq.h>
35#include <linux/spinlock.h> 36#include <linux/spinlock.h>
36#include <asm/ppcdebug.h>
37 37
38#include <asm/ppcdebug.h>
39#include <asm/iSeries/HvTypes.h>
40#include <asm/iSeries/HvLpEvent.h>
38#include <asm/iSeries/HvCallPci.h> 41#include <asm/iSeries/HvCallPci.h>
39#include <asm/iSeries/HvCallXm.h> 42#include <asm/iSeries/HvCallXm.h>
40#include <asm/iSeries/iSeries_irq.h> 43#include <asm/iSeries/iSeries_irq.h>
@@ -46,6 +49,169 @@ unsigned int virt_irq_to_real_map[NR_IRQS];
46/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */ 49/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
47static int next_virtual_irq = 2; 50static int next_virtual_irq = 2;
48 51
52static long Pci_Interrupt_Count;
53static long Pci_Event_Count;
54
55enum XmPciLpEvent_Subtype {
56 XmPciLpEvent_BusCreated = 0, // PHB has been created
57 XmPciLpEvent_BusError = 1, // PHB has failed
58 XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus
59 XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed
60 XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered
61 XmPciLpEvent_BusRecovered = 12, // PHB has been recovered
62 XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing
63 XmPciLpEvent_BridgeError = 21, // Bridge Error
64 XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt
65};
66
67struct XmPciLpEvent_BusInterrupt {
68 HvBusNumber busNumber;
69 HvSubBusNumber subBusNumber;
70};
71
72struct XmPciLpEvent_NodeInterrupt {
73 HvBusNumber busNumber;
74 HvSubBusNumber subBusNumber;
75 HvAgentId deviceId;
76};
77
78struct XmPciLpEvent {
79 struct HvLpEvent hvLpEvent;
80
81 union {
82 u64 alignData; // Align on an 8-byte boundary
83
84 struct {
85 u32 fisr;
86 HvBusNumber busNumber;
87 HvSubBusNumber subBusNumber;
88 HvAgentId deviceId;
89 } slotInterrupt;
90
91 struct XmPciLpEvent_BusInterrupt busFailed;
92 struct XmPciLpEvent_BusInterrupt busRecovered;
93 struct XmPciLpEvent_BusInterrupt busCreated;
94
95 struct XmPciLpEvent_NodeInterrupt nodeFailed;
96 struct XmPciLpEvent_NodeInterrupt nodeRecovered;
97
98 } eventData;
99
100};
101
102static void intReceived(struct XmPciLpEvent *eventParm,
103 struct pt_regs *regsParm)
104{
105 int irq;
106
107 ++Pci_Interrupt_Count;
108#if 0
109 PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n");
110#endif
111
112 switch (eventParm->hvLpEvent.xSubtype) {
113 case XmPciLpEvent_SlotInterrupt:
114 irq = eventParm->hvLpEvent.xCorrelationToken;
115 /* Dispatch the interrupt handlers for this irq */
116 ppc_irq_dispatch_handler(regsParm, irq);
117 HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
118 eventParm->eventData.slotInterrupt.subBusNumber,
119 eventParm->eventData.slotInterrupt.deviceId);
120 break;
121 /* Ignore error recovery events for now */
122 case XmPciLpEvent_BusCreated:
123 printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n",
124 eventParm->eventData.busCreated.busNumber);
125 break;
126 case XmPciLpEvent_BusError:
127 case XmPciLpEvent_BusFailed:
128 printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n",
129 eventParm->eventData.busFailed.busNumber);
130 break;
131 case XmPciLpEvent_BusRecovered:
132 case XmPciLpEvent_UnQuiesceBus:
133 printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n",
134 eventParm->eventData.busRecovered.busNumber);
135 break;
136 case XmPciLpEvent_NodeFailed:
137 case XmPciLpEvent_BridgeError:
138 printk(KERN_INFO
139 "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n",
140 eventParm->eventData.nodeFailed.busNumber,
141 eventParm->eventData.nodeFailed.subBusNumber,
142 eventParm->eventData.nodeFailed.deviceId);
143 break;
144 case XmPciLpEvent_NodeRecovered:
145 printk(KERN_INFO
146 "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n",
147 eventParm->eventData.nodeRecovered.busNumber,
148 eventParm->eventData.nodeRecovered.subBusNumber,
149 eventParm->eventData.nodeRecovered.deviceId);
150 break;
151 default:
152 printk(KERN_ERR
153 "XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
154 eventParm->hvLpEvent.xSubtype);
155 break;
156 }
157}
158
159static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
160 struct pt_regs *regsParm)
161{
162#ifdef CONFIG_PCI
163#if 0
164 PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n",
165 eventParm->xType);
166#endif
167 ++Pci_Event_Count;
168
169 if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
170 switch (eventParm->xFlags.xFunction) {
171 case HvLpEvent_Function_Int:
172 intReceived((struct XmPciLpEvent *)eventParm, regsParm);
173 break;
174 case HvLpEvent_Function_Ack:
175 printk(KERN_ERR
176 "XmPciLpEvent.c: unexpected ack received\n");
177 break;
178 default:
179 printk(KERN_ERR
180 "XmPciLpEvent.c: unexpected event function %d\n",
181 (int)eventParm->xFlags.xFunction);
182 break;
183 }
184 } else if (eventParm)
185 printk(KERN_ERR
186 "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",
187 (int)eventParm->xType);
188 else
189 printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
190#endif
191}
192
193/* This should be called sometime prior to buswalk (init_IRQ would be good) */
194int XmPciLpEvent_init()
195{
196 int xRc;
197
198 PPCDBG(PPCDBG_BUSWALK,
199 "XmPciLpEvent_init, Register Event type 0x%04X\n",
200 HvLpEvent_Type_PciIo);
201
202 xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
203 &XmPciLpEvent_handler);
204 if (xRc == 0) {
205 xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
206 if (xRc != 0)
207 printk(KERN_ERR "XmPciLpEvent.c: open event path "
208 "failed with rc 0x%x\n", xRc);
209 } else
210 printk(KERN_ERR "XmPciLpEvent.c: register handler "
211 "failed with rc 0x%x\n", xRc);
212 return xRc;
213}
214
49/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ 215/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */
50void __init iSeries_init_IRQ(void) 216void __init iSeries_init_IRQ(void)
51{ 217{