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/Makefile2
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c2
-rw-r--r--arch/powerpc/platforms/iseries/pci.c670
-rw-r--r--arch/powerpc/platforms/iseries/pci.h27
-rw-r--r--arch/powerpc/platforms/iseries/setup.c61
-rw-r--r--arch/powerpc/platforms/iseries/setup.h1
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c275
8 files changed, 451 insertions, 591 deletions
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index a65f1b44abf8..cc7161ff1666 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -5,7 +5,7 @@ extra-y += dt.o
5obj-y += exception.o 5obj-y += exception.o
6obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ 6obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
7 hvcall.o proc.o htab.o iommu.o misc.o irq.o 7 hvcall.o proc.o htab.o iommu.o misc.o irq.o
8obj-$(CONFIG_PCI) += pci.o vpdinfo.o 8obj-$(CONFIG_PCI) += pci.o
9obj-$(CONFIG_SMP) += smp.o 9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_VIOPATH) += viopath.o vio.o 10obj-$(CONFIG_VIOPATH) += viopath.o vio.o
11obj-$(CONFIG_MODULES) += ksyms.o 11obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 49e9c664ea89..6a0c6f6675cd 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -163,8 +163,10 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
163 (it->it_type == TCE_PCI) && 163 (it->it_type == TCE_PCI) &&
164 (it->it_offset == tbl->it_offset) && 164 (it->it_offset == tbl->it_offset) &&
165 (it->it_index == tbl->it_index) && 165 (it->it_index == tbl->it_index) &&
166 (it->it_size == tbl->it_size)) 166 (it->it_size == tbl->it_size)) {
167 of_node_put(node);
167 return it; 168 return it;
169 }
168 } 170 }
169 return NULL; 171 return NULL;
170} 172}
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index 275f49449839..e5b40e3e0082 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -239,7 +239,7 @@ int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
239 * other CPUs, and that the deleted handler isn't 239 * other CPUs, and that the deleted handler isn't
240 * still running on another CPU when we return. 240 * still running on another CPU when we return.
241 */ 241 */
242 synchronize_rcu(); 242 synchronize_sched();
243 return 0; 243 return 0;
244 } 244 }
245 } 245 }
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index da87162000f0..cc562e4c2f32 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2001 Allan Trautman, IBM Corporation 2 * Copyright (C) 2001 Allan Trautman, IBM Corporation
3 * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp
3 * 4 *
4 * iSeries specific routines for PCI. 5 * iSeries specific routines for PCI.
5 * 6 *
@@ -19,13 +20,18 @@
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 22 */
23
24#undef DEBUG
25
22#include <linux/kernel.h> 26#include <linux/kernel.h>
23#include <linux/list.h> 27#include <linux/list.h>
24#include <linux/string.h> 28#include <linux/string.h>
25#include <linux/init.h> 29#include <linux/init.h>
26#include <linux/module.h> 30#include <linux/module.h>
27#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/of.h>
28 33
34#include <asm/types.h>
29#include <asm/io.h> 35#include <asm/io.h>
30#include <asm/irq.h> 36#include <asm/irq.h>
31#include <asm/prom.h> 37#include <asm/prom.h>
@@ -35,6 +41,7 @@
35#include <asm/abs_addr.h> 41#include <asm/abs_addr.h>
36#include <asm/firmware.h> 42#include <asm/firmware.h>
37 43
44#include <asm/iseries/hv_types.h>
38#include <asm/iseries/hv_call_xm.h> 45#include <asm/iseries/hv_call_xm.h>
39#include <asm/iseries/mf.h> 46#include <asm/iseries/mf.h>
40#include <asm/iseries/iommu.h> 47#include <asm/iseries/iommu.h>
@@ -45,15 +52,8 @@
45#include "pci.h" 52#include "pci.h"
46#include "call_pci.h" 53#include "call_pci.h"
47 54
48/* 55#define PCI_RETRY_MAX 3
49 * Forward declares of prototypes. 56static int limit_pci_retries = 1; /* Set Retry Error on. */
50 */
51static struct device_node *find_Device_Node(int bus, int devfn);
52
53static int Pci_Retry_Max = 3; /* Only retry 3 times */
54static int Pci_Error_Flag = 1; /* Set Retry Error on. */
55
56static struct pci_ops iSeries_pci_ops;
57 57
58/* 58/*
59 * Table defines 59 * Table defines
@@ -62,6 +62,7 @@ static struct pci_ops iSeries_pci_ops;
62#define IOMM_TABLE_MAX_ENTRIES 1024 62#define IOMM_TABLE_MAX_ENTRIES 1024
63#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL 63#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL
64#define BASE_IO_MEMORY 0xE000000000000000UL 64#define BASE_IO_MEMORY 0xE000000000000000UL
65#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL
65 66
66static unsigned long max_io_memory = BASE_IO_MEMORY; 67static unsigned long max_io_memory = BASE_IO_MEMORY;
67static long current_iomm_table_entry; 68static long current_iomm_table_entry;
@@ -70,12 +71,237 @@ static long current_iomm_table_entry;
70 * Lookup Tables. 71 * Lookup Tables.
71 */ 72 */
72static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; 73static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
73static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; 74static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];
74 75
75static const char pci_io_text[] = "iSeries PCI I/O";
76static DEFINE_SPINLOCK(iomm_table_lock); 76static DEFINE_SPINLOCK(iomm_table_lock);
77 77
78/* 78/*
79 * Generate a Direct Select Address for the Hypervisor
80 */
81static inline u64 iseries_ds_addr(struct device_node *node)
82{
83 struct pci_dn *pdn = PCI_DN(node);
84 const u32 *sbp = of_get_property(node, "linux,subbus", NULL);
85
86 return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)
87 + ((u64)0x10 << 32);
88}
89
90/*
91 * Size of Bus VPD data
92 */
93#define BUS_VPDSIZE 1024
94
95/*
96 * Bus Vpd Tags
97 */
98#define VPD_END_OF_AREA 0x79
99#define VPD_ID_STRING 0x82
100#define VPD_VENDOR_AREA 0x84
101
102/*
103 * Mfg Area Tags
104 */
105#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
106#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
107#define VPD_SLOT_MAP 0x534D /* "SM" */
108
109/*
110 * Structures of the areas
111 */
112struct mfg_vpd_area {
113 u16 tag;
114 u8 length;
115 u8 data1;
116 u8 data2;
117};
118#define MFG_ENTRY_SIZE 3
119
120struct slot_map {
121 u8 agent;
122 u8 secondary_agent;
123 u8 phb;
124 char card_location[3];
125 char parms[8];
126 char reserved[2];
127};
128#define SLOT_ENTRY_SIZE 16
129
130/*
131 * Parse the Slot Area
132 */
133static void __init iseries_parse_slot_area(struct slot_map *map, int len,
134 HvAgentId agent, u8 *phb, char card[4])
135{
136 /*
137 * Parse Slot label until we find the one requested
138 */
139 while (len > 0) {
140 if (map->agent == agent) {
141 /*
142 * If Phb wasn't found, grab the entry first one found.
143 */
144 if (*phb == 0xff)
145 *phb = map->phb;
146 /* Found it, extract the data. */
147 if (map->phb == *phb) {
148 memcpy(card, &map->card_location, 3);
149 card[3] = 0;
150 break;
151 }
152 }
153 /* Point to the next Slot */
154 map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
155 len -= SLOT_ENTRY_SIZE;
156 }
157}
158
159/*
160 * Parse the Mfg Area
161 */
162static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
163 HvAgentId agent, u8 *phb, u8 *frame, char card[4])
164{
165 u16 slot_map_fmt = 0;
166
167 /* Parse Mfg Data */
168 while (len > 0) {
169 int mfg_tag_len = area->length;
170 /* Frame ID (FI 4649020310 ) */
171 if (area->tag == VPD_FRU_FRAME_ID)
172 *frame = area->data1;
173 /* Slot Map Format (MF 4D46020004 ) */
174 else if (area->tag == VPD_SLOT_MAP_FORMAT)
175 slot_map_fmt = (area->data1 * 256)
176 + area->data2;
177 /* Slot Map (SM 534D90 */
178 else if (area->tag == VPD_SLOT_MAP) {
179 struct slot_map *slot_map;
180
181 if (slot_map_fmt == 0x1004)
182 slot_map = (struct slot_map *)((char *)area
183 + MFG_ENTRY_SIZE + 1);
184 else
185 slot_map = (struct slot_map *)((char *)area
186 + MFG_ENTRY_SIZE);
187 iseries_parse_slot_area(slot_map, mfg_tag_len,
188 agent, phb, card);
189 }
190 /*
191 * Point to the next Mfg Area
192 * Use defined size, sizeof give wrong answer
193 */
194 area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
195 + MFG_ENTRY_SIZE);
196 len -= (mfg_tag_len + MFG_ENTRY_SIZE);
197 }
198}
199
200/*
201 * Look for "BUS".. Data is not Null terminated.
202 * PHBID of 0xFF indicates PHB was not found in VPD Data.
203 */
204static u8 __init iseries_parse_phbid(u8 *area, int len)
205{
206 while (len > 0) {
207 if ((*area == 'B') && (*(area + 1) == 'U')
208 && (*(area + 2) == 'S')) {
209 area += 3;
210 while (*area == ' ')
211 area++;
212 return *area & 0x0F;
213 }
214 area++;
215 len--;
216 }
217 return 0xff;
218}
219
220/*
221 * Parse out the VPD Areas
222 */
223static void __init iseries_parse_vpd(u8 *data, int data_len,
224 HvAgentId agent, u8 *frame, char card[4])
225{
226 u8 phb = 0xff;
227
228 while (data_len > 0) {
229 int len;
230 u8 tag = *data;
231
232 if (tag == VPD_END_OF_AREA)
233 break;
234 len = *(data + 1) + (*(data + 2) * 256);
235 data += 3;
236 data_len -= 3;
237 if (tag == VPD_ID_STRING)
238 phb = iseries_parse_phbid(data, len);
239 else if (tag == VPD_VENDOR_AREA)
240 iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
241 agent, &phb, frame, card);
242 /* Point to next Area. */
243 data += len;
244 data_len -= len;
245 }
246}
247
248static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
249 u8 *frame, char card[4])
250{
251 int status = 0;
252 int bus_vpd_len = 0;
253 u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
254
255 if (bus_vpd == NULL) {
256 printk("PCI: Bus VPD Buffer allocation failure.\n");
257 return 0;
258 }
259 bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
260 BUS_VPDSIZE);
261 if (bus_vpd_len == 0) {
262 printk("PCI: Bus VPD Buffer zero length.\n");
263 goto out_free;
264 }
265 /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
266 /* Make sure this is what I think it is */
267 if (*bus_vpd != VPD_ID_STRING) {
268 printk("PCI: Bus VPD Buffer missing starting tag.\n");
269 goto out_free;
270 }
271 iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
272 status = 1;
273out_free:
274 kfree(bus_vpd);
275 return status;
276}
277
278/*
279 * Prints the device information.
280 * - Pass in pci_dev* pointer to the device.
281 * - Pass in the device count
282 *
283 * Format:
284 * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
285 * controller
286 */
287static void __init iseries_device_information(struct pci_dev *pdev,
288 u16 bus, HvSubBusNumber subbus)
289{
290 u8 frame = 0;
291 char card[4];
292 HvAgentId agent;
293
294 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
295 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
296
297 if (iseries_get_location_code(bus, agent, &frame, card)) {
298 printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "
299 "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor,
300 frame, card, (int)(pdev->class >> 8));
301 }
302}
303
304/*
79 * iomm_table_allocate_entry 305 * iomm_table_allocate_entry
80 * 306 *
81 * Adds pci_dev entry in address translation table 307 * Adds pci_dev entry in address translation table
@@ -87,7 +313,7 @@ static DEFINE_SPINLOCK(iomm_table_lock);
87 * - CurrentIndex is incremented to keep track of the last entry. 313 * - CurrentIndex is incremented to keep track of the last entry.
88 * - Builds the resource entry for allocated BARs. 314 * - Builds the resource entry for allocated BARs.
89 */ 315 */
90static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) 316static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
91{ 317{
92 struct resource *bar_res = &dev->resource[bar_num]; 318 struct resource *bar_res = &dev->resource[bar_num];
93 long bar_size = pci_resource_len(dev, bar_num); 319 long bar_size = pci_resource_len(dev, bar_num);
@@ -101,7 +327,6 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
101 * Set Resource values. 327 * Set Resource values.
102 */ 328 */
103 spin_lock(&iomm_table_lock); 329 spin_lock(&iomm_table_lock);
104 bar_res->name = pci_io_text;
105 bar_res->start = BASE_IO_MEMORY + 330 bar_res->start = BASE_IO_MEMORY +
106 IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; 331 IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
107 bar_res->end = bar_res->start + bar_size - 1; 332 bar_res->end = bar_res->start + bar_size - 1;
@@ -110,7 +335,8 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
110 */ 335 */
111 while (bar_size > 0 ) { 336 while (bar_size > 0 ) {
112 iomm_table[current_iomm_table_entry] = dev->sysdata; 337 iomm_table[current_iomm_table_entry] = dev->sysdata;
113 iobar_table[current_iomm_table_entry] = bar_num; 338 ds_addr_table[current_iomm_table_entry] =
339 iseries_ds_addr(dev->sysdata) | (bar_num << 24);
114 bar_size -= IOMM_TABLE_ENTRY_SIZE; 340 bar_size -= IOMM_TABLE_ENTRY_SIZE;
115 ++current_iomm_table_entry; 341 ++current_iomm_table_entry;
116 } 342 }
@@ -130,7 +356,7 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
130 * - Loops through The Bar resources(0 - 5) including the ROM 356 * - Loops through The Bar resources(0 - 5) including the ROM
131 * is resource(6). 357 * is resource(6).
132 */ 358 */
133static void allocate_device_bars(struct pci_dev *dev) 359static void __init allocate_device_bars(struct pci_dev *dev)
134{ 360{
135 int bar_num; 361 int bar_num;
136 362
@@ -145,79 +371,19 @@ static void allocate_device_bars(struct pci_dev *dev)
145 * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx 371 * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
146 * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx 372 * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
147 */ 373 */
148static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, 374static void pci_log_error(char *error, int bus, int subbus,
149 int AgentId, int HvRc) 375 int agent, int hv_res)
150{ 376{
151 if (HvRc == 0x0302) 377 if (hv_res == 0x0302)
152 return; 378 return;
153 printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X", 379 printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
154 Error_Text, Bus, SubBus, AgentId, HvRc); 380 error, bus, subbus, agent, hv_res);
155}
156
157/*
158 * iSeries_pci_final_fixup(void)
159 */
160void __init iSeries_pci_final_fixup(void)
161{
162 struct pci_dev *pdev = NULL;
163 struct device_node *node;
164 int DeviceCount = 0;
165
166 /* Fix up at the device node and pci_dev relationship */
167 mf_display_src(0xC9000100);
168
169 printk("pcibios_final_fixup\n");
170 for_each_pci_dev(pdev) {
171 node = find_Device_Node(pdev->bus->number, pdev->devfn);
172 printk("pci dev %p (%x.%x), node %p\n", pdev,
173 pdev->bus->number, pdev->devfn, node);
174
175 if (node != NULL) {
176 struct pci_dn *pdn = PCI_DN(node);
177 const u32 *agent;
178
179 agent = of_get_property(node, "linux,agent-id", NULL);
180 if ((pdn != NULL) && (agent != NULL)) {
181 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
182 pdn->bussubno);
183 int err;
184
185 err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno,
186 *agent, irq);
187 if (err)
188 pci_Log_Error("Connect Bus Unit",
189 pdn->busno, pdn->bussubno, *agent, err);
190 else {
191 err = HvCallPci_configStore8(pdn->busno, pdn->bussubno,
192 *agent,
193 PCI_INTERRUPT_LINE,
194 irq);
195 if (err)
196 pci_Log_Error("PciCfgStore Irq Failed!",
197 pdn->busno, pdn->bussubno, *agent, err);
198 }
199 if (!err)
200 pdev->irq = irq;
201 }
202
203 ++DeviceCount;
204 pdev->sysdata = (void *)node;
205 PCI_DN(node)->pcidev = pdev;
206 allocate_device_bars(pdev);
207 iSeries_Device_Information(pdev, DeviceCount);
208 iommu_devnode_init_iSeries(pdev, node);
209 } else
210 printk("PCI: Device Tree not found for 0x%016lX\n",
211 (unsigned long)pdev);
212 }
213 iSeries_activate_IRQs();
214 mf_display_src(0xC9000200);
215} 381}
216 382
217/* 383/*
218 * Look down the chain to find the matching Device Device 384 * Look down the chain to find the matching Device Device
219 */ 385 */
220static struct device_node *find_Device_Node(int bus, int devfn) 386static struct device_node *find_device_node(int bus, int devfn)
221{ 387{
222 struct device_node *node; 388 struct device_node *node;
223 389
@@ -230,22 +396,66 @@ static struct device_node *find_Device_Node(int bus, int devfn)
230 return NULL; 396 return NULL;
231} 397}
232 398
233#if 0
234/* 399/*
235 * Returns the device node for the passed pci_dev 400 * iSeries_pcibios_fixup_resources
236 * Sanity Check Node PciDev to passed pci_dev 401 *
237 * If none is found, returns a NULL which the client must handle. 402 * Fixes up all resources for devices
238 */ 403 */
239static struct device_node *get_Device_Node(struct pci_dev *pdev) 404void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
240{ 405{
406 const u32 *agent;
407 const u32 *sub_bus;
408 unsigned char bus = pdev->bus->number;
241 struct device_node *node; 409 struct device_node *node;
410 int i;
411
412 node = find_device_node(bus, pdev->devfn);
413 pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
414 pci_name(pdev), pdev, node);
415 if (!node) {
416 printk("PCI: %s disabled, device tree entry not found !\n",
417 pci_name(pdev));
418 for (i = 0; i <= PCI_ROM_RESOURCE; i++)
419 pdev->resource[i].flags = 0;
420 return;
421 }
422 sub_bus = of_get_property(node, "linux,subbus", NULL);
423 agent = of_get_property(node, "linux,agent-id", NULL);
424 if (agent && sub_bus) {
425 u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);
426 int err;
427
428 err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);
429 if (err)
430 pci_log_error("Connect Bus Unit",
431 bus, *sub_bus, *agent, err);
432 else {
433 err = HvCallPci_configStore8(bus, *sub_bus,
434 *agent, PCI_INTERRUPT_LINE, irq);
435 if (err)
436 pci_log_error("PciCfgStore Irq Failed!",
437 bus, *sub_bus, *agent, err);
438 else
439 pdev->irq = irq;
440 }
441 }
242 442
243 node = pdev->sysdata; 443 pdev->sysdata = node;
244 if (node == NULL || PCI_DN(node)->pcidev != pdev) 444 allocate_device_bars(pdev);
245 node = find_Device_Node(pdev->bus->number, pdev->devfn); 445 iseries_device_information(pdev, bus, *sub_bus);
246 return node; 446 iommu_devnode_init_iSeries(pdev, node);
447}
448
449/*
450 * iSeries_pci_final_fixup(void)
451 */
452void __init iSeries_pci_final_fixup(void)
453{
454 /* Fix up at the device node and pci_dev relationship */
455 mf_display_src(0xC9000100);
456 iSeries_activate_IRQs();
457 mf_display_src(0xC9000200);
247} 458}
248#endif
249 459
250/* 460/*
251 * Config space read and write functions. 461 * Config space read and write functions.
@@ -269,7 +479,7 @@ static u64 hv_cfg_write_func[4] = {
269static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, 479static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
270 int offset, int size, u32 *val) 480 int offset, int size, u32 *val)
271{ 481{
272 struct device_node *node = find_Device_Node(bus->number, devfn); 482 struct device_node *node = find_device_node(bus->number, devfn);
273 u64 fn; 483 u64 fn;
274 struct HvCallPci_LoadReturn ret; 484 struct HvCallPci_LoadReturn ret;
275 485
@@ -299,7 +509,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
299static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, 509static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
300 int offset, int size, u32 val) 510 int offset, int size, u32 val)
301{ 511{
302 struct device_node *node = find_Device_Node(bus->number, devfn); 512 struct device_node *node = find_device_node(bus->number, devfn);
303 u64 fn; 513 u64 fn;
304 u64 ret; 514 u64 ret;
305 515
@@ -331,22 +541,22 @@ static struct pci_ops iSeries_pci_ops = {
331 * PCI: Device 23.90 ReadL Retry( 1) 541 * PCI: Device 23.90 ReadL Retry( 1)
332 * PCI: Device 23.90 ReadL Retry Successful(1) 542 * PCI: Device 23.90 ReadL Retry Successful(1)
333 */ 543 */
334static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, 544static int check_return_code(char *type, struct device_node *dn,
335 int *retry, u64 ret) 545 int *retry, u64 ret)
336{ 546{
337 if (ret != 0) { 547 if (ret != 0) {
338 struct pci_dn *pdn = PCI_DN(DevNode); 548 struct pci_dn *pdn = PCI_DN(dn);
339 549
340 (*retry)++; 550 (*retry)++;
341 printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", 551 printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
342 TextHdr, pdn->busno, pdn->devfn, 552 type, pdn->busno, pdn->devfn,
343 *retry, (int)ret); 553 *retry, (int)ret);
344 /* 554 /*
345 * Bump the retry and check for retry count exceeded. 555 * Bump the retry and check for retry count exceeded.
346 * If, Exceeded, panic the system. 556 * If, Exceeded, panic the system.
347 */ 557 */
348 if (((*retry) > Pci_Retry_Max) && 558 if (((*retry) > PCI_RETRY_MAX) &&
349 (Pci_Error_Flag > 0)) { 559 (limit_pci_retries > 0)) {
350 mf_display_src(0xB6000103); 560 mf_display_src(0xB6000103);
351 panic_timeout = 0; 561 panic_timeout = 0;
352 panic("PCI: Hardware I/O Error, SRC B6000103, " 562 panic("PCI: Hardware I/O Error, SRC B6000103, "
@@ -363,28 +573,39 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
363 * the exposure of being device global. 573 * the exposure of being device global.
364 */ 574 */
365static inline struct device_node *xlate_iomm_address( 575static inline struct device_node *xlate_iomm_address(
366 const volatile void __iomem *IoAddress, 576 const volatile void __iomem *addr,
367 u64 *dsaptr, u64 *BarOffsetPtr) 577 u64 *dsaptr, u64 *bar_offset, const char *func)
368{ 578{
369 unsigned long OrigIoAddr; 579 unsigned long orig_addr;
370 unsigned long BaseIoAddr; 580 unsigned long base_addr;
371 unsigned long TableIndex; 581 unsigned long ind;
372 struct device_node *DevNode; 582 struct device_node *dn;
583
584 orig_addr = (unsigned long __force)addr;
585 if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
586 static unsigned long last_jiffies;
587 static int num_printed;
373 588
374 OrigIoAddr = (unsigned long __force)IoAddress; 589 if ((jiffies - last_jiffies) > 60 * HZ) {
375 if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) 590 last_jiffies = jiffies;
591 num_printed = 0;
592 }
593 if (num_printed++ < 10)
594 printk(KERN_ERR
595 "iSeries_%s: invalid access at IO address %p\n",
596 func, addr);
376 return NULL; 597 return NULL;
377 BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY; 598 }
378 TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE; 599 base_addr = orig_addr - BASE_IO_MEMORY;
379 DevNode = iomm_table[TableIndex]; 600 ind = base_addr / IOMM_TABLE_ENTRY_SIZE;
380 601 dn = iomm_table[ind];
381 if (DevNode != NULL) { 602
382 int barnum = iobar_table[TableIndex]; 603 if (dn != NULL) {
383 *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24); 604 *dsaptr = ds_addr_table[ind];
384 *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; 605 *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
385 } else 606 } else
386 panic("PCI: Invalid PCI IoAddress detected!\n"); 607 panic("PCI: Invalid PCI IO address detected!\n");
387 return DevNode; 608 return dn;
388} 609}
389 610
390/* 611/*
@@ -392,91 +613,58 @@ static inline struct device_node *xlate_iomm_address(
392 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal 613 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
393 * else, data is returned in Big Endian format. 614 * else, data is returned in Big Endian format.
394 */ 615 */
395static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 616static u8 iseries_readb(const volatile void __iomem *addr)
396{ 617{
397 u64 BarOffset; 618 u64 bar_offset;
398 u64 dsa; 619 u64 dsa;
399 int retry = 0; 620 int retry = 0;
400 struct HvCallPci_LoadReturn ret; 621 struct HvCallPci_LoadReturn ret;
401 struct device_node *DevNode = 622 struct device_node *dn =
402 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 623 xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");
403
404 if (DevNode == NULL) {
405 static unsigned long last_jiffies;
406 static int num_printed;
407 624
408 if ((jiffies - last_jiffies) > 60 * HZ) { 625 if (dn == NULL)
409 last_jiffies = jiffies;
410 num_printed = 0;
411 }
412 if (num_printed++ < 10)
413 printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n",
414 IoAddress);
415 return 0xff; 626 return 0xff;
416 }
417 do { 627 do {
418 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); 628 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);
419 } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); 629 } while (check_return_code("RDB", dn, &retry, ret.rc) != 0);
420 630
421 return ret.value; 631 return ret.value;
422} 632}
423 633
424static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 634static u16 iseries_readw_be(const volatile void __iomem *addr)
425{ 635{
426 u64 BarOffset; 636 u64 bar_offset;
427 u64 dsa; 637 u64 dsa;
428 int retry = 0; 638 int retry = 0;
429 struct HvCallPci_LoadReturn ret; 639 struct HvCallPci_LoadReturn ret;
430 struct device_node *DevNode = 640 struct device_node *dn =
431 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 641 xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");
432 642
433 if (DevNode == NULL) { 643 if (dn == NULL)
434 static unsigned long last_jiffies;
435 static int num_printed;
436
437 if ((jiffies - last_jiffies) > 60 * HZ) {
438 last_jiffies = jiffies;
439 num_printed = 0;
440 }
441 if (num_printed++ < 10)
442 printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n",
443 IoAddress);
444 return 0xffff; 644 return 0xffff;
445 }
446 do { 645 do {
447 HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, 646 HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
448 BarOffset, 0); 647 bar_offset, 0);
449 } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); 648 } while (check_return_code("RDW", dn, &retry, ret.rc) != 0);
450 649
451 return ret.value; 650 return ret.value;
452} 651}
453 652
454static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 653static u32 iseries_readl_be(const volatile void __iomem *addr)
455{ 654{
456 u64 BarOffset; 655 u64 bar_offset;
457 u64 dsa; 656 u64 dsa;
458 int retry = 0; 657 int retry = 0;
459 struct HvCallPci_LoadReturn ret; 658 struct HvCallPci_LoadReturn ret;
460 struct device_node *DevNode = 659 struct device_node *dn =
461 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 660 xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");
462
463 if (DevNode == NULL) {
464 static unsigned long last_jiffies;
465 static int num_printed;
466 661
467 if ((jiffies - last_jiffies) > 60 * HZ) { 662 if (dn == NULL)
468 last_jiffies = jiffies;
469 num_printed = 0;
470 }
471 if (num_printed++ < 10)
472 printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n",
473 IoAddress);
474 return 0xffffffff; 663 return 0xffffffff;
475 }
476 do { 664 do {
477 HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, 665 HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
478 BarOffset, 0); 666 bar_offset, 0);
479 } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); 667 } while (check_return_code("RDL", dn, &retry, ret.rc) != 0);
480 668
481 return ret.value; 669 return ret.value;
482} 670}
@@ -485,134 +673,72 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
485 * Write MM I/O Instructions for the iSeries 673 * Write MM I/O Instructions for the iSeries
486 * 674 *
487 */ 675 */
488static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 676static void iseries_writeb(u8 data, volatile void __iomem *addr)
489{ 677{
490 u64 BarOffset; 678 u64 bar_offset;
491 u64 dsa; 679 u64 dsa;
492 int retry = 0; 680 int retry = 0;
493 u64 rc; 681 u64 rc;
494 struct device_node *DevNode = 682 struct device_node *dn =
495 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 683 xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");
496
497 if (DevNode == NULL) {
498 static unsigned long last_jiffies;
499 static int num_printed;
500 684
501 if ((jiffies - last_jiffies) > 60 * HZ) { 685 if (dn == NULL)
502 last_jiffies = jiffies;
503 num_printed = 0;
504 }
505 if (num_printed++ < 10)
506 printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
507 return; 686 return;
508 }
509 do { 687 do {
510 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); 688 rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);
511 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); 689 } while (check_return_code("WWB", dn, &retry, rc) != 0);
512} 690}
513 691
514static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) 692static void iseries_writew_be(u16 data, volatile void __iomem *addr)
515{ 693{
516 u64 BarOffset; 694 u64 bar_offset;
517 u64 dsa; 695 u64 dsa;
518 int retry = 0; 696 int retry = 0;
519 u64 rc; 697 u64 rc;
520 struct device_node *DevNode = 698 struct device_node *dn =
521 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 699 xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");
522 700
523 if (DevNode == NULL) { 701 if (dn == NULL)
524 static unsigned long last_jiffies;
525 static int num_printed;
526
527 if ((jiffies - last_jiffies) > 60 * HZ) {
528 last_jiffies = jiffies;
529 num_printed = 0;
530 }
531 if (num_printed++ < 10)
532 printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n",
533 IoAddress);
534 return; 702 return;
535 }
536 do { 703 do {
537 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0); 704 rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);
538 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); 705 } while (check_return_code("WWW", dn, &retry, rc) != 0);
539} 706}
540 707
541static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) 708static void iseries_writel_be(u32 data, volatile void __iomem *addr)
542{ 709{
543 u64 BarOffset; 710 u64 bar_offset;
544 u64 dsa; 711 u64 dsa;
545 int retry = 0; 712 int retry = 0;
546 u64 rc; 713 u64 rc;
547 struct device_node *DevNode = 714 struct device_node *dn =
548 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 715 xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");
549
550 if (DevNode == NULL) {
551 static unsigned long last_jiffies;
552 static int num_printed;
553 716
554 if ((jiffies - last_jiffies) > 60 * HZ) { 717 if (dn == NULL)
555 last_jiffies = jiffies;
556 num_printed = 0;
557 }
558 if (num_printed++ < 10)
559 printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n",
560 IoAddress);
561 return; 718 return;
562 }
563 do { 719 do {
564 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0); 720 rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);
565 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); 721 } while (check_return_code("WWL", dn, &retry, rc) != 0);
566}
567
568static u8 iseries_readb(const volatile void __iomem *addr)
569{
570 return iSeries_Read_Byte(addr);
571} 722}
572 723
573static u16 iseries_readw(const volatile void __iomem *addr) 724static u16 iseries_readw(const volatile void __iomem *addr)
574{ 725{
575 return le16_to_cpu(iSeries_Read_Word(addr)); 726 return le16_to_cpu(iseries_readw_be(addr));
576} 727}
577 728
578static u32 iseries_readl(const volatile void __iomem *addr) 729static u32 iseries_readl(const volatile void __iomem *addr)
579{ 730{
580 return le32_to_cpu(iSeries_Read_Long(addr)); 731 return le32_to_cpu(iseries_readl_be(addr));
581}
582
583static u16 iseries_readw_be(const volatile void __iomem *addr)
584{
585 return iSeries_Read_Word(addr);
586}
587
588static u32 iseries_readl_be(const volatile void __iomem *addr)
589{
590 return iSeries_Read_Long(addr);
591}
592
593static void iseries_writeb(u8 data, volatile void __iomem *addr)
594{
595 iSeries_Write_Byte(data, addr);
596} 732}
597 733
598static void iseries_writew(u16 data, volatile void __iomem *addr) 734static void iseries_writew(u16 data, volatile void __iomem *addr)
599{ 735{
600 iSeries_Write_Word(cpu_to_le16(data), addr); 736 iseries_writew_be(cpu_to_le16(data), addr);
601} 737}
602 738
603static void iseries_writel(u32 data, volatile void __iomem *addr) 739static void iseries_writel(u32 data, volatile void __iomem *addr)
604{ 740{
605 iSeries_Write_Long(cpu_to_le32(data), addr); 741 iseries_writel(cpu_to_le32(data), addr);
606}
607
608static void iseries_writew_be(u16 data, volatile void __iomem *addr)
609{
610 iSeries_Write_Word(data, addr);
611}
612
613static void iseries_writel_be(u32 data, volatile void __iomem *addr)
614{
615 iSeries_Write_Long(data, addr);
616} 742}
617 743
618static void iseries_readsb(const volatile void __iomem *addr, void *buf, 744static void iseries_readsb(const volatile void __iomem *addr, void *buf,
@@ -620,7 +746,7 @@ static void iseries_readsb(const volatile void __iomem *addr, void *buf,
620{ 746{
621 u8 *dst = buf; 747 u8 *dst = buf;
622 while(count-- > 0) 748 while(count-- > 0)
623 *(dst++) = iSeries_Read_Byte(addr); 749 *(dst++) = iseries_readb(addr);
624} 750}
625 751
626static void iseries_readsw(const volatile void __iomem *addr, void *buf, 752static void iseries_readsw(const volatile void __iomem *addr, void *buf,
@@ -628,7 +754,7 @@ static void iseries_readsw(const volatile void __iomem *addr, void *buf,
628{ 754{
629 u16 *dst = buf; 755 u16 *dst = buf;
630 while(count-- > 0) 756 while(count-- > 0)
631 *(dst++) = iSeries_Read_Word(addr); 757 *(dst++) = iseries_readw_be(addr);
632} 758}
633 759
634static void iseries_readsl(const volatile void __iomem *addr, void *buf, 760static void iseries_readsl(const volatile void __iomem *addr, void *buf,
@@ -636,7 +762,7 @@ static void iseries_readsl(const volatile void __iomem *addr, void *buf,
636{ 762{
637 u32 *dst = buf; 763 u32 *dst = buf;
638 while(count-- > 0) 764 while(count-- > 0)
639 *(dst++) = iSeries_Read_Long(addr); 765 *(dst++) = iseries_readl_be(addr);
640} 766}
641 767
642static void iseries_writesb(volatile void __iomem *addr, const void *buf, 768static void iseries_writesb(volatile void __iomem *addr, const void *buf,
@@ -644,7 +770,7 @@ static void iseries_writesb(volatile void __iomem *addr, const void *buf,
644{ 770{
645 const u8 *src = buf; 771 const u8 *src = buf;
646 while(count-- > 0) 772 while(count-- > 0)
647 iSeries_Write_Byte(*(src++), addr); 773 iseries_writeb(*(src++), addr);
648} 774}
649 775
650static void iseries_writesw(volatile void __iomem *addr, const void *buf, 776static void iseries_writesw(volatile void __iomem *addr, const void *buf,
@@ -652,7 +778,7 @@ static void iseries_writesw(volatile void __iomem *addr, const void *buf,
652{ 778{
653 const u16 *src = buf; 779 const u16 *src = buf;
654 while(count-- > 0) 780 while(count-- > 0)
655 iSeries_Write_Word(*(src++), addr); 781 iseries_writew_be(*(src++), addr);
656} 782}
657 783
658static void iseries_writesl(volatile void __iomem *addr, const void *buf, 784static void iseries_writesl(volatile void __iomem *addr, const void *buf,
@@ -660,7 +786,7 @@ static void iseries_writesl(volatile void __iomem *addr, const void *buf,
660{ 786{
661 const u32 *src = buf; 787 const u32 *src = buf;
662 while(count-- > 0) 788 while(count-- > 0)
663 iSeries_Write_Long(*(src++), addr); 789 iseries_writel_be(*(src++), addr);
664} 790}
665 791
666static void iseries_memset_io(volatile void __iomem *addr, int c, 792static void iseries_memset_io(volatile void __iomem *addr, int c,
@@ -669,7 +795,7 @@ static void iseries_memset_io(volatile void __iomem *addr, int c,
669 volatile char __iomem *d = addr; 795 volatile char __iomem *d = addr;
670 796
671 while (n-- > 0) 797 while (n-- > 0)
672 iSeries_Write_Byte(c, d++); 798 iseries_writeb(c, d++);
673} 799}
674 800
675static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src, 801static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
@@ -679,7 +805,7 @@ static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
679 const volatile char __iomem *s = src; 805 const volatile char __iomem *s = src;
680 806
681 while (n-- > 0) 807 while (n-- > 0)
682 *d++ = iSeries_Read_Byte(s++); 808 *d++ = iseries_readb(s++);
683} 809}
684 810
685static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src, 811static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
@@ -689,7 +815,7 @@ static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
689 volatile char __iomem *d = dest; 815 volatile char __iomem *d = dest;
690 816
691 while (n-- > 0) 817 while (n-- > 0)
692 iSeries_Write_Byte(*s++, d++); 818 iseries_writeb(*s++, d++);
693} 819}
694 820
695/* We only set MMIO ops. The default PIO ops will be default 821/* We only set MMIO ops. The default PIO ops will be default
@@ -742,6 +868,8 @@ void __init iSeries_pcibios_init(void)
742 /* Install IO hooks */ 868 /* Install IO hooks */
743 ppc_pci_io = iseries_pci_io; 869 ppc_pci_io = iseries_pci_io;
744 870
871 pci_probe_only = 1;
872
745 /* iSeries has no IO space in the common sense, it needs to set 873 /* iSeries has no IO space in the common sense, it needs to set
746 * the IO base to 0 874 * the IO base to 0
747 */ 875 */
@@ -767,11 +895,21 @@ void __init iSeries_pcibios_init(void)
767 phb = pcibios_alloc_controller(node); 895 phb = pcibios_alloc_controller(node);
768 if (phb == NULL) 896 if (phb == NULL)
769 continue; 897 continue;
898 /* All legacy iSeries PHBs are in domain zero */
899 phb->global_number = 0;
770 900
771 phb->pci_mem_offset = bus;
772 phb->first_busno = bus; 901 phb->first_busno = bus;
773 phb->last_busno = bus; 902 phb->last_busno = bus;
774 phb->ops = &iSeries_pci_ops; 903 phb->ops = &iSeries_pci_ops;
904 phb->io_base_virt = (void __iomem *)_IO_BASE;
905 phb->io_resource.flags = IORESOURCE_IO;
906 phb->io_resource.start = BASE_IO_MEMORY;
907 phb->io_resource.end = END_IO_MEMORY;
908 phb->io_resource.name = "iSeries PCI IO";
909 phb->mem_resources[0].flags = IORESOURCE_MEM;
910 phb->mem_resources[0].start = BASE_IO_MEMORY;
911 phb->mem_resources[0].end = END_IO_MEMORY;
912 phb->mem_resources[0].name = "Series PCI MEM";
775 } 913 }
776 914
777 of_node_put(root); 915 of_node_put(root);
diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h
index 33a8489fde54..d9cf974c2718 100644
--- a/arch/powerpc/platforms/iseries/pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -30,10 +30,6 @@
30 * End Change Activity 30 * End Change Activity
31 */ 31 */
32 32
33#include <asm/pci-bridge.h>
34
35struct pci_dev; /* For Forward Reference */
36
37/* 33/*
38 * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. 34 * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
39 * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h 35 * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
@@ -47,17 +43,16 @@ struct pci_dev; /* For Forward Reference */
47#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) 43#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7)
48#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) 44#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
49 45
50/* 46struct pci_dev;
51 * Generate a Direct Select Address for the Hypervisor 47
52 */ 48#ifdef CONFIG_PCI
53static inline u64 iseries_ds_addr(struct device_node *node) 49extern void iSeries_pcibios_init(void);
54{ 50extern void iSeries_pci_final_fixup(void);
55 struct pci_dn *pdn = PCI_DN(node); 51extern void iSeries_pcibios_fixup_resources(struct pci_dev *dev);
56 52#else
57 return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40) 53static inline void iSeries_pcibios_init(void) { }
58 + ((u64)0x10 << 32); 54static inline void iSeries_pci_final_fixup(void) { }
59} 55static inline void iSeries_pcibios_fixup_resources(struct pci_dev *dev) {}
60 56#endif
61extern void iSeries_Device_Information(struct pci_dev*, int);
62 57
63#endif /* _PLATFORMS_ISERIES_PCI_H */ 58#endif /* _PLATFORMS_ISERIES_PCI_H */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 0877a8834110..b72120751bbe 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -63,6 +63,7 @@
63#include "main_store.h" 63#include "main_store.h"
64#include "call_sm.h" 64#include "call_sm.h"
65#include "call_hpt.h" 65#include "call_hpt.h"
66#include "pci.h"
66 67
67#ifdef DEBUG 68#ifdef DEBUG
68#define DBG(fmt...) udbg_printf(fmt) 69#define DBG(fmt...) udbg_printf(fmt)
@@ -74,11 +75,6 @@
74static unsigned long build_iSeries_Memory_Map(void); 75static unsigned long build_iSeries_Memory_Map(void);
75static void iseries_shared_idle(void); 76static void iseries_shared_idle(void);
76static void iseries_dedicated_idle(void); 77static void iseries_dedicated_idle(void);
77#ifdef CONFIG_PCI
78extern void iSeries_pci_final_fixup(void);
79#else
80static void iSeries_pci_final_fixup(void) { }
81#endif
82 78
83 79
84struct MemoryBlock { 80struct MemoryBlock {
@@ -112,13 +108,13 @@ static unsigned long iSeries_process_Condor_mainstore_vpd(
112 * correctly. 108 * correctly.
113 */ 109 */
114 mb_array[0].logicalStart = 0; 110 mb_array[0].logicalStart = 0;
115 mb_array[0].logicalEnd = 0x100000000; 111 mb_array[0].logicalEnd = 0x100000000UL;
116 mb_array[0].absStart = 0; 112 mb_array[0].absStart = 0;
117 mb_array[0].absEnd = 0x100000000; 113 mb_array[0].absEnd = 0x100000000UL;
118 114
119 if (holeSize) { 115 if (holeSize) {
120 numMemoryBlocks = 2; 116 numMemoryBlocks = 2;
121 holeStart = holeStart & 0x000fffffffffffff; 117 holeStart = holeStart & 0x000fffffffffffffUL;
122 holeStart = addr_to_chunk(holeStart); 118 holeStart = addr_to_chunk(holeStart);
123 holeFirstChunk = holeStart; 119 holeFirstChunk = holeStart;
124 holeSize = addr_to_chunk(holeSize); 120 holeSize = addr_to_chunk(holeSize);
@@ -128,9 +124,9 @@ static unsigned long iSeries_process_Condor_mainstore_vpd(
128 mb_array[0].logicalEnd = holeFirstChunk; 124 mb_array[0].logicalEnd = holeFirstChunk;
129 mb_array[0].absEnd = holeFirstChunk; 125 mb_array[0].absEnd = holeFirstChunk;
130 mb_array[1].logicalStart = holeFirstChunk; 126 mb_array[1].logicalStart = holeFirstChunk;
131 mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks; 127 mb_array[1].logicalEnd = 0x100000000UL - holeSizeChunks;
132 mb_array[1].absStart = holeFirstChunk + holeSizeChunks; 128 mb_array[1].absStart = holeFirstChunk + holeSizeChunks;
133 mb_array[1].absEnd = 0x100000000; 129 mb_array[1].absEnd = 0x100000000UL;
134 } 130 }
135 return numMemoryBlocks; 131 return numMemoryBlocks;
136} 132}
@@ -234,9 +230,9 @@ static unsigned long iSeries_process_Regatta_mainstore_vpd(
234 mb_array[i].logicalEnd, 230 mb_array[i].logicalEnd,
235 mb_array[i].absStart, mb_array[i].absEnd); 231 mb_array[i].absStart, mb_array[i].absEnd);
236 mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart & 232 mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart &
237 0x000fffffffffffff); 233 0x000fffffffffffffUL);
238 mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd & 234 mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd &
239 0x000fffffffffffff); 235 0x000fffffffffffffUL);
240 mb_array[i].logicalStart = 236 mb_array[i].logicalStart =
241 addr_to_chunk(mb_array[i].logicalStart); 237 addr_to_chunk(mb_array[i].logicalStart);
242 mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd); 238 mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd);
@@ -320,7 +316,7 @@ struct mschunks_map mschunks_map = {
320}; 316};
321EXPORT_SYMBOL(mschunks_map); 317EXPORT_SYMBOL(mschunks_map);
322 318
323void mschunks_alloc(unsigned long num_chunks) 319static void mschunks_alloc(unsigned long num_chunks)
324{ 320{
325 klimit = _ALIGN(klimit, sizeof(u32)); 321 klimit = _ALIGN(klimit, sizeof(u32));
326 mschunks_map.mapping = (u32 *)klimit; 322 mschunks_map.mapping = (u32 *)klimit;
@@ -499,6 +495,8 @@ static void __init iSeries_setup_arch(void)
499 itVpdAreas.xSlicMaxLogicalProcs); 495 itVpdAreas.xSlicMaxLogicalProcs);
500 printk("Max physical processors = %d\n", 496 printk("Max physical processors = %d\n",
501 itVpdAreas.xSlicMaxPhysicalProcs); 497 itVpdAreas.xSlicMaxPhysicalProcs);
498
499 iSeries_pcibios_init();
502} 500}
503 501
504static void iSeries_show_cpuinfo(struct seq_file *m) 502static void iSeries_show_cpuinfo(struct seq_file *m)
@@ -641,24 +639,25 @@ static int __init iseries_probe(void)
641} 639}
642 640
643define_machine(iseries) { 641define_machine(iseries) {
644 .name = "iSeries", 642 .name = "iSeries",
645 .setup_arch = iSeries_setup_arch, 643 .setup_arch = iSeries_setup_arch,
646 .show_cpuinfo = iSeries_show_cpuinfo, 644 .show_cpuinfo = iSeries_show_cpuinfo,
647 .init_IRQ = iSeries_init_IRQ, 645 .init_IRQ = iSeries_init_IRQ,
648 .get_irq = iSeries_get_irq, 646 .get_irq = iSeries_get_irq,
649 .init_early = iSeries_init_early, 647 .init_early = iSeries_init_early,
650 .pcibios_fixup = iSeries_pci_final_fixup, 648 .pcibios_fixup = iSeries_pci_final_fixup,
651 .restart = mf_reboot, 649 .pcibios_fixup_resources= iSeries_pcibios_fixup_resources,
652 .power_off = mf_power_off, 650 .restart = mf_reboot,
653 .halt = mf_power_off, 651 .power_off = mf_power_off,
654 .get_boot_time = iSeries_get_boot_time, 652 .halt = mf_power_off,
655 .set_rtc_time = iSeries_set_rtc_time, 653 .get_boot_time = iSeries_get_boot_time,
656 .get_rtc_time = iSeries_get_rtc_time, 654 .set_rtc_time = iSeries_set_rtc_time,
657 .calibrate_decr = generic_calibrate_decr, 655 .get_rtc_time = iSeries_get_rtc_time,
658 .progress = iSeries_progress, 656 .calibrate_decr = generic_calibrate_decr,
659 .probe = iseries_probe, 657 .progress = iSeries_progress,
660 .ioremap = iseries_ioremap, 658 .probe = iseries_probe,
661 .iounmap = iseries_iounmap, 659 .ioremap = iseries_ioremap,
660 .iounmap = iseries_iounmap,
662 /* XXX Implement enable_pmcs for iSeries */ 661 /* XXX Implement enable_pmcs for iSeries */
663}; 662};
664 663
diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h
index 0a47ac53c959..729754bbb018 100644
--- a/arch/powerpc/platforms/iseries/setup.h
+++ b/arch/powerpc/platforms/iseries/setup.h
@@ -17,6 +17,7 @@
17#ifndef __ISERIES_SETUP_H__ 17#ifndef __ISERIES_SETUP_H__
18#define __ISERIES_SETUP_H__ 18#define __ISERIES_SETUP_H__
19 19
20extern void *iSeries_early_setup(void);
20extern unsigned long iSeries_get_boot_time(void); 21extern unsigned long iSeries_get_boot_time(void);
21extern int iSeries_set_rtc_time(struct rtc_time *tm); 22extern int iSeries_set_rtc_time(struct rtc_time *tm);
22extern void iSeries_get_rtc_time(struct rtc_time *tm); 23extern void iSeries_get_rtc_time(struct rtc_time *tm);
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
deleted file mode 100644
index 9f83878a0c2e..000000000000
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * This code gets the card location of the hardware
3 * Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
4 * Copyright (C) 2005 Stephen Rothwel, IBM Corp
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the:
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307 USA
21 *
22 * Change Activity:
23 * Created, Feb 2, 2001
24 * Ported to ppc64, August 20, 2001
25 * End Change Activity
26 */
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/pci.h>
30
31#include <asm/types.h>
32#include <asm/resource.h>
33#include <asm/abs_addr.h>
34#include <asm/pci-bridge.h>
35#include <asm/iseries/hv_types.h>
36
37#include "pci.h"
38#include "call_pci.h"
39
40/*
41 * Size of Bus VPD data
42 */
43#define BUS_VPDSIZE 1024
44
45/*
46 * Bus Vpd Tags
47 */
48#define VpdEndOfAreaTag 0x79
49#define VpdIdStringTag 0x82
50#define VpdVendorAreaTag 0x84
51
52/*
53 * Mfg Area Tags
54 */
55#define VpdFruFrameId 0x4649 // "FI"
56#define VpdSlotMapFormat 0x4D46 // "MF"
57#define VpdSlotMap 0x534D // "SM"
58
59/*
60 * Structures of the areas
61 */
62struct MfgVpdAreaStruct {
63 u16 Tag;
64 u8 TagLength;
65 u8 AreaData1;
66 u8 AreaData2;
67};
68typedef struct MfgVpdAreaStruct MfgArea;
69#define MFG_ENTRY_SIZE 3
70
71struct SlotMapStruct {
72 u8 AgentId;
73 u8 SecondaryAgentId;
74 u8 PhbId;
75 char CardLocation[3];
76 char Parms[8];
77 char Reserved[2];
78};
79typedef struct SlotMapStruct SlotMap;
80#define SLOT_ENTRY_SIZE 16
81
82/*
83 * Parse the Slot Area
84 */
85static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
86 HvAgentId agent, u8 *PhbId, char card[4])
87{
88 int SlotMapLen = MapLen;
89 SlotMap *SlotMapPtr = MapPtr;
90
91 /*
92 * Parse Slot label until we find the one requested
93 */
94 while (SlotMapLen > 0) {
95 if (SlotMapPtr->AgentId == agent) {
96 /*
97 * If Phb wasn't found, grab the entry first one found.
98 */
99 if (*PhbId == 0xff)
100 *PhbId = SlotMapPtr->PhbId;
101 /* Found it, extract the data. */
102 if (SlotMapPtr->PhbId == *PhbId) {
103 memcpy(card, &SlotMapPtr->CardLocation, 3);
104 card[3] = 0;
105 break;
106 }
107 }
108 /* Point to the next Slot */
109 SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
110 SlotMapLen -= SLOT_ENTRY_SIZE;
111 }
112}
113
114/*
115 * Parse the Mfg Area
116 */
117static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
118 HvAgentId agent, u8 *PhbId,
119 u8 *frame, char card[4])
120{
121 MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
122 int MfgAreaLen = AreaLen;
123 u16 SlotMapFmt = 0;
124
125 /* Parse Mfg Data */
126 while (MfgAreaLen > 0) {
127 int MfgTagLen = MfgAreaPtr->TagLength;
128 /* Frame ID (FI 4649020310 ) */
129 if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */
130 *frame = MfgAreaPtr->AreaData1;
131 /* Slot Map Format (MF 4D46020004 ) */
132 else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */
133 SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
134 + MfgAreaPtr->AreaData2;
135 /* Slot Map (SM 534D90 */
136 else if (MfgAreaPtr->Tag == VpdSlotMap) { /* SM */
137 SlotMap *SlotMapPtr;
138
139 if (SlotMapFmt == 0x1004)
140 SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
141 + MFG_ENTRY_SIZE + 1);
142 else
143 SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
144 + MFG_ENTRY_SIZE);
145 iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
146 agent, PhbId, card);
147 }
148 /*
149 * Point to the next Mfg Area
150 * Use defined size, sizeof give wrong answer
151 */
152 MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
153 + MFG_ENTRY_SIZE);
154 MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
155 }
156}
157
158/*
159 * Look for "BUS".. Data is not Null terminated.
160 * PHBID of 0xFF indicates PHB was not found in VPD Data.
161 */
162static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
163{
164 u8 *PhbPtr = AreaPtr;
165 int DataLen = AreaLength;
166 char PhbId = 0xFF;
167
168 while (DataLen > 0) {
169 if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
170 && (*(PhbPtr + 2) == 'S')) {
171 PhbPtr += 3;
172 while (*PhbPtr == ' ')
173 ++PhbPtr;
174 PhbId = (*PhbPtr & 0x0F);
175 break;
176 }
177 ++PhbPtr;
178 --DataLen;
179 }
180 return PhbId;
181}
182
183/*
184 * Parse out the VPD Areas
185 */
186static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
187 HvAgentId agent, u8 *frame, char card[4])
188{
189 u8 *TagPtr = VpdData;
190 int DataLen = VpdDataLen - 3;
191 u8 PhbId = 0xff;
192
193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
195 u8 *AreaData = TagPtr + 3;
196
197 if (*TagPtr == VpdIdStringTag)
198 PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
199 else if (*TagPtr == VpdVendorAreaTag)
200 iSeries_Parse_MfgArea(AreaData, AreaLen,
201 agent, &PhbId, frame, card);
202 /* Point to next Area. */
203 TagPtr = AreaData + AreaLen;
204 DataLen -= AreaLen;
205 }
206}
207
208static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
209 u8 *frame, char card[4])
210{
211 int status = 0;
212 int BusVpdLen = 0;
213 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
214
215 if (BusVpdPtr == NULL) {
216 printk("PCI: Bus VPD Buffer allocation failure.\n");
217 return 0;
218 }
219 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
220 BUS_VPDSIZE);
221 if (BusVpdLen == 0) {
222 printk("PCI: Bus VPD Buffer zero length.\n");
223 goto out_free;
224 }
225 /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
226 /* Make sure this is what I think it is */
227 if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */
228 printk("PCI: Bus VPD Buffer missing starting tag.\n");
229 goto out_free;
230 }
231 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
232 status = 1;
233out_free:
234 kfree(BusVpdPtr);
235 return status;
236}
237
238/*
239 * Prints the device information.
240 * - Pass in pci_dev* pointer to the device.
241 * - Pass in the device count
242 *
243 * Format:
244 * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
245 * controller
246 */
247void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
248{
249 struct device_node *DevNode = PciDev->sysdata;
250 struct pci_dn *pdn;
251 u16 bus;
252 u8 frame = 0;
253 char card[4];
254 HvSubBusNumber subbus;
255 HvAgentId agent;
256
257 if (DevNode == NULL) {
258 printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
259 count);
260 return;
261 }
262
263 pdn = PCI_DN(DevNode);
264 bus = pdn->busno;
265 subbus = pdn->bussubno;
266 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
267 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
268
269 if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
270 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
271 "Card %4s 0x%04X\n", count, bus,
272 PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
273 card, (int)(PciDev->class >> 8));
274 }
275}