aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/Makefile5
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c55
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c50
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c182
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c6
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c6
-rw-r--r--arch/powerpc/platforms/pseries/setup.c6
-rw-r--r--arch/powerpc/platforms/pseries/vio.c274
-rw-r--r--arch/powerpc/platforms/pseries/xics.c25
10 files changed, 169 insertions, 442 deletions
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 930898635c9f..e5e0ff466904 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,8 +1,11 @@
1ifeq ($(CONFIG_PPC64),y)
2EXTRA_CFLAGS += -mno-minimal-toc
3endif
4
1obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ 5obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
2 setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ 6 setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
3 firmware.o 7 firmware.o
4obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
5obj-$(CONFIG_IBMVIO) += vio.o
6obj-$(CONFIG_XICS) += xics.o 9obj-$(CONFIG_XICS) += xics.o
7obj-$(CONFIG_SCANLOG) += scanlog.o 10obj-$(CONFIG_SCANLOG) += scanlog.o
8obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o 11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index d4a402c5866c..98c23aec85be 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -304,6 +304,8 @@ void __init pci_addr_cache_build(void)
304 pci_addr_cache_insert_device(dev); 304 pci_addr_cache_insert_device(dev);
305 305
306 dn = pci_device_to_OF_node(dev); 306 dn = pci_device_to_OF_node(dev);
307 if (!dn)
308 continue;
307 pci_dev_get (dev); /* matching put is in eeh_remove_device() */ 309 pci_dev_get (dev); /* matching put is in eeh_remove_device() */
308 PCI_DN(dn)->pcidev = dev; 310 PCI_DN(dn)->pcidev = dev;
309 } 311 }
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 1fba695e32e8..0ec9a5445b95 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -23,9 +23,8 @@
23 * 23 *
24 */ 24 */
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/irq.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/notifier.h> 27#include <linux/irq.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
30#include <asm/eeh.h> 29#include <asm/eeh.h>
31#include <asm/eeh_event.h> 30#include <asm/eeh_event.h>
@@ -202,7 +201,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
202 201
203static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) 202static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
204{ 203{
205 int rc; 204 int cnt, rc;
205
206 /* pcibios will clear the counter; save the value */
207 cnt = pe_dn->eeh_freeze_count;
208
206 if (bus) 209 if (bus)
207 pcibios_remove_pci_devices(bus); 210 pcibios_remove_pci_devices(bus);
208 211
@@ -241,6 +244,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
241 ssleep (5); 244 ssleep (5);
242 pcibios_add_pci_devices(bus); 245 pcibios_add_pci_devices(bus);
243 } 246 }
247 pe_dn->eeh_freeze_count = cnt;
244 248
245 return 0; 249 return 0;
246} 250}
@@ -250,23 +254,29 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
250 */ 254 */
251#define MAX_WAIT_FOR_RECOVERY 15 255#define MAX_WAIT_FOR_RECOVERY 15
252 256
253void handle_eeh_events (struct eeh_event *event) 257struct pci_dn * handle_eeh_events (struct eeh_event *event)
254{ 258{
255 struct device_node *frozen_dn; 259 struct device_node *frozen_dn;
256 struct pci_dn *frozen_pdn; 260 struct pci_dn *frozen_pdn;
257 struct pci_bus *frozen_bus; 261 struct pci_bus *frozen_bus;
258 int rc = 0; 262 int rc = 0;
259 enum pci_ers_result result = PCI_ERS_RESULT_NONE; 263 enum pci_ers_result result = PCI_ERS_RESULT_NONE;
260 const char *pci_str, *drv_str; 264 const char *location, *pci_str, *drv_str;
261 265
262 frozen_dn = find_device_pe(event->dn); 266 frozen_dn = find_device_pe(event->dn);
263 frozen_bus = pcibios_find_pci_bus(frozen_dn); 267 frozen_bus = pcibios_find_pci_bus(frozen_dn);
264 268
265 if (!frozen_dn) { 269 if (!frozen_dn) {
266 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n", 270
267 pci_name(event->dev)); 271 location = (char *) get_property(event->dn, "ibm,loc-code", NULL);
268 return; 272 location = location ? location : "unknown";
273 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
274 "for location=%s pci addr=%s\n",
275 location, pci_name(event->dev));
276 return NULL;
269 } 277 }
278 location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL);
279 location = location ? location : "unknown";
270 280
271 /* There are two different styles for coming up with the PE. 281 /* There are two different styles for coming up with the PE.
272 * In the old style, it was the highest EEH-capable device 282 * In the old style, it was the highest EEH-capable device
@@ -278,9 +288,10 @@ void handle_eeh_events (struct eeh_event *event)
278 frozen_bus = pcibios_find_pci_bus (frozen_dn->parent); 288 frozen_bus = pcibios_find_pci_bus (frozen_dn->parent);
279 289
280 if (!frozen_bus) { 290 if (!frozen_bus) {
281 printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n", 291 printk(KERN_ERR "EEH: Cannot find PCI bus "
282 frozen_dn->full_name); 292 "for location=%s dn=%s\n",
283 return; 293 location, frozen_dn->full_name);
294 return NULL;
284 } 295 }
285 296
286#if 0 297#if 0
@@ -314,8 +325,9 @@ void handle_eeh_events (struct eeh_event *event)
314 325
315 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); 326 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
316 printk(KERN_WARNING 327 printk(KERN_WARNING
317 "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", 328 "EEH: This PCI device has failed %d times since last reboot: "
318 frozen_pdn->eeh_freeze_count, drv_str, pci_str); 329 "location=%s driver=%s pci addr=%s\n",
330 frozen_pdn->eeh_freeze_count, location, drv_str, pci_str);
319 331
320 /* Walk the various device drivers attached to this slot through 332 /* Walk the various device drivers attached to this slot through
321 * a reset sequence, giving each an opportunity to do what it needs 333 * a reset sequence, giving each an opportunity to do what it needs
@@ -355,7 +367,7 @@ void handle_eeh_events (struct eeh_event *event)
355 /* Tell all device drivers that they can resume operations */ 367 /* Tell all device drivers that they can resume operations */
356 pci_walk_bus(frozen_bus, eeh_report_resume, NULL); 368 pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
357 369
358 return; 370 return frozen_pdn;
359 371
360excess_failures: 372excess_failures:
361 /* 373 /*
@@ -364,17 +376,18 @@ excess_failures:
364 * due to actual, failed cards. 376 * due to actual, failed cards.
365 */ 377 */
366 printk(KERN_ERR 378 printk(KERN_ERR
367 "EEH: PCI device %s - %s has failed %d times \n" 379 "EEH: PCI device at location=%s driver=%s pci addr=%s \n"
368 "and has been permanently disabled. Please try reseating\n" 380 "has failed %d times and has been permanently disabled. \n"
369 "this device or replacing it.\n", 381 "Please try reseating this device or replacing it.\n",
370 drv_str, pci_str, frozen_pdn->eeh_freeze_count); 382 location, drv_str, pci_str, frozen_pdn->eeh_freeze_count);
371 goto perm_error; 383 goto perm_error;
372 384
373hard_fail: 385hard_fail:
374 printk(KERN_ERR 386 printk(KERN_ERR
375 "EEH: Unable to recover from failure of PCI device %s - %s\n" 387 "EEH: Unable to recover from failure of PCI device "
388 "at location=%s driver=%s pci addr=%s \n"
376 "Please try reseating this device or replacing it.\n", 389 "Please try reseating this device or replacing it.\n",
377 drv_str, pci_str); 390 location, drv_str, pci_str);
378 391
379perm_error: 392perm_error:
380 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); 393 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
@@ -384,6 +397,8 @@ perm_error:
384 397
385 /* Shut down the device drivers for good. */ 398 /* Shut down the device drivers for good. */
386 pcibios_remove_pci_devices(frozen_bus); 399 pcibios_remove_pci_devices(frozen_bus);
400
401 return NULL;
387} 402}
388 403
389/* ---------- end of file ---------- */ 404/* ---------- end of file ---------- */
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index 40020c65c89e..8f2d12935b99 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -18,6 +18,7 @@
18 * Copyright (c) 2005 Linas Vepstas <linas@linas.org> 18 * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
19 */ 19 */
20 20
21#include <linux/delay.h>
21#include <linux/list.h> 22#include <linux/list.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23#include <linux/pci.h> 24#include <linux/pci.h>
@@ -56,38 +57,43 @@ static int eeh_event_handler(void * dummy)
56{ 57{
57 unsigned long flags; 58 unsigned long flags;
58 struct eeh_event *event; 59 struct eeh_event *event;
60 struct pci_dn *pdn;
59 61
60 daemonize ("eehd"); 62 daemonize ("eehd");
63 set_current_state(TASK_INTERRUPTIBLE);
61 64
62 while (1) { 65 spin_lock_irqsave(&eeh_eventlist_lock, flags);
63 set_current_state(TASK_INTERRUPTIBLE); 66 event = NULL;
64 67
65 spin_lock_irqsave(&eeh_eventlist_lock, flags); 68 /* Unqueue the event, get ready to process. */
66 event = NULL; 69 if (!list_empty(&eeh_eventlist)) {
70 event = list_entry(eeh_eventlist.next, struct eeh_event, list);
71 list_del(&event->list);
72 }
73 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
67 74
68 /* Unqueue the event, get ready to process. */ 75 if (event == NULL)
69 if (!list_empty(&eeh_eventlist)) { 76 return 0;
70 event = list_entry(eeh_eventlist.next, struct eeh_event, list);
71 list_del(&event->list);
72 }
73 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
74 77
75 if (event == NULL) 78 /* Serialize processing of EEH events */
76 break; 79 mutex_lock(&eeh_event_mutex);
80 eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
77 81
78 /* Serialize processing of EEH events */ 82 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
79 mutex_lock(&eeh_event_mutex); 83 pci_name(event->dev));
80 eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
81 84
82 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", 85 pdn = handle_eeh_events(event);
83 pci_name(event->dev));
84 86
85 handle_eeh_events(event); 87 eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
88 pci_dev_put(event->dev);
89 kfree(event);
90 mutex_unlock(&eeh_event_mutex);
86 91
87 eeh_clear_slot(event->dn, EEH_MODE_RECOVERING); 92 /* If there are no new errors after an hour, clear the counter. */
88 pci_dev_put(event->dev); 93 if (pdn && pdn->eeh_freeze_count>0) {
89 kfree(event); 94 msleep_interruptible (3600*1000);
90 mutex_unlock(&eeh_event_mutex); 95 if (pdn->eeh_freeze_count>0)
96 pdn->eeh_freeze_count--;
91 } 97 }
92 98
93 return 0; 99 return 0;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 2643078433f0..d03a8b078f9d 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1,23 +1,24 @@
1/* 1/*
2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
3 * 3 *
4 * Rewrite, cleanup: 4 * Rewrite, cleanup:
5 * 5 *
6 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation 6 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
7 * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
7 * 8 *
8 * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. 9 * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
9 * 10 *
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 14 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 15 * (at your option) any later version.
15 * 16 *
16 * This program is distributed in the hope that it will be useful, 17 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details. 20 * GNU General Public License for more details.
20 * 21 *
21 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 23 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -49,52 +50,46 @@
49 50
50#define DBG(fmt...) 51#define DBG(fmt...)
51 52
52static void tce_build_pSeries(struct iommu_table *tbl, long index, 53static void tce_build_pSeries(struct iommu_table *tbl, long index,
53 long npages, unsigned long uaddr, 54 long npages, unsigned long uaddr,
54 enum dma_data_direction direction) 55 enum dma_data_direction direction)
55{ 56{
56 union tce_entry t; 57 u64 proto_tce;
57 union tce_entry *tp; 58 u64 *tcep;
59 u64 rpn;
58 60
59 index <<= TCE_PAGE_FACTOR; 61 index <<= TCE_PAGE_FACTOR;
60 npages <<= TCE_PAGE_FACTOR; 62 npages <<= TCE_PAGE_FACTOR;
61 63
62 t.te_word = 0; 64 proto_tce = TCE_PCI_READ; // Read allowed
63 t.te_rdwr = 1; // Read allowed
64 65
65 if (direction != DMA_TO_DEVICE) 66 if (direction != DMA_TO_DEVICE)
66 t.te_pciwr = 1; 67 proto_tce |= TCE_PCI_WRITE;
67 68
68 tp = ((union tce_entry *)tbl->it_base) + index; 69 tcep = ((u64 *)tbl->it_base) + index;
69 70
70 while (npages--) { 71 while (npages--) {
71 /* can't move this out since we might cross LMB boundary */ 72 /* can't move this out since we might cross LMB boundary */
72 t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; 73 rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
73 74 *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
74 tp->te_word = t.te_word;
75 75
76 uaddr += TCE_PAGE_SIZE; 76 uaddr += TCE_PAGE_SIZE;
77 tp++; 77 tcep++;
78 } 78 }
79} 79}
80 80
81 81
82static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) 82static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
83{ 83{
84 union tce_entry t; 84 u64 *tcep;
85 union tce_entry *tp;
86 85
87 npages <<= TCE_PAGE_FACTOR; 86 npages <<= TCE_PAGE_FACTOR;
88 index <<= TCE_PAGE_FACTOR; 87 index <<= TCE_PAGE_FACTOR;
89 88
90 t.te_word = 0; 89 tcep = ((u64 *)tbl->it_base) + index;
91 tp = ((union tce_entry *)tbl->it_base) + index; 90
92 91 while (npages--)
93 while (npages--) { 92 *(tcep++) = 0;
94 tp->te_word = t.te_word;
95
96 tp++;
97 }
98} 93}
99 94
100 95
@@ -103,43 +98,44 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
103 enum dma_data_direction direction) 98 enum dma_data_direction direction)
104{ 99{
105 u64 rc; 100 u64 rc;
106 union tce_entry tce; 101 u64 proto_tce, tce;
102 u64 rpn;
107 103
108 tcenum <<= TCE_PAGE_FACTOR; 104 tcenum <<= TCE_PAGE_FACTOR;
109 npages <<= TCE_PAGE_FACTOR; 105 npages <<= TCE_PAGE_FACTOR;
110 106
111 tce.te_word = 0; 107 rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
112 tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; 108 proto_tce = TCE_PCI_READ;
113 tce.te_rdwr = 1;
114 if (direction != DMA_TO_DEVICE) 109 if (direction != DMA_TO_DEVICE)
115 tce.te_pciwr = 1; 110 proto_tce |= TCE_PCI_WRITE;
116 111
117 while (npages--) { 112 while (npages--) {
118 rc = plpar_tce_put((u64)tbl->it_index, 113 tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
119 (u64)tcenum << 12, 114 rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
120 tce.te_word ); 115
121
122 if (rc && printk_ratelimit()) { 116 if (rc && printk_ratelimit()) {
123 printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); 117 printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
124 printk("\tindex = 0x%lx\n", (u64)tbl->it_index); 118 printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
125 printk("\ttcenum = 0x%lx\n", (u64)tcenum); 119 printk("\ttcenum = 0x%lx\n", (u64)tcenum);
126 printk("\ttce val = 0x%lx\n", tce.te_word ); 120 printk("\ttce val = 0x%lx\n", tce );
127 show_stack(current, (unsigned long *)__get_SP()); 121 show_stack(current, (unsigned long *)__get_SP());
128 } 122 }
129 123
130 tcenum++; 124 tcenum++;
131 tce.te_rpn++; 125 rpn++;
132 } 126 }
133} 127}
134 128
135static DEFINE_PER_CPU(void *, tce_page) = NULL; 129static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
136 130
137static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, 131static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
138 long npages, unsigned long uaddr, 132 long npages, unsigned long uaddr,
139 enum dma_data_direction direction) 133 enum dma_data_direction direction)
140{ 134{
141 u64 rc; 135 u64 rc;
142 union tce_entry tce, *tcep; 136 u64 proto_tce;
137 u64 *tcep;
138 u64 rpn;
143 long l, limit; 139 long l, limit;
144 140
145 if (TCE_PAGE_FACTOR == 0 && npages == 1) 141 if (TCE_PAGE_FACTOR == 0 && npages == 1)
@@ -152,7 +148,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
152 * from iommu_alloc{,_sg}() 148 * from iommu_alloc{,_sg}()
153 */ 149 */
154 if (!tcep) { 150 if (!tcep) {
155 tcep = (void *)__get_free_page(GFP_ATOMIC); 151 tcep = (u64 *)__get_free_page(GFP_ATOMIC);
156 /* If allocation fails, fall back to the loop implementation */ 152 /* If allocation fails, fall back to the loop implementation */
157 if (!tcep) 153 if (!tcep)
158 return tce_build_pSeriesLP(tbl, tcenum, npages, 154 return tce_build_pSeriesLP(tbl, tcenum, npages,
@@ -163,11 +159,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
163 tcenum <<= TCE_PAGE_FACTOR; 159 tcenum <<= TCE_PAGE_FACTOR;
164 npages <<= TCE_PAGE_FACTOR; 160 npages <<= TCE_PAGE_FACTOR;
165 161
166 tce.te_word = 0; 162 rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
167 tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; 163 proto_tce = TCE_PCI_READ;
168 tce.te_rdwr = 1;
169 if (direction != DMA_TO_DEVICE) 164 if (direction != DMA_TO_DEVICE)
170 tce.te_pciwr = 1; 165 proto_tce |= TCE_PCI_WRITE;
171 166
172 /* We can map max one pageful of TCEs at a time */ 167 /* We can map max one pageful of TCEs at a time */
173 do { 168 do {
@@ -175,11 +170,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
175 * Set up the page with TCE data, looping through and setting 170 * Set up the page with TCE data, looping through and setting
176 * the values. 171 * the values.
177 */ 172 */
178 limit = min_t(long, npages, 4096/sizeof(union tce_entry)); 173 limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
179 174
180 for (l = 0; l < limit; l++) { 175 for (l = 0; l < limit; l++) {
181 tcep[l] = tce; 176 tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
182 tce.te_rpn++; 177 rpn++;
183 } 178 }
184 179
185 rc = plpar_tce_put_indirect((u64)tbl->it_index, 180 rc = plpar_tce_put_indirect((u64)tbl->it_index,
@@ -195,7 +190,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
195 printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); 190 printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
196 printk("\tindex = 0x%lx\n", (u64)tbl->it_index); 191 printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
197 printk("\tnpages = 0x%lx\n", (u64)npages); 192 printk("\tnpages = 0x%lx\n", (u64)npages);
198 printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word); 193 printk("\ttce[0] val = 0x%lx\n", tcep[0]);
199 show_stack(current, (unsigned long *)__get_SP()); 194 show_stack(current, (unsigned long *)__get_SP());
200 } 195 }
201} 196}
@@ -203,23 +198,17 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
203static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) 198static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
204{ 199{
205 u64 rc; 200 u64 rc;
206 union tce_entry tce;
207 201
208 tcenum <<= TCE_PAGE_FACTOR; 202 tcenum <<= TCE_PAGE_FACTOR;
209 npages <<= TCE_PAGE_FACTOR; 203 npages <<= TCE_PAGE_FACTOR;
210 204
211 tce.te_word = 0;
212
213 while (npages--) { 205 while (npages--) {
214 rc = plpar_tce_put((u64)tbl->it_index, 206 rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
215 (u64)tcenum << 12,
216 tce.te_word);
217 207
218 if (rc && printk_ratelimit()) { 208 if (rc && printk_ratelimit()) {
219 printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); 209 printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
220 printk("\tindex = 0x%lx\n", (u64)tbl->it_index); 210 printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
221 printk("\ttcenum = 0x%lx\n", (u64)tcenum); 211 printk("\ttcenum = 0x%lx\n", (u64)tcenum);
222 printk("\ttce val = 0x%lx\n", tce.te_word );
223 show_stack(current, (unsigned long *)__get_SP()); 212 show_stack(current, (unsigned long *)__get_SP());
224 } 213 }
225 214
@@ -231,31 +220,24 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
231static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) 220static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
232{ 221{
233 u64 rc; 222 u64 rc;
234 union tce_entry tce;
235 223
236 tcenum <<= TCE_PAGE_FACTOR; 224 tcenum <<= TCE_PAGE_FACTOR;
237 npages <<= TCE_PAGE_FACTOR; 225 npages <<= TCE_PAGE_FACTOR;
238 226
239 tce.te_word = 0; 227 rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
240
241 rc = plpar_tce_stuff((u64)tbl->it_index,
242 (u64)tcenum << 12,
243 tce.te_word,
244 npages);
245 228
246 if (rc && printk_ratelimit()) { 229 if (rc && printk_ratelimit()) {
247 printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); 230 printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
248 printk("\trc = %ld\n", rc); 231 printk("\trc = %ld\n", rc);
249 printk("\tindex = 0x%lx\n", (u64)tbl->it_index); 232 printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
250 printk("\tnpages = 0x%lx\n", (u64)npages); 233 printk("\tnpages = 0x%lx\n", (u64)npages);
251 printk("\ttce val = 0x%lx\n", tce.te_word );
252 show_stack(current, (unsigned long *)__get_SP()); 234 show_stack(current, (unsigned long *)__get_SP());
253 } 235 }
254} 236}
255 237
256static void iommu_table_setparms(struct pci_controller *phb, 238static void iommu_table_setparms(struct pci_controller *phb,
257 struct device_node *dn, 239 struct device_node *dn,
258 struct iommu_table *tbl) 240 struct iommu_table *tbl)
259{ 241{
260 struct device_node *node; 242 struct device_node *node;
261 unsigned long *basep; 243 unsigned long *basep;
@@ -275,16 +257,16 @@ static void iommu_table_setparms(struct pci_controller *phb,
275 memset((void *)tbl->it_base, 0, *sizep); 257 memset((void *)tbl->it_base, 0, *sizep);
276 258
277 tbl->it_busno = phb->bus->number; 259 tbl->it_busno = phb->bus->number;
278 260
279 /* Units of tce entries */ 261 /* Units of tce entries */
280 tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; 262 tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
281 263
282 /* Test if we are going over 2GB of DMA space */ 264 /* Test if we are going over 2GB of DMA space */
283 if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { 265 if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
284 udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 266 udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
285 panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 267 panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
286 } 268 }
287 269
288 phb->dma_window_base_cur += phb->dma_window_size; 270 phb->dma_window_base_cur += phb->dma_window_size;
289 271
290 /* Set the tce table size - measured in entries */ 272 /* Set the tce table size - measured in entries */
@@ -299,30 +281,22 @@ static void iommu_table_setparms(struct pci_controller *phb,
299 * iommu_table_setparms_lpar 281 * iommu_table_setparms_lpar
300 * 282 *
301 * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. 283 * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
302 *
303 * ToDo: properly interpret the ibm,dma-window property. The definition is:
304 * logical-bus-number (1 word)
305 * phys-address (#address-cells words)
306 * size (#cell-size words)
307 *
308 * Currently we hard code these sizes (more or less).
309 */ 284 */
310static void iommu_table_setparms_lpar(struct pci_controller *phb, 285static void iommu_table_setparms_lpar(struct pci_controller *phb,
311 struct device_node *dn, 286 struct device_node *dn,
312 struct iommu_table *tbl, 287 struct iommu_table *tbl,
313 unsigned int *dma_window) 288 unsigned char *dma_window)
314{ 289{
290 unsigned long offset, size;
291
315 tbl->it_busno = PCI_DN(dn)->bussubno; 292 tbl->it_busno = PCI_DN(dn)->bussubno;
293 of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
316 294
317 /* TODO: Parse field size properties properly. */
318 tbl->it_size = (((unsigned long)dma_window[4] << 32) |
319 (unsigned long)dma_window[5]) >> PAGE_SHIFT;
320 tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
321 (unsigned long)dma_window[3]) >> PAGE_SHIFT;
322 tbl->it_base = 0; 295 tbl->it_base = 0;
323 tbl->it_index = dma_window[0];
324 tbl->it_blocksize = 16; 296 tbl->it_blocksize = 16;
325 tbl->it_type = TCE_PCI; 297 tbl->it_type = TCE_PCI;
298 tbl->it_offset = offset >> PAGE_SHIFT;
299 tbl->it_size = size >> PAGE_SHIFT;
326} 300}
327 301
328static void iommu_bus_setup_pSeries(struct pci_bus *bus) 302static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -357,13 +331,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
357 if (isa_dn_orig) 331 if (isa_dn_orig)
358 of_node_put(isa_dn_orig); 332 of_node_put(isa_dn_orig);
359 333
360 /* Count number of direct PCI children of the PHB. 334 /* Count number of direct PCI children of the PHB. */
361 * All PCI device nodes have class-code property, so it's
362 * an easy way to find them.
363 */
364 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) 335 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
365 if (get_property(tmp, "class-code", NULL)) 336 children++;
366 children++;
367 337
368 DBG("Children: %d\n", children); 338 DBG("Children: %d\n", children);
369 339
@@ -394,10 +364,11 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
394 pci->phb->dma_window_size = 0x8000000ul; 364 pci->phb->dma_window_size = 0x8000000ul;
395 pci->phb->dma_window_base_cur = 0x8000000ul; 365 pci->phb->dma_window_base_cur = 0x8000000ul;
396 366
397 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 367 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
368 pci->phb->node);
398 369
399 iommu_table_setparms(pci->phb, dn, tbl); 370 iommu_table_setparms(pci->phb, dn, tbl);
400 pci->iommu_table = iommu_init_table(tbl); 371 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
401 372
402 /* Divide the rest (1.75GB) among the children */ 373 /* Divide the rest (1.75GB) among the children */
403 pci->phb->dma_window_size = 0x80000000ul; 374 pci->phb->dma_window_size = 0x80000000ul;
@@ -414,7 +385,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
414 struct iommu_table *tbl; 385 struct iommu_table *tbl;
415 struct device_node *dn, *pdn; 386 struct device_node *dn, *pdn;
416 struct pci_dn *ppci; 387 struct pci_dn *ppci;
417 unsigned int *dma_window = NULL; 388 unsigned char *dma_window = NULL;
418 389
419 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); 390 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
420 391
@@ -422,7 +393,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
422 393
423 /* Find nearest ibm,dma-window, walking up the device tree */ 394 /* Find nearest ibm,dma-window, walking up the device tree */
424 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 395 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
425 dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); 396 dma_window = get_property(pdn, "ibm,dma-window", NULL);
426 if (dma_window != NULL) 397 if (dma_window != NULL)
427 break; 398 break;
428 } 399 }
@@ -440,12 +411,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
440 411
441 ppci->bussubno = bus->number; 412 ppci->bussubno = bus->number;
442 413
443 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 414 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
444 GFP_KERNEL); 415 ppci->phb->node);
445 416
446 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 417 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
447 418
448 ppci->iommu_table = iommu_init_table(tbl); 419 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
449 } 420 }
450 421
451 if (pdn != dn) 422 if (pdn != dn)
@@ -468,9 +439,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
468 */ 439 */
469 if (!dev->bus->self) { 440 if (!dev->bus->self) {
470 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 441 DBG(" --> first child, no bridge. Allocating iommu table.\n");
471 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 442 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
443 PCI_DN(dn)->phb->node);
472 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); 444 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
473 PCI_DN(mydn)->iommu_table = iommu_init_table(tbl); 445 PCI_DN(dn)->iommu_table = iommu_init_table(tbl,
446 PCI_DN(dn)->phb->node);
474 447
475 return; 448 return;
476 } 449 }
@@ -516,7 +489,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
516{ 489{
517 struct device_node *pdn, *dn; 490 struct device_node *pdn, *dn;
518 struct iommu_table *tbl; 491 struct iommu_table *tbl;
519 int *dma_window = NULL; 492 unsigned char *dma_window = NULL;
520 struct pci_dn *pci; 493 struct pci_dn *pci;
521 494
522 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); 495 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -531,8 +504,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
531 504
532 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 505 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
533 pdn = pdn->parent) { 506 pdn = pdn->parent) {
534 dma_window = (unsigned int *) 507 dma_window = get_property(pdn, "ibm,dma-window", NULL);
535 get_property(pdn, "ibm,dma-window", NULL);
536 if (dma_window) 508 if (dma_window)
537 break; 509 break;
538 } 510 }
@@ -553,12 +525,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
553 /* iommu_table_setparms_lpar needs bussubno. */ 525 /* iommu_table_setparms_lpar needs bussubno. */
554 pci->bussubno = pci->phb->bus->number; 526 pci->bussubno = pci->phb->bus->number;
555 527
556 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 528 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
557 GFP_KERNEL); 529 pci->phb->node);
558 530
559 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 531 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
560 532
561 pci->iommu_table = iommu_init_table(tbl); 533 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
562 } 534 }
563 535
564 if (pdn != dn) 536 if (pdn != dn)
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index e0000ce769e5..2e4e04042d85 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -348,7 +348,7 @@ static int enable_surveillance(int timeout)
348 return 0; 348 return 0;
349 349
350 if (error == -EINVAL) { 350 if (error == -EINVAL) {
351 printk(KERN_INFO "rtasd: surveillance not supported\n"); 351 printk(KERN_DEBUG "rtasd: surveillance not supported\n");
352 return 0; 352 return 0;
353 } 353 }
354 354
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
440 goto error; 440 goto error;
441 } 441 }
442 442
443 printk(KERN_INFO "RTAS daemon started\n"); 443 printk(KERN_DEBUG "RTAS daemon started\n");
444 444
445 DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); 445 DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate));
446 446
@@ -487,7 +487,7 @@ static int __init rtas_init(void)
487 487
488 /* No RTAS */ 488 /* No RTAS */
489 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { 489 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
490 printk(KERN_INFO "rtasd: no event-scan on system\n"); 490 printk(KERN_DEBUG "rtasd: no event-scan on system\n");
491 return -ENODEV; 491 return -ENODEV;
492 } 492 }
493 493
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 50643496eb63..77a5bb1d9c30 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -107,9 +107,9 @@ static ssize_t scanlog_read(struct file *file, char __user *buf,
107 /* Break to sleep default time */ 107 /* Break to sleep default time */
108 break; 108 break;
109 default: 109 default:
110 if (status > 9900 && status <= 9905) { 110 /* Assume extended busy */
111 wait_time = rtas_extended_busy_delay_time(status); 111 wait_time = rtas_busy_delay_time(status);
112 } else { 112 if (!wait_time) {
113 printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); 113 printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status);
114 return -EIO; 114 return -EIO;
115 } 115 }
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 3ba87835757e..1e28518c6121 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -235,14 +235,14 @@ static void __init pSeries_setup_arch(void)
235 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 235 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
236 vpa_init(boot_cpuid); 236 vpa_init(boot_cpuid);
237 if (get_lppaca()->shared_proc) { 237 if (get_lppaca()->shared_proc) {
238 printk(KERN_INFO "Using shared processor idle loop\n"); 238 printk(KERN_DEBUG "Using shared processor idle loop\n");
239 ppc_md.power_save = pseries_shared_idle_sleep; 239 ppc_md.power_save = pseries_shared_idle_sleep;
240 } else { 240 } else {
241 printk(KERN_INFO "Using dedicated idle loop\n"); 241 printk(KERN_DEBUG "Using dedicated idle loop\n");
242 ppc_md.power_save = pseries_dedicated_idle_sleep; 242 ppc_md.power_save = pseries_dedicated_idle_sleep;
243 } 243 }
244 } else { 244 } else {
245 printk(KERN_INFO "Using default idle loop\n"); 245 printk(KERN_DEBUG "Using default idle loop\n");
246 } 246 }
247 247
248 if (firmware_has_feature(FW_FEATURE_LPAR)) 248 if (firmware_has_feature(FW_FEATURE_LPAR))
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
deleted file mode 100644
index 8e53e04ada8b..000000000000
--- a/arch/powerpc/platforms/pseries/vio.c
+++ /dev/null
@@ -1,274 +0,0 @@
1/*
2 * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
3 *
4 * Copyright (c) 2003-2005 IBM Corp.
5 * Dave Engebretsen engebret@us.ibm.com
6 * Santiago Leon santil@us.ibm.com
7 * Hollis Blanchard <hollisb@us.ibm.com>
8 * Stephen Rothwell
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/mm.h>
19#include <linux/kobject.h>
20#include <asm/iommu.h>
21#include <asm/dma.h>
22#include <asm/prom.h>
23#include <asm/vio.h>
24#include <asm/hvcall.h>
25#include <asm/tce.h>
26
27extern struct subsystem devices_subsys; /* needed for vio_find_name() */
28
29static void probe_bus_pseries(void)
30{
31 struct device_node *node_vroot, *of_node;
32
33 node_vroot = find_devices("vdevice");
34 if ((node_vroot == NULL) || (node_vroot->child == NULL))
35 /* this machine doesn't do virtual IO, and that's ok */
36 return;
37
38 /*
39 * Create struct vio_devices for each virtual device in the device tree.
40 * Drivers will associate with them later.
41 */
42 for (of_node = node_vroot->child; of_node != NULL;
43 of_node = of_node->sibling) {
44 printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
45 vio_register_device_node(of_node);
46 }
47}
48
49/**
50 * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
51 * vio_device_id
52 */
53static int vio_match_device_pseries(const struct vio_device_id *id,
54 const struct vio_dev *dev)
55{
56 return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
57 device_is_compatible(dev->dev.platform_data, id->compat);
58}
59
60static void vio_release_device_pseries(struct device *dev)
61{
62 /* XXX free TCE table */
63 of_node_put(dev->platform_data);
64}
65
66static ssize_t viodev_show_devspec(struct device *dev,
67 struct device_attribute *attr, char *buf)
68{
69 struct device_node *of_node = dev->platform_data;
70
71 return sprintf(buf, "%s\n", of_node->full_name);
72}
73DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
74
75static void vio_unregister_device_pseries(struct vio_dev *viodev)
76{
77 device_remove_file(&viodev->dev, &dev_attr_devspec);
78}
79
80static struct vio_bus_ops vio_bus_ops_pseries = {
81 .match = vio_match_device_pseries,
82 .unregister_device = vio_unregister_device_pseries,
83 .release_device = vio_release_device_pseries,
84};
85
86/**
87 * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
88 */
89static int __init vio_bus_init_pseries(void)
90{
91 int err;
92
93 err = vio_bus_init(&vio_bus_ops_pseries);
94 if (err == 0)
95 probe_bus_pseries();
96 return err;
97}
98
99__initcall(vio_bus_init_pseries);
100
101/**
102 * vio_build_iommu_table: - gets the dma information from OF and
103 * builds the TCE tree.
104 * @dev: the virtual device.
105 *
106 * Returns a pointer to the built tce tree, or NULL if it can't
107 * find property.
108*/
109static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
110{
111 unsigned int *dma_window;
112 struct iommu_table *newTceTable;
113 unsigned long offset;
114 int dma_window_property_size;
115
116 dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
117 if(!dma_window) {
118 return NULL;
119 }
120
121 newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
122
123 /* There should be some code to extract the phys-encoded offset
124 using prom_n_addr_cells(). However, according to a comment
125 on earlier versions, it's always zero, so we don't bother */
126 offset = dma_window[1] >> PAGE_SHIFT;
127
128 /* TCE table size - measured in tce entries */
129 newTceTable->it_size = dma_window[4] >> PAGE_SHIFT;
130 /* offset for VIO should always be 0 */
131 newTceTable->it_offset = offset;
132 newTceTable->it_busno = 0;
133 newTceTable->it_index = (unsigned long)dma_window[0];
134 newTceTable->it_type = TCE_VB;
135
136 return iommu_init_table(newTceTable);
137}
138
139/**
140 * vio_register_device_node: - Register a new vio device.
141 * @of_node: The OF node for this device.
142 *
143 * Creates and initializes a vio_dev structure from the data in
144 * of_node (dev.platform_data) and adds it to the list of virtual devices.
145 * Returns a pointer to the created vio_dev or NULL if node has
146 * NULL device_type or compatible fields.
147 */
148struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
149{
150 struct vio_dev *viodev;
151 unsigned int *unit_address;
152 unsigned int *irq_p;
153
154 /* we need the 'device_type' property, in order to match with drivers */
155 if ((NULL == of_node->type)) {
156 printk(KERN_WARNING
157 "%s: node %s missing 'device_type'\n", __FUNCTION__,
158 of_node->name ? of_node->name : "<unknown>");
159 return NULL;
160 }
161
162 unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
163 if (!unit_address) {
164 printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
165 of_node->name ? of_node->name : "<unknown>");
166 return NULL;
167 }
168
169 /* allocate a vio_dev for this node */
170 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
171 if (!viodev) {
172 return NULL;
173 }
174 memset(viodev, 0, sizeof(struct vio_dev));
175
176 viodev->dev.platform_data = of_node_get(of_node);
177
178 viodev->irq = NO_IRQ;
179 irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
180 if (irq_p) {
181 int virq = virt_irq_create_mapping(*irq_p);
182 if (virq == NO_IRQ) {
183 printk(KERN_ERR "Unable to allocate interrupt "
184 "number for %s\n", of_node->full_name);
185 } else
186 viodev->irq = irq_offset_up(virq);
187 }
188
189 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
190 viodev->name = of_node->name;
191 viodev->type = of_node->type;
192 viodev->unit_address = *unit_address;
193 viodev->iommu_table = vio_build_iommu_table(viodev);
194
195 /* register with generic device framework */
196 if (vio_register_device(viodev) == NULL) {
197 /* XXX free TCE table */
198 kfree(viodev);
199 return NULL;
200 }
201 device_create_file(&viodev->dev, &dev_attr_devspec);
202
203 return viodev;
204}
205EXPORT_SYMBOL(vio_register_device_node);
206
207/**
208 * vio_get_attribute: - get attribute for virtual device
209 * @vdev: The vio device to get property.
210 * @which: The property/attribute to be extracted.
211 * @length: Pointer to length of returned data size (unused if NULL).
212 *
213 * Calls prom.c's get_property() to return the value of the
214 * attribute specified by the preprocessor constant @which
215*/
216const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
217{
218 return get_property(vdev->dev.platform_data, (char*)which, length);
219}
220EXPORT_SYMBOL(vio_get_attribute);
221
222/* vio_find_name() - internal because only vio.c knows how we formatted the
223 * kobject name
224 * XXX once vio_bus_type.devices is actually used as a kset in
225 * drivers/base/bus.c, this function should be removed in favor of
226 * "device_find(kobj_name, &vio_bus_type)"
227 */
228static struct vio_dev *vio_find_name(const char *kobj_name)
229{
230 struct kobject *found;
231
232 found = kset_find_obj(&devices_subsys.kset, kobj_name);
233 if (!found)
234 return NULL;
235
236 return to_vio_dev(container_of(found, struct device, kobj));
237}
238
239/**
240 * vio_find_node - find an already-registered vio_dev
241 * @vnode: device_node of the virtual device we're looking for
242 */
243struct vio_dev *vio_find_node(struct device_node *vnode)
244{
245 uint32_t *unit_address;
246 char kobj_name[BUS_ID_SIZE];
247
248 /* construct the kobject name from the device node */
249 unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
250 if (!unit_address)
251 return NULL;
252 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
253
254 return vio_find_name(kobj_name);
255}
256EXPORT_SYMBOL(vio_find_node);
257
258int vio_enable_interrupts(struct vio_dev *dev)
259{
260 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
261 if (rc != H_SUCCESS)
262 printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
263 return rc;
264}
265EXPORT_SYMBOL(vio_enable_interrupts);
266
267int vio_disable_interrupts(struct vio_dev *dev)
268{
269 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
270 if (rc != H_SUCCESS)
271 printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
272 return rc;
273}
274EXPORT_SYMBOL(vio_disable_interrupts);
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 2d60ea30fed6..b14f9b5c114e 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -522,7 +522,7 @@ nextnode:
522 522
523 np = of_find_node_by_type(NULL, "interrupt-controller"); 523 np = of_find_node_by_type(NULL, "interrupt-controller");
524 if (!np) { 524 if (!np) {
525 printk(KERN_WARNING "xics: no ISA interrupt controller\n"); 525 printk(KERN_DEBUG "xics: no ISA interrupt controller\n");
526 xics_irq_8259_cascade_real = -1; 526 xics_irq_8259_cascade_real = -1;
527 xics_irq_8259_cascade = -1; 527 xics_irq_8259_cascade = -1;
528 } else { 528 } else {
@@ -641,23 +641,26 @@ void xics_teardown_cpu(int secondary)
641 ops->cppr_info(cpu, 0x00); 641 ops->cppr_info(cpu, 0x00);
642 iosync(); 642 iosync();
643 643
644 /* Clear IPI */
645 ops->qirr_info(cpu, 0xff);
646
647 /*
648 * we need to EOI the IPI if we got here from kexec down IPI
649 *
650 * probably need to check all the other interrupts too
651 * should we be flagging idle loop instead?
652 * or creating some task to be scheduled?
653 */
654 ops->xirr_info_set(cpu, XICS_IPI);
655
644 /* 656 /*
645 * Some machines need to have at least one cpu in the GIQ, 657 * Some machines need to have at least one cpu in the GIQ,
646 * so leave the master cpu in the group. 658 * so leave the master cpu in the group.
647 */ 659 */
648 if (secondary) { 660 if (secondary)
649 /*
650 * we need to EOI the IPI if we got here from kexec down IPI
651 *
652 * probably need to check all the other interrupts too
653 * should we be flagging idle loop instead?
654 * or creating some task to be scheduled?
655 */
656 ops->xirr_info_set(cpu, XICS_IPI);
657 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, 661 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
658 (1UL << interrupt_server_size) - 1 - 662 (1UL << interrupt_server_size) - 1 -
659 default_distrib_server, 0); 663 default_distrib_server, 0);
660 }
661} 664}
662 665
663#ifdef CONFIG_HOTPLUG_CPU 666#ifdef CONFIG_HOTPLUG_CPU