aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/iseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/iseries')
-rw-r--r--arch/powerpc/platforms/iseries/irq.c7
-rw-r--r--arch/powerpc/platforms/iseries/irq.h2
-rw-r--r--arch/powerpc/platforms/iseries/pci.c273
-rw-r--r--arch/powerpc/platforms/iseries/setup.c204
4 files changed, 286 insertions, 200 deletions
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index be3fbfc24e6c..62bbbcf5ded3 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -42,6 +42,7 @@
42#include <asm/iseries/it_lp_queue.h> 42#include <asm/iseries/it_lp_queue.h>
43 43
44#include "irq.h" 44#include "irq.h"
45#include "pci.h"
45#include "call_pci.h" 46#include "call_pci.h"
46 47
47#if defined(CONFIG_SMP) 48#if defined(CONFIG_SMP)
@@ -312,12 +313,12 @@ static hw_irq_controller iSeries_IRQ_handler = {
312 * Note that sub_bus is always 0 (at the moment at least). 313 * Note that sub_bus is always 0 (at the moment at least).
313 */ 314 */
314int __init iSeries_allocate_IRQ(HvBusNumber bus, 315int __init iSeries_allocate_IRQ(HvBusNumber bus,
315 HvSubBusNumber sub_bus, HvAgentId dev_id) 316 HvSubBusNumber sub_bus, u32 bsubbus)
316{ 317{
317 int virtirq; 318 int virtirq;
318 unsigned int realirq; 319 unsigned int realirq;
319 u8 idsel = (dev_id >> 4); 320 u8 idsel = ISERIES_GET_DEVICE_FROM_SUBBUS(bsubbus);
320 u8 function = dev_id & 7; 321 u8 function = ISERIES_GET_FUNCTION_FROM_SUBBUS(bsubbus);
321 322
322 realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) 323 realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
323 + function; 324 + function;
diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h
index b9c801ba5a47..188aa808abd7 100644
--- a/arch/powerpc/platforms/iseries/irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -2,7 +2,7 @@
2#define _ISERIES_IRQ_H 2#define _ISERIES_IRQ_H
3 3
4extern void iSeries_init_IRQ(void); 4extern void iSeries_init_IRQ(void);
5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); 5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
6extern void iSeries_activate_IRQs(void); 6extern void iSeries_activate_IRQs(void);
7extern int iSeries_get_irq(struct pt_regs *); 7extern int iSeries_get_irq(struct pt_regs *);
8 8
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 91a94747eda9..9d571e749098 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -49,14 +49,9 @@
49 * Forward declares of prototypes. 49 * Forward declares of prototypes.
50 */ 50 */
51static struct device_node *find_Device_Node(int bus, int devfn); 51static struct device_node *find_Device_Node(int bus, int devfn);
52static void scan_PHB_slots(struct pci_controller *Phb);
53static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
54static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
55 52
56LIST_HEAD(iSeries_Global_Device_List); 53LIST_HEAD(iSeries_Global_Device_List);
57 54
58static int DeviceCount;
59
60static int Pci_Retry_Max = 3; /* Only retry 3 times */ 55static int Pci_Retry_Max = 3; /* Only retry 3 times */
61static int Pci_Error_Flag = 1; /* Set Retry Error on. */ 56static int Pci_Error_Flag = 1; /* Set Retry Error on. */
62 57
@@ -162,32 +157,6 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
162} 157}
163 158
164/* 159/*
165 * build_device_node(u16 Bus, int SubBus, u8 DevFn)
166 */
167static struct device_node *build_device_node(HvBusNumber Bus,
168 HvSubBusNumber SubBus, int AgentId, int Function)
169{
170 struct device_node *node;
171 struct pci_dn *pdn;
172
173 node = kzalloc(sizeof(struct device_node), GFP_KERNEL);
174 if (node == NULL)
175 return NULL;
176 pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
177 if (pdn == NULL) {
178 kfree(node);
179 return NULL;
180 }
181 node->data = pdn;
182 pdn->node = node;
183 list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List);
184 pdn->busno = Bus;
185 pdn->bussubno = SubBus;
186 pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
187 return node;
188}
189
190/*
191 * iSeries_pcibios_init 160 * iSeries_pcibios_init
192 * 161 *
193 * Description: 162 * Description:
@@ -199,33 +168,86 @@ static struct device_node *build_device_node(HvBusNumber Bus,
199void iSeries_pcibios_init(void) 168void iSeries_pcibios_init(void)
200{ 169{
201 struct pci_controller *phb; 170 struct pci_controller *phb;
202 HvBusNumber bus; 171 struct device_node *node;
203 172 struct device_node *dn;
204 /* Check all possible buses. */ 173
205 for (bus = 0; bus < 256; bus++) { 174 for_each_node_by_type(node, "pci") {
206 int ret = HvCallXm_testBus(bus); 175 HvBusNumber bus;
207 if (ret == 0) { 176 u32 *busp;
208 printk("bus %d appears to exist\n", bus); 177
209 178 busp = (u32 *)get_property(node, "bus-range", NULL);
210 phb = pcibios_alloc_controller(NULL); 179 if (busp == NULL)
211 if (phb == NULL) 180 continue;
212 return -ENOMEM; 181 bus = *busp;
182 printk("bus %d appears to exist\n", bus);
183 phb = pcibios_alloc_controller(node);
184 if (phb == NULL)
185 continue;
186
187 phb->pci_mem_offset = phb->local_number = bus;
188 phb->first_busno = bus;
189 phb->last_busno = bus;
190 phb->ops = &iSeries_pci_ops;
191
192 /* Find and connect the devices. */
193 for (dn = NULL; (dn = of_get_next_child(node, dn)) != NULL;) {
194 struct pci_dn *pdn;
195 u8 irq;
196 int err;
197 u32 *agent;
198 u32 *reg;
199 u32 *lsn;
200
201 reg = (u32 *)get_property(dn, "reg", NULL);
202 if (reg == NULL) {
203 printk(KERN_DEBUG "no reg property!\n");
204 continue;
205 }
206 busp = (u32 *)get_property(dn, "linux,subbus", NULL);
207 if (busp == NULL) {
208 printk(KERN_DEBUG "no subbus property!\n");
209 continue;
210 }
211 agent = (u32 *)get_property(dn, "linux,agent-id", NULL);
212 if (agent == NULL) {
213 printk(KERN_DEBUG "no agent-id\n");
214 continue;
215 }
216 lsn = (u32 *)get_property(dn,
217 "linux,logical-slot-number", NULL);
218 if (lsn == NULL) {
219 printk(KERN_DEBUG "no logical-slot-number\n");
220 continue;
221 }
213 222
214 phb->pci_mem_offset = phb->local_number = bus; 223 irq = iSeries_allocate_IRQ(bus, 0, *busp);
215 phb->first_busno = bus; 224 err = HvCallXm_connectBusUnit(bus, *busp, *agent, irq);
216 phb->last_busno = bus; 225 if (err) {
217 phb->ops = &iSeries_pci_ops; 226 pci_Log_Error("Connect Bus Unit",
227 bus, *busp, *agent, err);
228 continue;
229 }
230 err = HvCallPci_configStore8(bus, *busp, *agent,
231 PCI_INTERRUPT_LINE, irq);
232 if (err) {
233 pci_Log_Error("PciCfgStore Irq Failed!",
234 bus, *busp, *agent, err);
235 continue;
236 }
218 237
219 /* Find and connect the devices. */ 238 pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
220 scan_PHB_slots(phb); 239 if (pdn == NULL)
240 return;
241 dn->data = pdn;
242 pdn->node = dn;
243 pdn->busno = bus;
244 pdn->devfn = (reg[0] >> 8) & 0xff;
245 pdn->bussubno = *busp;
246 pdn->Irq = irq;
247 pdn->LogicalSlot = *lsn;
248 list_add_tail(&pdn->Device_List,
249 &iSeries_Global_Device_List);
221 } 250 }
222 /*
223 * Check for Unexpected Return code, a clue that something
224 * has gone wrong.
225 */
226 else if (ret != 0x0301)
227 printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
228 bus, ret);
229 } 251 }
230} 252}
231 253
@@ -272,147 +294,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
272} 294}
273 295
274/* 296/*
275 * Loop through each node function to find usable EADs bridges.
276 */
277static void scan_PHB_slots(struct pci_controller *Phb)
278{
279 struct HvCallPci_DeviceInfo *DevInfo;
280 HvBusNumber bus = Phb->local_number; /* System Bus */
281 const HvSubBusNumber SubBus = 0; /* EADs is always 0. */
282 int HvRc = 0;
283 int IdSel;
284 const int MaxAgents = 8;
285
286 DevInfo = kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
287 if (DevInfo == NULL)
288 return;
289
290 /*
291 * Probe for EADs Bridges
292 */
293 for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
294 HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
295 iseries_hv_addr(DevInfo),
296 sizeof(struct HvCallPci_DeviceInfo));
297 if (HvRc == 0) {
298 if (DevInfo->deviceType == HvCallPci_NodeDevice)
299 scan_EADS_bridge(bus, SubBus, IdSel);
300 else
301 printk("PCI: Invalid System Configuration(0x%02X)"
302 " for bus 0x%02x id 0x%02x.\n",
303 DevInfo->deviceType, bus, IdSel);
304 }
305 else
306 pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
307 }
308 kfree(DevInfo);
309}
310
311static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
312 int IdSel)
313{
314 struct HvCallPci_BridgeInfo *BridgeInfo;
315 HvAgentId AgentId;
316 int Function;
317 int HvRc;
318
319 BridgeInfo = (struct HvCallPci_BridgeInfo *)
320 kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
321 if (BridgeInfo == NULL)
322 return;
323
324 /* Note: hvSubBus and irq is always be 0 at this level! */
325 for (Function = 0; Function < 8; ++Function) {
326 AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
327 HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
328 if (HvRc == 0) {
329 printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
330 bus, IdSel, Function, AgentId);
331 /* Connect EADs: 0x18.00.12 = 0x00 */
332 HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
333 iseries_hv_addr(BridgeInfo),
334 sizeof(struct HvCallPci_BridgeInfo));
335 if (HvRc == 0) {
336 printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
337 BridgeInfo->busUnitInfo.deviceType,
338 BridgeInfo->subBusNumber,
339 BridgeInfo->maxAgents,
340 BridgeInfo->maxSubBusNumber,
341 BridgeInfo->logicalSlotNumber);
342 if (BridgeInfo->busUnitInfo.deviceType ==
343 HvCallPci_BridgeDevice) {
344 /* Scan_Bridge_Slot...: 0x18.00.12 */
345 scan_bridge_slot(bus, BridgeInfo);
346 } else
347 printk("PCI: Invalid Bridge Configuration(0x%02X)",
348 BridgeInfo->busUnitInfo.deviceType);
349 }
350 } else if (HvRc != 0x000B)
351 pci_Log_Error("EADs Connect",
352 bus, SubBus, AgentId, HvRc);
353 }
354 kfree(BridgeInfo);
355}
356
357/*
358 * This assumes that the node slot is always on the primary bus!
359 */
360static int scan_bridge_slot(HvBusNumber Bus,
361 struct HvCallPci_BridgeInfo *BridgeInfo)
362{
363 struct device_node *node;
364 HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
365 u16 VendorId = 0;
366 int HvRc = 0;
367 u8 Irq = 0;
368 int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
369 int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
370 HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
371
372 /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
373 Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
374
375 /*
376 * Connect all functions of any device found.
377 */
378 for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
379 for (Function = 0; Function < 8; ++Function) {
380 HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
381 HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
382 AgentId, Irq);
383 if (HvRc != 0) {
384 pci_Log_Error("Connect Bus Unit",
385 Bus, SubBus, AgentId, HvRc);
386 continue;
387 }
388
389 HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
390 PCI_VENDOR_ID, &VendorId);
391 if (HvRc != 0) {
392 pci_Log_Error("Read Vendor",
393 Bus, SubBus, AgentId, HvRc);
394 continue;
395 }
396 printk("read vendor ID: %x\n", VendorId);
397
398 /* FoundDevice: 0x18.28.10 = 0x12AE */
399 HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
400 PCI_INTERRUPT_LINE, Irq);
401 if (HvRc != 0)
402 pci_Log_Error("PciCfgStore Irq Failed!",
403 Bus, SubBus, AgentId, HvRc);
404
405 ++DeviceCount;
406 node = build_device_node(Bus, SubBus, EADsIdSel, Function);
407 PCI_DN(node)->Irq = Irq;
408 PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
409
410 } /* for (Function = 0; Function < 8; ++Function) */
411 } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
412 return HvRc;
413}
414
415/*
416 * I/0 Memory copy MUST use mmio commands on iSeries 297 * I/0 Memory copy MUST use mmio commands on iSeries
417 * To do; For performance, include the hv call directly 298 * To do; For performance, include the hv call directly
418 */ 299 */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index fd6d0ebe8ddd..d83f5ed4ec1f 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -66,6 +66,8 @@
66#include "main_store.h" 66#include "main_store.h"
67#include "call_sm.h" 67#include "call_sm.h"
68#include "call_hpt.h" 68#include "call_hpt.h"
69#include "call_pci.h"
70#include "pci.h"
69 71
70#ifdef DEBUG 72#ifdef DEBUG
71#define DBG(fmt...) udbg_printf(fmt) 73#define DBG(fmt...) udbg_printf(fmt)
@@ -1000,6 +1002,207 @@ void dt_vdevices(struct iseries_flat_dt *dt)
1000 dt_end_node(dt); 1002 dt_end_node(dt);
1001} 1003}
1002 1004
1005/*
1006 * This assumes that the node slot is always on the primary bus!
1007 */
1008static void scan_bridge_slot(struct iseries_flat_dt *dt, HvBusNumber bus,
1009 struct HvCallPci_BridgeInfo *bridge_info)
1010{
1011 HvSubBusNumber sub_bus = bridge_info->subBusNumber;
1012 u16 vendor_id;
1013 u16 device_id;
1014 u32 class_id;
1015 int err;
1016 char buf[32];
1017 u32 reg[5];
1018 int id_sel = ISERIES_GET_DEVICE_FROM_SUBBUS(sub_bus);
1019 int function = ISERIES_GET_FUNCTION_FROM_SUBBUS(sub_bus);
1020 HvAgentId eads_id_sel = ISERIES_PCI_AGENTID(id_sel, function);
1021
1022 /*
1023 * Connect all functions of any device found.
1024 */
1025 for (id_sel = 1; id_sel <= bridge_info->maxAgents; id_sel++) {
1026 for (function = 0; function < 8; function++) {
1027 u8 devfn;
1028
1029 HvAgentId agent_id = ISERIES_PCI_AGENTID(id_sel,
1030 function);
1031 err = HvCallXm_connectBusUnit(bus, sub_bus,
1032 agent_id, 0);
1033 if (err) {
1034 if (err != 0x302)
1035 printk(KERN_DEBUG
1036 "connectBusUnit(%x, %x, %x) "
1037 "== %x\n",
1038 bus, sub_bus, agent_id, err);
1039 continue;
1040 }
1041
1042 err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
1043 PCI_VENDOR_ID, &vendor_id);
1044 if (err) {
1045 printk(KERN_DEBUG
1046 "ReadVendor(%x, %x, %x) == %x\n",
1047 bus, sub_bus, agent_id, err);
1048 continue;
1049 }
1050 err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
1051 PCI_DEVICE_ID, &device_id);
1052 if (err) {
1053 printk(KERN_DEBUG
1054 "ReadDevice(%x, %x, %x) == %x\n",
1055 bus, sub_bus, agent_id, err);
1056 continue;
1057 }
1058 err = HvCallPci_configLoad32(bus, sub_bus, agent_id,
1059 PCI_CLASS_REVISION , &class_id);
1060 if (err) {
1061 printk(KERN_DEBUG
1062 "ReadClass(%x, %x, %x) == %x\n",
1063 bus, sub_bus, agent_id, err);
1064 continue;
1065 }
1066
1067 devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(eads_id_sel),
1068 function);
1069 if (function == 0)
1070 snprintf(buf, sizeof(buf), "pci@%x",
1071 PCI_SLOT(devfn));
1072 else
1073 snprintf(buf, sizeof(buf), "pci@%x,%d",
1074 PCI_SLOT(devfn), function);
1075 dt_start_node(dt, buf);
1076 reg[0] = (bus << 18) | (devfn << 8);
1077 reg[1] = 0;
1078 reg[2] = 0;
1079 reg[3] = 0;
1080 reg[4] = 0;
1081 dt_prop_u32_list(dt, "reg", reg, 5);
1082 dt_prop_u32(dt, "vendor-id", vendor_id);
1083 dt_prop_u32(dt, "device-id", device_id);
1084 dt_prop_u32(dt, "class-code", class_id >> 8);
1085 dt_prop_u32(dt, "revision-id", class_id & 0xff);
1086 dt_prop_u32(dt, "linux,subbus", sub_bus);
1087 dt_prop_u32(dt, "linux,agent-id", agent_id);
1088 dt_prop_u32(dt, "linux,logical-slot-number",
1089 bridge_info->logicalSlotNumber);
1090 dt_end_node(dt);
1091
1092 }
1093 }
1094}
1095
1096static void scan_bridge(struct iseries_flat_dt *dt, HvBusNumber bus,
1097 HvSubBusNumber sub_bus, int id_sel)
1098{
1099 struct HvCallPci_BridgeInfo bridge_info;
1100 HvAgentId agent_id;
1101 int function;
1102 int ret;
1103
1104 /* Note: hvSubBus and irq is always be 0 at this level! */
1105 for (function = 0; function < 8; ++function) {
1106 agent_id = ISERIES_PCI_AGENTID(id_sel, function);
1107 ret = HvCallXm_connectBusUnit(bus, sub_bus, agent_id, 0);
1108 if (ret != 0) {
1109 if (ret != 0xb)
1110 printk(KERN_DEBUG "connectBusUnit(%x, %x, %x) "
1111 "== %x\n",
1112 bus, sub_bus, agent_id, ret);
1113 continue;
1114 }
1115 printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
1116 bus, id_sel, function, agent_id);
1117 ret = HvCallPci_getBusUnitInfo(bus, sub_bus, agent_id,
1118 iseries_hv_addr(&bridge_info),
1119 sizeof(struct HvCallPci_BridgeInfo));
1120 if (ret != 0)
1121 continue;
1122 printk("bridge info: type %x subbus %x "
1123 "maxAgents %x maxsubbus %x logslot %x\n",
1124 bridge_info.busUnitInfo.deviceType,
1125 bridge_info.subBusNumber,
1126 bridge_info.maxAgents,
1127 bridge_info.maxSubBusNumber,
1128 bridge_info.logicalSlotNumber);
1129 if (bridge_info.busUnitInfo.deviceType ==
1130 HvCallPci_BridgeDevice)
1131 scan_bridge_slot(dt, bus, &bridge_info);
1132 else
1133 printk("PCI: Invalid Bridge Configuration(0x%02X)",
1134 bridge_info.busUnitInfo.deviceType);
1135 }
1136}
1137
1138static void scan_phb(struct iseries_flat_dt *dt, HvBusNumber bus)
1139{
1140 struct HvCallPci_DeviceInfo dev_info;
1141 const HvSubBusNumber sub_bus = 0; /* EADs is always 0. */
1142 int err;
1143 int id_sel;
1144 const int max_agents = 8;
1145
1146 /*
1147 * Probe for EADs Bridges
1148 */
1149 for (id_sel = 1; id_sel < max_agents; ++id_sel) {
1150 err = HvCallPci_getDeviceInfo(bus, sub_bus, id_sel,
1151 iseries_hv_addr(&dev_info),
1152 sizeof(struct HvCallPci_DeviceInfo));
1153 if (err) {
1154 if (err != 0x302)
1155 printk(KERN_DEBUG "getDeviceInfo(%x, %x, %x) "
1156 "== %x\n",
1157 bus, sub_bus, id_sel, err);
1158 continue;
1159 }
1160 if (dev_info.deviceType != HvCallPci_NodeDevice) {
1161 printk(KERN_DEBUG "PCI: Invalid System Configuration"
1162 "(0x%02X) for bus 0x%02x id 0x%02x.\n",
1163 dev_info.deviceType, bus, id_sel);
1164 continue;
1165 }
1166 scan_bridge(dt, bus, sub_bus, id_sel);
1167 }
1168}
1169
1170static void dt_pci_devices(struct iseries_flat_dt *dt)
1171{
1172 HvBusNumber bus;
1173 char buf[32];
1174 u32 buses[2];
1175 int phb_num = 0;
1176
1177 /* Check all possible buses. */
1178 for (bus = 0; bus < 256; bus++) {
1179 int err = HvCallXm_testBus(bus);
1180
1181 if (err) {
1182 /*
1183 * Check for Unexpected Return code, a clue that
1184 * something has gone wrong.
1185 */
1186 if (err != 0x0301)
1187 printk(KERN_ERR "Unexpected Return on Probe"
1188 "(0x%02X): 0x%04X", bus, err);
1189 continue;
1190 }
1191 printk("bus %d appears to exist\n", bus);
1192 snprintf(buf, 32, "pci@%d", phb_num);
1193 dt_start_node(dt, buf);
1194 dt_prop_str(dt, "device_type", "pci");
1195 dt_prop_str(dt, "compatible", "IBM,iSeries-Logical-PHB");
1196 dt_prop_u32(dt, "#address-cells", 3);
1197 dt_prop_u32(dt, "#size-cells", 2);
1198 buses[0] = buses[1] = bus;
1199 dt_prop_u32_list(dt, "bus-range", buses, 2);
1200 scan_phb(dt, bus);
1201 dt_end_node(dt);
1202 phb_num++;
1203 }
1204}
1205
1003void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) 1206void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
1004{ 1207{
1005 u64 tmp[2]; 1208 u64 tmp[2];
@@ -1029,6 +1232,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
1029 dt_cpus(dt); 1232 dt_cpus(dt);
1030 1233
1031 dt_vdevices(dt); 1234 dt_vdevices(dt);
1235 dt_pci_devices(dt);
1032 1236
1033 dt_end_node(dt); 1237 dt_end_node(dt);
1034 1238