aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/ps3
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/ps3')
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig26
-rw-r--r--arch/powerpc/platforms/ps3/Makefile1
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c785
-rw-r--r--arch/powerpc/platforms/ps3/htab.c31
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c272
-rw-r--r--arch/powerpc/platforms/ps3/mm.c632
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c4
-rw-r--r--arch/powerpc/platforms/ps3/platform.h43
-rw-r--r--arch/powerpc/platforms/ps3/repository.c586
-rw-r--r--arch/powerpc/platforms/ps3/setup.c105
-rw-r--r--arch/powerpc/platforms/ps3/smp.c18
-rw-r--r--arch/powerpc/platforms/ps3/spu.c13
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c562
-rw-r--r--arch/powerpc/platforms/ps3/time.c2
14 files changed, 2408 insertions, 672 deletions
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 40f0008af4d1..a05079b07696 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,6 +7,7 @@ config PPC_PS3
7 select USB_OHCI_BIG_ENDIAN_MMIO 7 select USB_OHCI_BIG_ENDIAN_MMIO
8 select USB_ARCH_HAS_EHCI 8 select USB_ARCH_HAS_EHCI
9 select USB_EHCI_BIG_ENDIAN_MMIO 9 select USB_EHCI_BIG_ENDIAN_MMIO
10 select MEMORY_HOTPLUG
10 help 11 help
11 This option enables support for the Sony PS3 game console 12 This option enables support for the Sony PS3 game console
12 and other platforms using the PS3 hypervisor. 13 and other platforms using the PS3 hypervisor.
@@ -73,18 +74,12 @@ config PS3_USE_LPAR_ADDR
73 74
74config PS3_VUART 75config PS3_VUART
75 depends on PPC_PS3 76 depends on PPC_PS3
76 bool "PS3 Virtual UART support" if PS3_ADVANCED 77 tristate
77 default y
78 help
79 Include support for the PS3 Virtual UART.
80
81 This support is required for several system services
82 including the System Manager and AV Settings. In
83 general, all users will say Y.
84 78
85config PS3_PS3AV 79config PS3_PS3AV
80 depends on PPC_PS3
86 tristate "PS3 AV settings driver" if PS3_ADVANCED 81 tristate "PS3 AV settings driver" if PS3_ADVANCED
87 depends on PS3_VUART 82 select PS3_VUART
88 default y 83 default y
89 help 84 help
90 Include support for the PS3 AV Settings driver. 85 Include support for the PS3 AV Settings driver.
@@ -93,13 +88,18 @@ config PS3_PS3AV
93 general, all users will say Y or M. 88 general, all users will say Y or M.
94 89
95config PS3_SYS_MANAGER 90config PS3_SYS_MANAGER
96 bool "PS3 System Manager driver" if PS3_ADVANCED 91 depends on PPC_PS3
97 depends on PS3_VUART 92 tristate "PS3 System Manager driver" if PS3_ADVANCED
98 default y 93 select PS3_VUART
94 default m
99 help 95 help
100 Include support for the PS3 System Manager. 96 Include support for the PS3 System Manager.
101 97
102 This support is required for system control. In 98 This support is required for system control. In
103 general, all users will say Y. 99 general, all users will say Y or M.
100
101config PS3_STORAGE
102 depends on PPC_PS3
103 tristate
104 104
105endmenu 105endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index a0048fcf0866..ac1bdf844eca 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -4,3 +4,4 @@ obj-y += system-bus.o
4 4
5obj-$(CONFIG_SMP) += smp.o 5obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_SPU_BASE) += spu.o 6obj-$(CONFIG_SPU_BASE) += spu.o
7obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
new file mode 100644
index 000000000000..825ebb2cbc2a
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -0,0 +1,785 @@
1/*
2 * PS3 device registration routines.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
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 Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/delay.h>
22#include <linux/freezer.h>
23#include <linux/kernel.h>
24#include <linux/kthread.h>
25#include <linux/init.h>
26
27#include <asm/firmware.h>
28#include <asm/lv1call.h>
29#include <asm/ps3stor.h>
30
31#include "platform.h"
32
33/**
34 * ps3_setup_gelic_device - Setup and register a gelic device instance.
35 *
36 * Allocates memory for a struct ps3_system_bus_device instance, initialises the
37 * structure members, and registers the device instance with the system bus.
38 */
39
40static int __init ps3_setup_gelic_device(
41 const struct ps3_repository_device *repo)
42{
43 int result;
44 struct layout {
45 struct ps3_system_bus_device dev;
46 struct ps3_dma_region d_region;
47 } *p;
48
49 pr_debug(" -> %s:%d\n", __func__, __LINE__);
50
51 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
52 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
53
54 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
55
56 if (!p) {
57 result = -ENOMEM;
58 goto fail_malloc;
59 }
60
61 p->dev.match_id = PS3_MATCH_ID_GELIC;
62 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
63 p->dev.bus_id = repo->bus_id;
64 p->dev.dev_id = repo->dev_id;
65 p->dev.d_region = &p->d_region;
66
67 result = ps3_repository_find_interrupt(repo,
68 PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
69
70 if (result) {
71 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
72 __func__, __LINE__);
73 goto fail_find_interrupt;
74 }
75
76 BUG_ON(p->dev.interrupt_id != 0);
77
78 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
79 PS3_DMA_OTHER, NULL, 0);
80
81 if (result) {
82 pr_debug("%s:%d ps3_dma_region_init failed\n",
83 __func__, __LINE__);
84 goto fail_dma_init;
85 }
86
87 result = ps3_system_bus_device_register(&p->dev);
88
89 if (result) {
90 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
91 __func__, __LINE__);
92 goto fail_device_register;
93 }
94
95 pr_debug(" <- %s:%d\n", __func__, __LINE__);
96 return result;
97
98fail_device_register:
99fail_dma_init:
100fail_find_interrupt:
101 kfree(p);
102fail_malloc:
103 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
104 return result;
105}
106
107static int __init_refok ps3_setup_uhc_device(
108 const struct ps3_repository_device *repo, enum ps3_match_id match_id,
109 enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
110{
111 int result;
112 struct layout {
113 struct ps3_system_bus_device dev;
114 struct ps3_dma_region d_region;
115 struct ps3_mmio_region m_region;
116 } *p;
117 u64 bus_addr;
118 u64 len;
119
120 pr_debug(" -> %s:%d\n", __func__, __LINE__);
121
122 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
123 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
124
125 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
126
127 if (!p) {
128 result = -ENOMEM;
129 goto fail_malloc;
130 }
131
132 p->dev.match_id = match_id;
133 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
134 p->dev.bus_id = repo->bus_id;
135 p->dev.dev_id = repo->dev_id;
136 p->dev.d_region = &p->d_region;
137 p->dev.m_region = &p->m_region;
138
139 result = ps3_repository_find_interrupt(repo,
140 interrupt_type, &p->dev.interrupt_id);
141
142 if (result) {
143 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
144 __func__, __LINE__);
145 goto fail_find_interrupt;
146 }
147
148 result = ps3_repository_find_reg(repo, reg_type,
149 &bus_addr, &len);
150
151 if (result) {
152 pr_debug("%s:%d ps3_repository_find_reg failed\n",
153 __func__, __LINE__);
154 goto fail_find_reg;
155 }
156
157 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
158 PS3_DMA_INTERNAL, NULL, 0);
159
160 if (result) {
161 pr_debug("%s:%d ps3_dma_region_init failed\n",
162 __func__, __LINE__);
163 goto fail_dma_init;
164 }
165
166 result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
167 PS3_MMIO_4K);
168
169 if (result) {
170 pr_debug("%s:%d ps3_mmio_region_init failed\n",
171 __func__, __LINE__);
172 goto fail_mmio_init;
173 }
174
175 result = ps3_system_bus_device_register(&p->dev);
176
177 if (result) {
178 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
179 __func__, __LINE__);
180 goto fail_device_register;
181 }
182
183 pr_debug(" <- %s:%d\n", __func__, __LINE__);
184 return result;
185
186fail_device_register:
187fail_mmio_init:
188fail_dma_init:
189fail_find_reg:
190fail_find_interrupt:
191 kfree(p);
192fail_malloc:
193 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
194 return result;
195}
196
197static int __init ps3_setup_ehci_device(
198 const struct ps3_repository_device *repo)
199{
200 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
201 PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
202}
203
204static int __init ps3_setup_ohci_device(
205 const struct ps3_repository_device *repo)
206{
207 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
208 PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
209}
210
211static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
212 unsigned int port_number)
213{
214 int result;
215 struct layout {
216 struct ps3_system_bus_device dev;
217 } *p;
218
219 pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
220 match_id, port_number);
221
222 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
223
224 if (!p)
225 return -ENOMEM;
226
227 p->dev.match_id = match_id;
228 p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
229 p->dev.port_number = port_number;
230
231 result = ps3_system_bus_device_register(&p->dev);
232
233 if (result)
234 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
235 __func__, __LINE__);
236
237 pr_debug(" <- %s:%d\n", __func__, __LINE__);
238 return result;
239}
240
241static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
242 unsigned int timeout)
243{
244 int result = -1;
245 unsigned int retries = 0;
246 u64 status;
247
248 for (retries = 0; retries < timeout; retries++) {
249 result = lv1_storage_check_async_status(dev_id, tag, &status);
250 if (!result)
251 break;
252
253 msleep(1);
254 }
255
256 if (result)
257 pr_debug("%s:%u: check_async_status: %s, status %lx\n",
258 __func__, __LINE__, ps3_result(result), status);
259
260 return result;
261}
262
263/**
264 * ps3_storage_wait_for_device - Wait for a storage device to become ready.
265 * @repo: The repository device to wait for.
266 *
267 * Uses the hypervisor's storage device notification mechanism to wait until
268 * a storage device is ready. The device notification mechanism uses a
269 * psuedo device (id = -1) to asynchronously notify the guest when storage
270 * devices become ready. The notification device has a block size of 512
271 * bytes.
272 */
273
274static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
275{
276 int result;
277 const u64 notification_dev_id = (u64)-1LL;
278 const unsigned int timeout = HZ;
279 u64 lpar;
280 u64 tag;
281 struct {
282 u64 operation_code; /* must be zero */
283 u64 event_mask; /* 1 = device ready */
284 } *notify_cmd;
285 struct {
286 u64 event_type; /* notify_device_ready */
287 u64 bus_id;
288 u64 dev_id;
289 u64 dev_type;
290 u64 dev_port;
291 } *notify_event;
292 enum {
293 notify_device_ready = 1
294 };
295
296 pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
297 __LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
298
299 notify_cmd = kzalloc(512, GFP_KERNEL);
300 notify_event = (void *)notify_cmd;
301 if (!notify_cmd)
302 return -ENOMEM;
303
304 lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd));
305
306 result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
307 if (result) {
308 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
309 __LINE__, ps3_result(result));
310 result = -ENODEV;
311 goto fail_free;
312 }
313
314 /* Setup and write the request for device notification. */
315
316 notify_cmd->operation_code = 0; /* must be zero */
317 notify_cmd->event_mask = 0x01; /* device ready */
318
319 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
320 &tag);
321 if (result) {
322 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
323 ps3_result(result));
324 result = -ENODEV;
325 goto fail_close;
326 }
327
328 /* Wait for the write completion */
329
330 result = ps3stor_wait_for_completion(notification_dev_id, tag,
331 timeout);
332 if (result) {
333 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
334 __LINE__, ps3_result(result));
335 result = -ENODEV;
336 goto fail_close;
337 }
338
339 /* Loop here processing the requested notification events. */
340
341 result = -ENODEV;
342 while (1) {
343 memset(notify_event, 0, sizeof(*notify_event));
344
345 result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
346 lpar, &tag);
347 if (result) {
348 printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
349 __LINE__, ps3_result(result));
350 break;
351 }
352
353 result = ps3stor_wait_for_completion(notification_dev_id, tag,
354 timeout);
355 if (result) {
356 printk(KERN_ERR "%s:%u: read not completed %s\n",
357 __func__, __LINE__, ps3_result(result));
358 break;
359 }
360
361 if (notify_event->event_type != notify_device_ready ||
362 notify_event->bus_id != repo->bus_id) {
363 pr_debug("%s:%u: bad notify_event: event %lu, "
364 "dev_id %lu, dev_type %lu\n",
365 __func__, __LINE__, notify_event->event_type,
366 notify_event->dev_id, notify_event->dev_type);
367 break;
368 }
369
370 if (notify_event->dev_id == repo->dev_id &&
371 notify_event->dev_type == repo->dev_type) {
372 pr_debug("%s:%u: device ready: dev_id %u\n", __func__,
373 __LINE__, repo->dev_id);
374 result = 0;
375 break;
376 }
377
378 if (notify_event->dev_id == repo->dev_id &&
379 notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
380 pr_debug("%s:%u: no access: dev_id %u\n", __func__,
381 __LINE__, repo->dev_id);
382 break;
383 }
384 }
385
386fail_close:
387 lv1_close_device(repo->bus_id, notification_dev_id);
388fail_free:
389 kfree(notify_cmd);
390 pr_debug(" <- %s:%u\n", __func__, __LINE__);
391 return result;
392}
393
394static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
395 enum ps3_match_id match_id)
396{
397 int result;
398 struct ps3_storage_device *p;
399 u64 port, blk_size, num_blocks;
400 unsigned int num_regions, i;
401
402 pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
403
404 result = ps3_repository_read_stor_dev_info(repo->bus_index,
405 repo->dev_index, &port,
406 &blk_size, &num_blocks,
407 &num_regions);
408 if (result) {
409 printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
410 __func__, __LINE__, result);
411 return -ENODEV;
412 }
413
414 pr_debug("%s:%u: index %u:%u: port %lu blk_size %lu num_blocks %lu "
415 "num_regions %u\n", __func__, __LINE__, repo->bus_index,
416 repo->dev_index, port, blk_size, num_blocks, num_regions);
417
418 p = kzalloc(sizeof(struct ps3_storage_device) +
419 num_regions * sizeof(struct ps3_storage_region),
420 GFP_KERNEL);
421 if (!p) {
422 result = -ENOMEM;
423 goto fail_malloc;
424 }
425
426 p->sbd.match_id = match_id;
427 p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
428 p->sbd.bus_id = repo->bus_id;
429 p->sbd.dev_id = repo->dev_id;
430 p->sbd.d_region = &p->dma_region;
431 p->blk_size = blk_size;
432 p->num_regions = num_regions;
433
434 result = ps3_repository_find_interrupt(repo,
435 PS3_INTERRUPT_TYPE_EVENT_PORT,
436 &p->sbd.interrupt_id);
437 if (result) {
438 printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
439 __LINE__, result);
440 result = -ENODEV;
441 goto fail_find_interrupt;
442 }
443
444 /* FIXME: Arrange to only do this on a 'cold' boot */
445
446 result = ps3_storage_wait_for_device(repo);
447 if (result) {
448 printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
449 __func__, __LINE__, result);
450 result = -ENODEV;
451 goto fail_probe_notification;
452 }
453
454 for (i = 0; i < num_regions; i++) {
455 unsigned int id;
456 u64 start, size;
457
458 result = ps3_repository_read_stor_dev_region(repo->bus_index,
459 repo->dev_index,
460 i, &id, &start,
461 &size);
462 if (result) {
463 printk(KERN_ERR
464 "%s:%u: read_stor_dev_region failed %d\n",
465 __func__, __LINE__, result);
466 result = -ENODEV;
467 goto fail_read_region;
468 }
469 pr_debug("%s:%u: region %u: id %u start %lu size %lu\n",
470 __func__, __LINE__, i, id, start, size);
471
472 p->regions[i].id = id;
473 p->regions[i].start = start;
474 p->regions[i].size = size;
475 }
476
477 result = ps3_system_bus_device_register(&p->sbd);
478 if (result) {
479 pr_debug("%s:%u ps3_system_bus_device_register failed\n",
480 __func__, __LINE__);
481 goto fail_device_register;
482 }
483
484 pr_debug(" <- %s:%u\n", __func__, __LINE__);
485 return 0;
486
487fail_device_register:
488fail_read_region:
489fail_probe_notification:
490fail_find_interrupt:
491 kfree(p);
492fail_malloc:
493 pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
494 return result;
495}
496
497static int __init ps3_register_vuart_devices(void)
498{
499 int result;
500 unsigned int port_number;
501
502 pr_debug(" -> %s:%d\n", __func__, __LINE__);
503
504 result = ps3_repository_read_vuart_av_port(&port_number);
505 if (result)
506 port_number = 0; /* av default */
507
508 result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
509 WARN_ON(result);
510
511 result = ps3_repository_read_vuart_sysmgr_port(&port_number);
512 if (result)
513 port_number = 2; /* sysmgr default */
514
515 result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
516 port_number);
517 WARN_ON(result);
518
519 pr_debug(" <- %s:%d\n", __func__, __LINE__);
520 return result;
521}
522
523static int __init ps3_register_sound_devices(void)
524{
525 int result;
526 struct layout {
527 struct ps3_system_bus_device dev;
528 struct ps3_dma_region d_region;
529 struct ps3_mmio_region m_region;
530 } *p;
531
532 pr_debug(" -> %s:%d\n", __func__, __LINE__);
533
534 p = kzalloc(sizeof(*p), GFP_KERNEL);
535 if (!p)
536 return -ENOMEM;
537
538 p->dev.match_id = PS3_MATCH_ID_SOUND;
539 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
540 p->dev.d_region = &p->d_region;
541 p->dev.m_region = &p->m_region;
542
543 result = ps3_system_bus_device_register(&p->dev);
544
545 if (result)
546 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
547 __func__, __LINE__);
548
549 pr_debug(" <- %s:%d\n", __func__, __LINE__);
550 return result;
551}
552
553static int __init ps3_register_graphics_devices(void)
554{
555 int result;
556 struct layout {
557 struct ps3_system_bus_device dev;
558 } *p;
559
560 pr_debug(" -> %s:%d\n", __func__, __LINE__);
561
562 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
563
564 if (!p)
565 return -ENOMEM;
566
567 p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
568 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
569
570 result = ps3_system_bus_device_register(&p->dev);
571
572 if (result)
573 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
574 __func__, __LINE__);
575
576 pr_debug(" <- %s:%d\n", __func__, __LINE__);
577 return result;
578}
579
580/**
581 * ps3_register_repository_device - Register a device from the repositiory info.
582 *
583 */
584
585static int ps3_register_repository_device(
586 const struct ps3_repository_device *repo)
587{
588 int result;
589
590 switch (repo->dev_type) {
591 case PS3_DEV_TYPE_SB_GELIC:
592 result = ps3_setup_gelic_device(repo);
593 if (result) {
594 pr_debug("%s:%d ps3_setup_gelic_device failed\n",
595 __func__, __LINE__);
596 }
597 break;
598 case PS3_DEV_TYPE_SB_USB:
599
600 /* Each USB device has both an EHCI and an OHCI HC */
601
602 result = ps3_setup_ehci_device(repo);
603
604 if (result) {
605 pr_debug("%s:%d ps3_setup_ehci_device failed\n",
606 __func__, __LINE__);
607 }
608
609 result = ps3_setup_ohci_device(repo);
610
611 if (result) {
612 pr_debug("%s:%d ps3_setup_ohci_device failed\n",
613 __func__, __LINE__);
614 }
615 break;
616 case PS3_DEV_TYPE_STOR_DISK:
617 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
618
619 /* Some devices are not accessable from the Other OS lpar. */
620 if (result == -ENODEV) {
621 result = 0;
622 pr_debug("%s:%u: not accessable\n", __func__,
623 __LINE__);
624 }
625
626 if (result)
627 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
628 __func__, __LINE__);
629 break;
630
631 case PS3_DEV_TYPE_STOR_ROM:
632 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
633 if (result)
634 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
635 __func__, __LINE__);
636 break;
637
638 case PS3_DEV_TYPE_STOR_FLASH:
639 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
640 if (result)
641 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
642 __func__, __LINE__);
643 break;
644
645 default:
646 result = 0;
647 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
648 repo->dev_type);
649 }
650
651 return result;
652}
653
654/**
655 * ps3_probe_thread - Background repository probing at system startup.
656 *
657 * This implementation only supports background probing on a single bus.
658 */
659
660static int ps3_probe_thread(void *data)
661{
662 struct ps3_repository_device *repo = data;
663 int result;
664 unsigned int ms = 250;
665
666 pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
667
668 do {
669 try_to_freeze();
670
671 pr_debug("%s:%u: probing...\n", __func__, __LINE__);
672
673 do {
674 result = ps3_repository_find_device(repo);
675
676 if (result == -ENODEV)
677 pr_debug("%s:%u: nothing new\n", __func__,
678 __LINE__);
679 else if (result)
680 pr_debug("%s:%u: find device error.\n",
681 __func__, __LINE__);
682 else {
683 pr_debug("%s:%u: found device\n", __func__,
684 __LINE__);
685 ps3_register_repository_device(repo);
686 ps3_repository_bump_device(repo);
687 ms = 250;
688 }
689 } while (!result);
690
691 pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
692
693 if ( ms > 60000)
694 break;
695
696 msleep_interruptible(ms);
697
698 /* An exponential backoff. */
699 ms <<= 1;
700
701 } while (!kthread_should_stop());
702
703 pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
704
705 return 0;
706}
707
708/**
709 * ps3_start_probe_thread - Starts the background probe thread.
710 *
711 */
712
713static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
714{
715 int result;
716 struct task_struct *task;
717 static struct ps3_repository_device repo; /* must be static */
718
719 pr_debug(" -> %s:%d\n", __func__, __LINE__);
720
721 memset(&repo, 0, sizeof(repo));
722
723 repo.bus_type = bus_type;
724
725 result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
726
727 if (result) {
728 printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
729 return -ENODEV;
730 }
731
732 result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
733
734 if (result) {
735 printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
736 result);
737 return -ENODEV;
738 }
739
740 task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
741
742 if (IS_ERR(task)) {
743 result = PTR_ERR(task);
744 printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
745 result);
746 return result;
747 }
748
749 pr_debug(" <- %s:%d\n", __func__, __LINE__);
750 return 0;
751}
752
753/**
754 * ps3_register_devices - Probe the system and register devices found.
755 *
756 * A device_initcall() routine.
757 */
758
759static int __init ps3_register_devices(void)
760{
761 int result;
762
763 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
764 return -ENODEV;
765
766 pr_debug(" -> %s:%d\n", __func__, __LINE__);
767
768 /* ps3_repository_dump_bus_info(); */
769
770 result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
771
772 ps3_register_vuart_devices();
773
774 ps3_register_graphics_devices();
775
776 ps3_repository_find_devices(PS3_BUS_TYPE_SB,
777 ps3_register_repository_device);
778
779 ps3_register_sound_devices();
780
781 pr_debug(" <- %s:%d\n", __func__, __LINE__);
782 return 0;
783}
784
785device_initcall(ps3_register_devices);
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index a1409e450c70..5d2e176a1b18 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -29,12 +29,12 @@
29#include "platform.h" 29#include "platform.h"
30 30
31#if defined(DEBUG) 31#if defined(DEBUG)
32#define DBG(fmt...) udbg_printf(fmt) 32#define DBG udbg_printf
33#else 33#else
34#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 34#define DBG pr_debug
35#endif 35#endif
36 36
37static hpte_t *htab; 37static struct hash_pte *htab;
38static unsigned long htab_addr; 38static unsigned long htab_addr;
39static unsigned char *bolttab; 39static unsigned char *bolttab;
40static unsigned char *inusetab; 40static unsigned char *inusetab;
@@ -44,8 +44,8 @@ static DEFINE_SPINLOCK(ps3_bolttab_lock);
44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \ 44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \
45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) 45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
46static void _debug_dump_hpte(unsigned long pa, unsigned long va, 46static void _debug_dump_hpte(unsigned long pa, unsigned long va,
47 unsigned long group, unsigned long bitmap, hpte_t lhpte, int psize, 47 unsigned long group, unsigned long bitmap, struct hash_pte lhpte,
48 unsigned long slot, const char* func, int line) 48 int psize, unsigned long slot, const char* func, int line)
49{ 49{
50 DBG("%s:%d: pa = %lxh\n", func, line, pa); 50 DBG("%s:%d: pa = %lxh\n", func, line, pa);
51 DBG("%s:%d: lpar = %lxh\n", func, line, 51 DBG("%s:%d: lpar = %lxh\n", func, line,
@@ -63,7 +63,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) 63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize)
64{ 64{
65 unsigned long slot; 65 unsigned long slot;
66 hpte_t lhpte; 66 struct hash_pte lhpte;
67 int secondary = 0; 67 int secondary = 0;
68 unsigned long result; 68 unsigned long result;
69 unsigned long bitmap; 69 unsigned long bitmap;
@@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
234 234
235static void ps3_hpte_clear(void) 235static void ps3_hpte_clear(void)
236{ 236{
237 /* Make sure to clean up the frame buffer device first */ 237 int result;
238 ps3fb_cleanup();
239 238
240 lv1_unmap_htab(htab_addr); 239 DBG(" -> %s:%d\n", __func__, __LINE__);
240
241 result = lv1_unmap_htab(htab_addr);
242 BUG_ON(result);
243
244 ps3_mm_shutdown();
245 ps3_mm_vas_destroy();
246
247 DBG(" <- %s:%d\n", __func__, __LINE__);
241} 248}
242 249
243void __init ps3_hpte_init(unsigned long htab_size) 250void __init ps3_hpte_init(unsigned long htab_size)
@@ -255,7 +262,7 @@ void __init ps3_hpte_init(unsigned long htab_size)
255 262
256 ppc64_pft_size = __ilog2(htab_size); 263 ppc64_pft_size = __ilog2(htab_size);
257 264
258 bitmap_size = htab_size / sizeof(hpte_t) / 8; 265 bitmap_size = htab_size / sizeof(struct hash_pte) / 8;
259 266
260 bolttab = __va(lmb_alloc(bitmap_size, 1)); 267 bolttab = __va(lmb_alloc(bitmap_size, 1));
261 inusetab = __va(lmb_alloc(bitmap_size, 1)); 268 inusetab = __va(lmb_alloc(bitmap_size, 1));
@@ -273,8 +280,8 @@ void __init ps3_map_htab(void)
273 280
274 result = lv1_map_htab(0, &htab_addr); 281 result = lv1_map_htab(0, &htab_addr);
275 282
276 htab = (hpte_t *)__ioremap(htab_addr, htab_size, 283 htab = (__force struct hash_pte *)ioremap_flags(htab_addr, htab_size,
277 pgprot_val(PAGE_READONLY_X)); 284 pgprot_val(PAGE_READONLY_X));
278 285
279 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, 286 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
280 htab_addr, (unsigned long)htab); 287 htab_addr, (unsigned long)htab);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index ec9030dbb5f1..67e32ec9b37e 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38/** 38/**
@@ -78,19 +78,85 @@ struct ps3_bmp {
78/** 78/**
79 * struct ps3_private - a per cpu data structure 79 * struct ps3_private - a per cpu data structure
80 * @bmp: ps3_bmp structure 80 * @bmp: ps3_bmp structure
81 * @node: HV logical_ppe_id 81 * @ppe_id: HV logical_ppe_id
82 * @cpu: HV thread_id 82 * @thread_id: HV thread_id
83 */ 83 */
84 84
85struct ps3_private { 85struct ps3_private {
86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
87 u64 node; 87 u64 ppe_id;
88 unsigned int cpu; 88 u64 thread_id;
89}; 89};
90 90
91static DEFINE_PER_CPU(struct ps3_private, ps3_private); 91static DEFINE_PER_CPU(struct ps3_private, ps3_private);
92 92
93/** 93/**
94 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
95 * @virq: The assigned Linux virq.
96 *
97 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
98 */
99
100static void ps3_chip_mask(unsigned int virq)
101{
102 struct ps3_private *pd = get_irq_chip_data(virq);
103 unsigned long flags;
104
105 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
106 pd->thread_id, virq);
107
108 local_irq_save(flags);
109 clear_bit(63 - virq, &pd->bmp.mask);
110 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
111 local_irq_restore(flags);
112}
113
114/**
115 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
116 * @virq: The assigned Linux virq.
117 *
118 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
119 */
120
121static void ps3_chip_unmask(unsigned int virq)
122{
123 struct ps3_private *pd = get_irq_chip_data(virq);
124 unsigned long flags;
125
126 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
127 pd->thread_id, virq);
128
129 local_irq_save(flags);
130 set_bit(63 - virq, &pd->bmp.mask);
131 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
132 local_irq_restore(flags);
133}
134
135/**
136 * ps3_chip_eoi - HV end-of-interrupt.
137 * @virq: The assigned Linux virq.
138 *
139 * Calls lv1_end_of_interrupt_ext().
140 */
141
142static void ps3_chip_eoi(unsigned int virq)
143{
144 const struct ps3_private *pd = get_irq_chip_data(virq);
145 lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
146}
147
148/**
149 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
150 */
151
152static struct irq_chip ps3_irq_chip = {
153 .typename = "ps3",
154 .mask = ps3_chip_mask,
155 .unmask = ps3_chip_unmask,
156 .eoi = ps3_chip_eoi,
157};
158
159/**
94 * ps3_virq_setup - virq related setup. 160 * ps3_virq_setup - virq related setup.
95 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 161 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
96 * serviced on. 162 * serviced on.
@@ -134,6 +200,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
134 goto fail_set; 200 goto fail_set;
135 } 201 }
136 202
203 ps3_chip_mask(*virq);
204
137 return result; 205 return result;
138 206
139fail_set: 207fail_set:
@@ -153,8 +221,8 @@ int ps3_virq_destroy(unsigned int virq)
153{ 221{
154 const struct ps3_private *pd = get_irq_chip_data(virq); 222 const struct ps3_private *pd = get_irq_chip_data(virq);
155 223
156 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 224 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
157 pd->node, pd->cpu, virq); 225 __LINE__, pd->ppe_id, pd->thread_id, virq);
158 226
159 set_irq_chip_data(virq, NULL); 227 set_irq_chip_data(virq, NULL);
160 irq_dispose_mapping(virq); 228 irq_dispose_mapping(virq);
@@ -190,7 +258,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
190 258
191 /* Binds outlet to cpu + virq. */ 259 /* Binds outlet to cpu + virq. */
192 260
193 result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); 261 result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
262 outlet, 0);
194 263
195 if (result) { 264 if (result) {
196 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 265 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
@@ -222,10 +291,12 @@ int ps3_irq_plug_destroy(unsigned int virq)
222 int result; 291 int result;
223 const struct ps3_private *pd = get_irq_chip_data(virq); 292 const struct ps3_private *pd = get_irq_chip_data(virq);
224 293
225 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 294 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
226 pd->node, pd->cpu, virq); 295 __LINE__, pd->ppe_id, pd->thread_id, virq);
296
297 ps3_chip_mask(virq);
227 298
228 result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); 299 result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
229 300
230 if (result) 301 if (result)
231 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 302 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
@@ -282,7 +353,9 @@ int ps3_event_receive_port_destroy(unsigned int virq)
282{ 353{
283 int result; 354 int result;
284 355
285 pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); 356 pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
357
358 ps3_chip_mask(virq);
286 359
287 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 360 result = lv1_destruct_event_receive_port(virq_to_hw(virq));
288 361
@@ -290,17 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq)
290 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 363 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
291 __func__, __LINE__, ps3_result(result)); 364 __func__, __LINE__, ps3_result(result));
292 365
293 /* lv1_destruct_event_receive_port() destroys the IRQ plug, 366 /*
294 * so don't call ps3_irq_plug_destroy() here. 367 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
368 * calls from interrupt context (smp_call_function) when kexecing.
295 */ 369 */
296 370
297 result = ps3_virq_destroy(virq);
298 BUG_ON(result);
299
300 pr_debug(" <- %s:%d\n", __func__, __LINE__); 371 pr_debug(" <- %s:%d\n", __func__, __LINE__);
301 return result; 372 return result;
302} 373}
303EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
304 374
305int ps3_send_event_locally(unsigned int virq) 375int ps3_send_event_locally(unsigned int virq)
306{ 376{
@@ -311,17 +381,15 @@ int ps3_send_event_locally(unsigned int virq)
311 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 381 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
312 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 382 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
313 * serviced on. 383 * serviced on.
314 * @did: The HV device identifier read from the system repository. 384 * @dev: The system bus device instance.
315 * @interrupt_id: The device interrupt id read from the system repository.
316 * @virq: The assigned Linux virq. 385 * @virq: The assigned Linux virq.
317 * 386 *
318 * An event irq represents a virtual device interrupt. The interrupt_id 387 * An event irq represents a virtual device interrupt. The interrupt_id
319 * coresponds to the software interrupt number. 388 * coresponds to the software interrupt number.
320 */ 389 */
321 390
322int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 391int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
323 const struct ps3_device_id *did, unsigned int interrupt_id, 392 enum ps3_cpu_binding cpu, unsigned int *virq)
324 unsigned int *virq)
325{ 393{
326 /* this should go in system-bus.c */ 394 /* this should go in system-bus.c */
327 395
@@ -332,8 +400,8 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
332 if (result) 400 if (result)
333 return result; 401 return result;
334 402
335 result = lv1_connect_interrupt_event_receive_port(did->bus_id, 403 result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
336 did->dev_id, virq_to_hw(*virq), interrupt_id); 404 dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);
337 405
338 if (result) { 406 if (result) {
339 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 407 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
@@ -345,24 +413,24 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
345 } 413 }
346 414
347 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 415 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
348 interrupt_id, *virq); 416 dev->interrupt_id, *virq);
349 417
350 return 0; 418 return 0;
351} 419}
352EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 420EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
353 421
354int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 422int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
355 unsigned int interrupt_id, unsigned int virq) 423 unsigned int virq)
356{ 424{
357 /* this should go in system-bus.c */ 425 /* this should go in system-bus.c */
358 426
359 int result; 427 int result;
360 428
361 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 429 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
362 interrupt_id, virq); 430 dev->interrupt_id, virq);
363 431
364 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, 432 result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
365 did->dev_id, virq_to_hw(virq), interrupt_id); 433 dev->dev_id, virq_to_hw(virq), dev->interrupt_id);
366 434
367 if (result) 435 if (result)
368 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 436 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
@@ -372,6 +440,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
372 result = ps3_event_receive_port_destroy(virq); 440 result = ps3_event_receive_port_destroy(virq);
373 BUG_ON(result); 441 BUG_ON(result);
374 442
443 /*
444 * ps3_event_receive_port_destroy() destroys the IRQ plug,
445 * so don't call ps3_irq_plug_destroy() here.
446 */
447
448 result = ps3_virq_destroy(virq);
449 BUG_ON(result);
450
375 pr_debug(" <- %s:%d\n", __func__, __LINE__); 451 pr_debug(" <- %s:%d\n", __func__, __LINE__);
376 return result; 452 return result;
377} 453}
@@ -412,16 +488,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
412int ps3_io_irq_destroy(unsigned int virq) 488int ps3_io_irq_destroy(unsigned int virq)
413{ 489{
414 int result; 490 int result;
491 unsigned long outlet = virq_to_hw(virq);
415 492
416 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); 493 ps3_chip_mask(virq);
417 494
418 if (result) 495 /*
419 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 496 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
420 __func__, __LINE__, ps3_result(result)); 497 * so call ps3_irq_plug_destroy() first.
498 */
421 499
422 result = ps3_irq_plug_destroy(virq); 500 result = ps3_irq_plug_destroy(virq);
423 BUG_ON(result); 501 BUG_ON(result);
424 502
503 result = lv1_destruct_io_irq_outlet(outlet);
504
505 if (result)
506 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
507 __func__, __LINE__, ps3_result(result));
508
425 return result; 509 return result;
426} 510}
427EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 511EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -461,11 +545,13 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
461 545
462 return result; 546 return result;
463} 547}
548EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
464 549
465int ps3_vuart_irq_destroy(unsigned int virq) 550int ps3_vuart_irq_destroy(unsigned int virq)
466{ 551{
467 int result; 552 int result;
468 553
554 ps3_chip_mask(virq);
469 result = lv1_deconfigure_virtual_uart_irq(); 555 result = lv1_deconfigure_virtual_uart_irq();
470 556
471 if (result) { 557 if (result) {
@@ -479,6 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
479 565
480 return result; 566 return result;
481} 567}
568EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
482 569
483/** 570/**
484 * ps3_spe_irq_setup - Setup an spe virq. 571 * ps3_spe_irq_setup - Setup an spe virq.
@@ -514,9 +601,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
514 601
515int ps3_spe_irq_destroy(unsigned int virq) 602int ps3_spe_irq_destroy(unsigned int virq)
516{ 603{
517 int result = ps3_irq_plug_destroy(virq); 604 int result;
605
606 ps3_chip_mask(virq);
607
608 result = ps3_irq_plug_destroy(virq);
518 BUG_ON(result); 609 BUG_ON(result);
519 return 0; 610
611 return result;
520} 612}
521 613
522 614
@@ -533,7 +625,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
533 *p & 0xffff); 625 *p & 0xffff);
534} 626}
535 627
536static void __attribute__ ((unused)) _dump_256_bmp(const char *header, 628static void __maybe_unused _dump_256_bmp(const char *header,
537 const u64 *p, unsigned cpu, const char* func, int line) 629 const u64 *p, unsigned cpu, const char* func, int line)
538{ 630{
539 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 631 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
@@ -546,86 +638,25 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
546 unsigned long flags; 638 unsigned long flags;
547 639
548 spin_lock_irqsave(&pd->bmp.lock, flags); 640 spin_lock_irqsave(&pd->bmp.lock, flags);
549 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); 641 _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
550 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 642 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
551 spin_unlock_irqrestore(&pd->bmp.lock, flags); 643 spin_unlock_irqrestore(&pd->bmp.lock, flags);
552} 644}
553 645
554#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 646#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
555static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, 647static void __maybe_unused _dump_mask(struct ps3_private *pd,
556 const char* func, int line) 648 const char* func, int line)
557{ 649{
558 unsigned long flags; 650 unsigned long flags;
559 651
560 spin_lock_irqsave(&pd->bmp.lock, flags); 652 spin_lock_irqsave(&pd->bmp.lock, flags);
561 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 653 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
562 spin_unlock_irqrestore(&pd->bmp.lock, flags); 654 spin_unlock_irqrestore(&pd->bmp.lock, flags);
563} 655}
564#else 656#else
565static void dump_bmp(struct ps3_private* pd) {}; 657static void dump_bmp(struct ps3_private* pd) {};
566#endif /* defined(DEBUG) */ 658#endif /* defined(DEBUG) */
567 659
568static void ps3_chip_mask(unsigned int virq)
569{
570 struct ps3_private *pd = get_irq_chip_data(virq);
571 u64 bit = 0x8000000000000000UL >> virq;
572 u64 *p = &pd->bmp.mask;
573 u64 old;
574 unsigned long flags;
575
576 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
577
578 local_irq_save(flags);
579 asm volatile(
580 "1: ldarx %0,0,%3\n"
581 "andc %0,%0,%2\n"
582 "stdcx. %0,0,%3\n"
583 "bne- 1b"
584 : "=&r" (old), "+m" (*p)
585 : "r" (bit), "r" (p)
586 : "cc" );
587
588 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
589 local_irq_restore(flags);
590}
591
592static void ps3_chip_unmask(unsigned int virq)
593{
594 struct ps3_private *pd = get_irq_chip_data(virq);
595 u64 bit = 0x8000000000000000UL >> virq;
596 u64 *p = &pd->bmp.mask;
597 u64 old;
598 unsigned long flags;
599
600 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
601
602 local_irq_save(flags);
603 asm volatile(
604 "1: ldarx %0,0,%3\n"
605 "or %0,%0,%2\n"
606 "stdcx. %0,0,%3\n"
607 "bne- 1b"
608 : "=&r" (old), "+m" (*p)
609 : "r" (bit), "r" (p)
610 : "cc" );
611
612 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
613 local_irq_restore(flags);
614}
615
616static void ps3_chip_eoi(unsigned int virq)
617{
618 const struct ps3_private *pd = get_irq_chip_data(virq);
619 lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
620}
621
622static struct irq_chip irq_chip = {
623 .typename = "ps3",
624 .mask = ps3_chip_mask,
625 .unmask = ps3_chip_unmask,
626 .eoi = ps3_chip_eoi,
627};
628
629static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 660static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
630{ 661{
631 set_irq_chip_data(virq, NULL); 662 set_irq_chip_data(virq, NULL);
@@ -637,7 +668,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
637 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 668 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
638 virq); 669 virq);
639 670
640 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); 671 set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
641 672
642 return 0; 673 return 0;
643} 674}
@@ -657,7 +688,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
657 cpu, virq, pd->bmp.ipi_debug_brk_mask); 688 cpu, virq, pd->bmp.ipi_debug_brk_mask);
658} 689}
659 690
660unsigned int ps3_get_irq(void) 691static unsigned int ps3_get_irq(void)
661{ 692{
662 struct ps3_private *pd = &__get_cpu_var(ps3_private); 693 struct ps3_private *pd = &__get_cpu_var(ps3_private);
663 u64 x = (pd->bmp.status & pd->bmp.mask); 694 u64 x = (pd->bmp.status & pd->bmp.mask);
@@ -672,8 +703,8 @@ unsigned int ps3_get_irq(void)
672 plug &= 0x3f; 703 plug &= 0x3f;
673 704
674 if (unlikely(plug) == NO_IRQ) { 705 if (unlikely(plug) == NO_IRQ) {
675 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, 706 pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__,
676 pd->cpu); 707 __LINE__, pd->thread_id);
677 dump_bmp(&per_cpu(ps3_private, 0)); 708 dump_bmp(&per_cpu(ps3_private, 0));
678 dump_bmp(&per_cpu(ps3_private, 1)); 709 dump_bmp(&per_cpu(ps3_private, 1));
679 return NO_IRQ; 710 return NO_IRQ;
@@ -703,16 +734,16 @@ void __init ps3_init_IRQ(void)
703 for_each_possible_cpu(cpu) { 734 for_each_possible_cpu(cpu) {
704 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 735 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
705 736
706 lv1_get_logical_ppe_id(&pd->node); 737 lv1_get_logical_ppe_id(&pd->ppe_id);
707 pd->cpu = get_hard_smp_processor_id(cpu); 738 pd->thread_id = get_hard_smp_processor_id(cpu);
708 spin_lock_init(&pd->bmp.lock); 739 spin_lock_init(&pd->bmp.lock);
709 740
710 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, 741 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n",
711 __LINE__, pd->node, pd->cpu, 742 __func__, __LINE__, pd->ppe_id, pd->thread_id,
712 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 743 ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
713 744
714 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, 745 result = lv1_configure_irq_state_bitmap(pd->ppe_id,
715 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 746 pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
716 747
717 if (result) 748 if (result)
718 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 749 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
@@ -722,3 +753,16 @@ void __init ps3_init_IRQ(void)
722 753
723 ppc_md.get_irq = ps3_get_irq; 754 ppc_md.get_irq = ps3_get_irq;
724} 755}
756
757void ps3_shutdown_IRQ(int cpu)
758{
759 int result;
760 u64 ppe_id;
761 u64 thread_id = get_hard_smp_processor_id(cpu);
762
763 lv1_get_logical_ppe_id(&ppe_id);
764 result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
765
766 DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__,
767 __LINE__, ppe_id, thread_id, cpu, ps3_result(result));
768}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index f8a3e206c584..7bb3e1620974 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38enum { 38enum {
@@ -115,7 +115,8 @@ struct map {
115}; 115};
116 116
117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__) 117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
118static void _debug_dump_map(const struct map* m, const char* func, int line) 118static void __maybe_unused _debug_dump_map(const struct map *m,
119 const char *func, int line)
119{ 120{
120 DBG("%s:%d: map.total = %lxh\n", func, line, m->total); 121 DBG("%s:%d: map.total = %lxh\n", func, line, m->total);
121 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); 122 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size);
@@ -212,9 +213,15 @@ fail:
212 213
213void ps3_mm_vas_destroy(void) 214void ps3_mm_vas_destroy(void)
214{ 215{
216 int result;
217
218 DBG("%s:%d: map.vas_id = %lu\n", __func__, __LINE__, map.vas_id);
219
215 if (map.vas_id) { 220 if (map.vas_id) {
216 lv1_select_virtual_address_space(0); 221 result = lv1_select_virtual_address_space(0);
217 lv1_destruct_virtual_address_space(map.vas_id); 222 BUG_ON(result);
223 result = lv1_destruct_virtual_address_space(map.vas_id);
224 BUG_ON(result);
218 map.vas_id = 0; 225 map.vas_id = 0;
219 } 226 }
220} 227}
@@ -232,7 +239,7 @@ void ps3_mm_vas_destroy(void)
232 * @size is rounded down to a multiple of the vas large page size. 239 * @size is rounded down to a multiple of the vas large page size.
233 */ 240 */
234 241
235int ps3_mm_region_create(struct mem_region *r, unsigned long size) 242static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
236{ 243{
237 int result; 244 int result;
238 unsigned long muid; 245 unsigned long muid;
@@ -273,10 +280,14 @@ zero_region:
273 * @r: pointer to struct mem_region 280 * @r: pointer to struct mem_region
274 */ 281 */
275 282
276void ps3_mm_region_destroy(struct mem_region *r) 283static void ps3_mm_region_destroy(struct mem_region *r)
277{ 284{
285 int result;
286
287 DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base);
278 if (r->base) { 288 if (r->base) {
279 lv1_release_memory(r->base); 289 result = lv1_release_memory(r->base);
290 BUG_ON(result);
280 r->size = r->base = r->offset = 0; 291 r->size = r->base = r->offset = 0;
281 map.total = map.rm.size; 292 map.total = map.rm.size;
282 } 293 }
@@ -329,31 +340,34 @@ core_initcall(ps3_mm_add_memory);
329/*============================================================================*/ 340/*============================================================================*/
330 341
331/** 342/**
332 * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address. 343 * dma_sb_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
333 * @r: pointer to dma region structure 344 * @r: pointer to dma region structure
334 * @lpar_addr: HV lpar address 345 * @lpar_addr: HV lpar address
335 */ 346 */
336 347
337static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r, 348static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r,
338 unsigned long lpar_addr) 349 unsigned long lpar_addr)
339{ 350{
340 BUG_ON(lpar_addr >= map.r1.base + map.r1.size); 351 if (lpar_addr >= map.rm.size)
341 return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr 352 lpar_addr -= map.r1.offset;
342 : lpar_addr - map.r1.offset); 353 BUG_ON(lpar_addr < r->offset);
354 BUG_ON(lpar_addr >= r->offset + r->len);
355 return r->bus_addr + lpar_addr - r->offset;
343} 356}
344 357
345#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__) 358#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__)
346static void _dma_dump_region(const struct ps3_dma_region *r, const char* func, 359static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
347 int line) 360 const char *func, int line)
348{ 361{
349 DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 362 DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
350 r->did.dev_id); 363 r->dev->dev_id);
351 DBG("%s:%d: page_size %u\n", func, line, r->page_size); 364 DBG("%s:%d: page_size %u\n", func, line, r->page_size);
352 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 365 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
353 DBG("%s:%d: len %lxh\n", func, line, r->len); 366 DBG("%s:%d: len %lxh\n", func, line, r->len);
367 DBG("%s:%d: offset %lxh\n", func, line, r->offset);
354} 368}
355 369
356/** 370 /**
357 * dma_chunk - A chunk of dma pages mapped by the io controller. 371 * dma_chunk - A chunk of dma pages mapped by the io controller.
358 * @region - The dma region that owns this chunk. 372 * @region - The dma region that owns this chunk.
359 * @lpar_addr: Starting lpar address of the area to map. 373 * @lpar_addr: Starting lpar address of the area to map.
@@ -381,10 +395,11 @@ static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
381 int line) 395 int line)
382{ 396{
383 DBG("%s:%d: r.dev %u:%u\n", func, line, 397 DBG("%s:%d: r.dev %u:%u\n", func, line,
384 c->region->did.bus_id, c->region->did.dev_id); 398 c->region->dev->bus_id, c->region->dev->dev_id);
385 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); 399 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
386 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); 400 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
387 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len); 401 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len);
402 DBG("%s:%d: r.offset %lxh\n", func, line, c->region->offset);
388 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr); 403 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr);
389 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr); 404 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr);
390 DBG("%s:%d: c.len %lxh\n", func, line, c->len); 405 DBG("%s:%d: c.len %lxh\n", func, line, c->len);
@@ -395,39 +410,68 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
395{ 410{
396 struct dma_chunk *c; 411 struct dma_chunk *c;
397 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size); 412 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
398 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 413 unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
414 1 << r->page_size);
399 415
400 list_for_each_entry(c, &r->chunk_list.head, link) { 416 list_for_each_entry(c, &r->chunk_list.head, link) {
401 /* intersection */ 417 /* intersection */
402 if (aligned_bus >= c->bus_addr 418 if (aligned_bus >= c->bus_addr &&
403 && aligned_bus < c->bus_addr + c->len 419 aligned_bus + aligned_len <= c->bus_addr + c->len)
404 && aligned_bus + aligned_len <= c->bus_addr + c->len) {
405 return c; 420 return c;
406 } 421
407 /* below */ 422 /* below */
408 if (aligned_bus + aligned_len <= c->bus_addr) { 423 if (aligned_bus + aligned_len <= c->bus_addr)
409 continue; 424 continue;
410 } 425
411 /* above */ 426 /* above */
412 if (aligned_bus >= c->bus_addr + c->len) { 427 if (aligned_bus >= c->bus_addr + c->len)
413 continue; 428 continue;
414 }
415 429
416 /* we don't handle the multi-chunk case for now */ 430 /* we don't handle the multi-chunk case for now */
417
418 dma_dump_chunk(c); 431 dma_dump_chunk(c);
419 BUG(); 432 BUG();
420 } 433 }
421 return NULL; 434 return NULL;
422} 435}
423 436
424static int dma_free_chunk(struct dma_chunk *c) 437static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
438 unsigned long lpar_addr, unsigned long len)
439{
440 struct dma_chunk *c;
441 unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
442 unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
443 1 << r->page_size);
444
445 list_for_each_entry(c, &r->chunk_list.head, link) {
446 /* intersection */
447 if (c->lpar_addr <= aligned_lpar &&
448 aligned_lpar < c->lpar_addr + c->len) {
449 if (aligned_lpar + aligned_len <= c->lpar_addr + c->len)
450 return c;
451 else {
452 dma_dump_chunk(c);
453 BUG();
454 }
455 }
456 /* below */
457 if (aligned_lpar + aligned_len <= c->lpar_addr) {
458 continue;
459 }
460 /* above */
461 if (c->lpar_addr + c->len <= aligned_lpar) {
462 continue;
463 }
464 }
465 return NULL;
466}
467
468static int dma_sb_free_chunk(struct dma_chunk *c)
425{ 469{
426 int result = 0; 470 int result = 0;
427 471
428 if (c->bus_addr) { 472 if (c->bus_addr) {
429 result = lv1_unmap_device_dma_region(c->region->did.bus_id, 473 result = lv1_unmap_device_dma_region(c->region->dev->bus_id,
430 c->region->did.dev_id, c->bus_addr, c->len); 474 c->region->dev->dev_id, c->bus_addr, c->len);
431 BUG_ON(result); 475 BUG_ON(result);
432 } 476 }
433 477
@@ -435,8 +479,39 @@ static int dma_free_chunk(struct dma_chunk *c)
435 return result; 479 return result;
436} 480}
437 481
482static int dma_ioc0_free_chunk(struct dma_chunk *c)
483{
484 int result = 0;
485 int iopage;
486 unsigned long offset;
487 struct ps3_dma_region *r = c->region;
488
489 DBG("%s:start\n", __func__);
490 for (iopage = 0; iopage < (c->len >> r->page_size); iopage++) {
491 offset = (1 << r->page_size) * iopage;
492 /* put INVALID entry */
493 result = lv1_put_iopte(0,
494 c->bus_addr + offset,
495 c->lpar_addr + offset,
496 r->ioid,
497 0);
498 DBG("%s: bus=%#lx, lpar=%#lx, ioid=%d\n", __func__,
499 c->bus_addr + offset,
500 c->lpar_addr + offset,
501 r->ioid);
502
503 if (result) {
504 DBG("%s:%d: lv1_put_iopte failed: %s\n", __func__,
505 __LINE__, ps3_result(result));
506 }
507 }
508 kfree(c);
509 DBG("%s:end\n", __func__);
510 return result;
511}
512
438/** 513/**
439 * dma_map_pages - Maps dma pages into the io controller bus address space. 514 * dma_sb_map_pages - Maps dma pages into the io controller bus address space.
440 * @r: Pointer to a struct ps3_dma_region. 515 * @r: Pointer to a struct ps3_dma_region.
441 * @phys_addr: Starting physical address of the area to map. 516 * @phys_addr: Starting physical address of the area to map.
442 * @len: Length in bytes of the area to map. 517 * @len: Length in bytes of the area to map.
@@ -446,8 +521,8 @@ static int dma_free_chunk(struct dma_chunk *c)
446 * make the HV call to add the pages into the io controller address space. 521 * make the HV call to add the pages into the io controller address space.
447 */ 522 */
448 523
449static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, 524static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
450 unsigned long len, struct dma_chunk **c_out) 525 unsigned long len, struct dma_chunk **c_out, u64 iopte_flag)
451{ 526{
452 int result; 527 int result;
453 struct dma_chunk *c; 528 struct dma_chunk *c;
@@ -461,13 +536,13 @@ static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
461 536
462 c->region = r; 537 c->region = r;
463 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 538 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
464 c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr); 539 c->bus_addr = dma_sb_lpar_to_bus(r, c->lpar_addr);
465 c->len = len; 540 c->len = len;
466 541
467 result = lv1_map_device_dma_region(c->region->did.bus_id, 542 BUG_ON(iopte_flag != 0xf800000000000000UL);
468 c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len, 543 result = lv1_map_device_dma_region(c->region->dev->bus_id,
469 0xf800000000000000UL); 544 c->region->dev->dev_id, c->lpar_addr,
470 545 c->bus_addr, c->len, iopte_flag);
471 if (result) { 546 if (result) {
472 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n", 547 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
473 __func__, __LINE__, ps3_result(result)); 548 __func__, __LINE__, ps3_result(result));
@@ -487,26 +562,120 @@ fail_alloc:
487 return result; 562 return result;
488} 563}
489 564
565static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
566 unsigned long len, struct dma_chunk **c_out,
567 u64 iopte_flag)
568{
569 int result;
570 struct dma_chunk *c, *last;
571 int iopage, pages;
572 unsigned long offset;
573
574 DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__,
575 phys_addr, ps3_mm_phys_to_lpar(phys_addr), len);
576 c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC);
577
578 if (!c) {
579 result = -ENOMEM;
580 goto fail_alloc;
581 }
582
583 c->region = r;
584 c->len = len;
585 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
586 /* allocate IO address */
587 if (list_empty(&r->chunk_list.head)) {
588 /* first one */
589 c->bus_addr = r->bus_addr;
590 } else {
591 /* derive from last bus addr*/
592 last = list_entry(r->chunk_list.head.next,
593 struct dma_chunk, link);
594 c->bus_addr = last->bus_addr + last->len;
595 DBG("%s: last bus=%#lx, len=%#lx\n", __func__,
596 last->bus_addr, last->len);
597 }
598
599 /* FIXME: check whether length exceeds region size */
600
601 /* build ioptes for the area */
602 pages = len >> r->page_size;
603 DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__,
604 r->page_size, r->len, pages, iopte_flag);
605 for (iopage = 0; iopage < pages; iopage++) {
606 offset = (1 << r->page_size) * iopage;
607 result = lv1_put_iopte(0,
608 c->bus_addr + offset,
609 c->lpar_addr + offset,
610 r->ioid,
611 iopte_flag);
612 if (result) {
613 printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region "
614 "failed: %s\n", __func__, __LINE__,
615 ps3_result(result));
616 goto fail_map;
617 }
618 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
619 iopage, c->bus_addr + offset, c->lpar_addr + offset,
620 r->ioid);
621 }
622
623 /* be sure that last allocated one is inserted at head */
624 list_add(&c->link, &r->chunk_list.head);
625
626 *c_out = c;
627 DBG("%s: end\n", __func__);
628 return 0;
629
630fail_map:
631 for (iopage--; 0 <= iopage; iopage--) {
632 lv1_put_iopte(0,
633 c->bus_addr + offset,
634 c->lpar_addr + offset,
635 r->ioid,
636 0);
637 }
638 kfree(c);
639fail_alloc:
640 *c_out = NULL;
641 return result;
642}
643
490/** 644/**
491 * dma_region_create - Create a device dma region. 645 * dma_sb_region_create - Create a device dma region.
492 * @r: Pointer to a struct ps3_dma_region. 646 * @r: Pointer to a struct ps3_dma_region.
493 * 647 *
494 * This is the lowest level dma region create routine, and is the one that 648 * This is the lowest level dma region create routine, and is the one that
495 * will make the HV call to create the region. 649 * will make the HV call to create the region.
496 */ 650 */
497 651
498static int dma_region_create(struct ps3_dma_region* r) 652static int dma_sb_region_create(struct ps3_dma_region *r)
499{ 653{
500 int result; 654 int result;
501 655
502 r->len = _ALIGN_UP(map.total, 1 << r->page_size); 656 pr_info(" -> %s:%d:\n", __func__, __LINE__);
657
658 BUG_ON(!r);
659
660 if (!r->dev->bus_id) {
661 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
662 r->dev->bus_id, r->dev->dev_id);
663 return 0;
664 }
665
666 DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
667 __LINE__, r->len, r->page_size, r->offset);
668
669 BUG_ON(!r->len);
670 BUG_ON(!r->page_size);
671 BUG_ON(!r->region_ops);
672
503 INIT_LIST_HEAD(&r->chunk_list.head); 673 INIT_LIST_HEAD(&r->chunk_list.head);
504 spin_lock_init(&r->chunk_list.lock); 674 spin_lock_init(&r->chunk_list.lock);
505 675
506 result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id, 676 result = lv1_allocate_device_dma_region(r->dev->bus_id, r->dev->dev_id,
507 r->len, r->page_size, r->region_type, &r->bus_addr); 677 roundup_pow_of_two(r->len), r->page_size, r->region_type,
508 678 &r->bus_addr);
509 dma_dump_region(r);
510 679
511 if (result) { 680 if (result) {
512 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", 681 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n",
@@ -517,6 +686,27 @@ static int dma_region_create(struct ps3_dma_region* r)
517 return result; 686 return result;
518} 687}
519 688
689static int dma_ioc0_region_create(struct ps3_dma_region *r)
690{
691 int result;
692
693 INIT_LIST_HEAD(&r->chunk_list.head);
694 spin_lock_init(&r->chunk_list.lock);
695
696 result = lv1_allocate_io_segment(0,
697 r->len,
698 r->page_size,
699 &r->bus_addr);
700 if (result) {
701 DBG("%s:%d: lv1_allocate_io_segment failed: %s\n",
702 __func__, __LINE__, ps3_result(result));
703 r->len = r->bus_addr = 0;
704 }
705 DBG("%s: len=%#lx, pg=%d, bus=%#lx\n", __func__,
706 r->len, r->page_size, r->bus_addr);
707 return result;
708}
709
520/** 710/**
521 * dma_region_free - Free a device dma region. 711 * dma_region_free - Free a device dma region.
522 * @r: Pointer to a struct ps3_dma_region. 712 * @r: Pointer to a struct ps3_dma_region.
@@ -525,31 +715,62 @@ static int dma_region_create(struct ps3_dma_region* r)
525 * will make the HV call to free the region. 715 * will make the HV call to free the region.
526 */ 716 */
527 717
528static int dma_region_free(struct ps3_dma_region* r) 718static int dma_sb_region_free(struct ps3_dma_region *r)
529{ 719{
530 int result; 720 int result;
531 struct dma_chunk *c; 721 struct dma_chunk *c;
532 struct dma_chunk *tmp; 722 struct dma_chunk *tmp;
533 723
724 BUG_ON(!r);
725
726 if (!r->dev->bus_id) {
727 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
728 r->dev->bus_id, r->dev->dev_id);
729 return 0;
730 }
731
534 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) { 732 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
535 list_del(&c->link); 733 list_del(&c->link);
536 dma_free_chunk(c); 734 dma_sb_free_chunk(c);
537 } 735 }
538 736
539 result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id, 737 result = lv1_free_device_dma_region(r->dev->bus_id, r->dev->dev_id,
540 r->bus_addr); 738 r->bus_addr);
541 739
542 if (result) 740 if (result)
543 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", 741 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
544 __func__, __LINE__, ps3_result(result)); 742 __func__, __LINE__, ps3_result(result));
545 743
546 r->len = r->bus_addr = 0; 744 r->bus_addr = 0;
745
746 return result;
747}
748
749static int dma_ioc0_region_free(struct ps3_dma_region *r)
750{
751 int result;
752 struct dma_chunk *c, *n;
753
754 DBG("%s: start\n", __func__);
755 list_for_each_entry_safe(c, n, &r->chunk_list.head, link) {
756 list_del(&c->link);
757 dma_ioc0_free_chunk(c);
758 }
759
760 result = lv1_release_io_segment(0, r->bus_addr);
761
762 if (result)
763 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
764 __func__, __LINE__, ps3_result(result));
765
766 r->bus_addr = 0;
767 DBG("%s: end\n", __func__);
547 768
548 return result; 769 return result;
549} 770}
550 771
551/** 772/**
552 * dma_map_area - Map an area of memory into a device dma region. 773 * dma_sb_map_area - Map an area of memory into a device dma region.
553 * @r: Pointer to a struct ps3_dma_region. 774 * @r: Pointer to a struct ps3_dma_region.
554 * @virt_addr: Starting virtual address of the area to map. 775 * @virt_addr: Starting virtual address of the area to map.
555 * @len: Length in bytes of the area to map. 776 * @len: Length in bytes of the area to map.
@@ -559,16 +780,19 @@ static int dma_region_free(struct ps3_dma_region* r)
559 * This is the common dma mapping routine. 780 * This is the common dma mapping routine.
560 */ 781 */
561 782
562static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr, 783static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
563 unsigned long len, unsigned long *bus_addr) 784 unsigned long len, unsigned long *bus_addr,
785 u64 iopte_flag)
564{ 786{
565 int result; 787 int result;
566 unsigned long flags; 788 unsigned long flags;
567 struct dma_chunk *c; 789 struct dma_chunk *c;
568 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 790 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
569 : virt_addr; 791 : virt_addr;
570 792 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
571 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 793 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
794 1 << r->page_size);
795 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
572 796
573 if (!USE_DYNAMIC_DMA) { 797 if (!USE_DYNAMIC_DMA) {
574 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 798 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
@@ -588,17 +812,18 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
588 c = dma_find_chunk(r, *bus_addr, len); 812 c = dma_find_chunk(r, *bus_addr, len);
589 813
590 if (c) { 814 if (c) {
815 DBG("%s:%d: reusing mapped chunk", __func__, __LINE__);
816 dma_dump_chunk(c);
591 c->usage_count++; 817 c->usage_count++;
592 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 818 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
593 return 0; 819 return 0;
594 } 820 }
595 821
596 result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size), 822 result = dma_sb_map_pages(r, aligned_phys, aligned_len, &c, iopte_flag);
597 _ALIGN_UP(len, 1 << r->page_size), &c);
598 823
599 if (result) { 824 if (result) {
600 *bus_addr = 0; 825 *bus_addr = 0;
601 DBG("%s:%d: dma_map_pages failed (%d)\n", 826 DBG("%s:%d: dma_sb_map_pages failed (%d)\n",
602 __func__, __LINE__, result); 827 __func__, __LINE__, result);
603 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 828 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
604 return result; 829 return result;
@@ -610,8 +835,57 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
610 return result; 835 return result;
611} 836}
612 837
838static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
839 unsigned long len, unsigned long *bus_addr,
840 u64 iopte_flag)
841{
842 int result;
843 unsigned long flags;
844 struct dma_chunk *c;
845 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
846 : virt_addr;
847 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
848 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
849 1 << r->page_size);
850
851 DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
852 virt_addr, len);
853 DBG(KERN_ERR "%s: ph=%#lx a_ph=%#lx a_l=%#lx\n", __func__,
854 phys_addr, aligned_phys, aligned_len);
855
856 spin_lock_irqsave(&r->chunk_list.lock, flags);
857 c = dma_find_chunk_lpar(r, ps3_mm_phys_to_lpar(phys_addr), len);
858
859 if (c) {
860 /* FIXME */
861 BUG();
862 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
863 c->usage_count++;
864 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
865 return 0;
866 }
867
868 result = dma_ioc0_map_pages(r, aligned_phys, aligned_len, &c,
869 iopte_flag);
870
871 if (result) {
872 *bus_addr = 0;
873 DBG("%s:%d: dma_ioc0_map_pages failed (%d)\n",
874 __func__, __LINE__, result);
875 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
876 return result;
877 }
878 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
879 DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__,
880 virt_addr, phys_addr, aligned_phys, *bus_addr);
881 c->usage_count = 1;
882
883 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
884 return result;
885}
886
613/** 887/**
614 * dma_unmap_area - Unmap an area of memory from a device dma region. 888 * dma_sb_unmap_area - Unmap an area of memory from a device dma region.
615 * @r: Pointer to a struct ps3_dma_region. 889 * @r: Pointer to a struct ps3_dma_region.
616 * @bus_addr: The starting ioc bus address of the area to unmap. 890 * @bus_addr: The starting ioc bus address of the area to unmap.
617 * @len: Length in bytes of the area to unmap. 891 * @len: Length in bytes of the area to unmap.
@@ -619,7 +893,7 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
619 * This is the common dma unmap routine. 893 * This is the common dma unmap routine.
620 */ 894 */
621 895
622int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, 896static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
623 unsigned long len) 897 unsigned long len)
624{ 898{
625 unsigned long flags; 899 unsigned long flags;
@@ -631,7 +905,8 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
631 if (!c) { 905 if (!c) {
632 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 906 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
633 1 << r->page_size); 907 1 << r->page_size);
634 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 908 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
909 - aligned_bus, 1 << r->page_size);
635 DBG("%s:%d: not found: bus_addr %lxh\n", 910 DBG("%s:%d: not found: bus_addr %lxh\n",
636 __func__, __LINE__, bus_addr); 911 __func__, __LINE__, bus_addr);
637 DBG("%s:%d: not found: len %lxh\n", 912 DBG("%s:%d: not found: len %lxh\n",
@@ -647,94 +922,166 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
647 922
648 if (!c->usage_count) { 923 if (!c->usage_count) {
649 list_del(&c->link); 924 list_del(&c->link);
650 dma_free_chunk(c); 925 dma_sb_free_chunk(c);
651 } 926 }
652 927
653 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 928 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
654 return 0; 929 return 0;
655} 930}
656 931
932static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
933 unsigned long bus_addr, unsigned long len)
934{
935 unsigned long flags;
936 struct dma_chunk *c;
937
938 DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len);
939 spin_lock_irqsave(&r->chunk_list.lock, flags);
940 c = dma_find_chunk(r, bus_addr, len);
941
942 if (!c) {
943 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
944 1 << r->page_size);
945 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
946 - aligned_bus,
947 1 << r->page_size);
948 DBG("%s:%d: not found: bus_addr %lxh\n",
949 __func__, __LINE__, bus_addr);
950 DBG("%s:%d: not found: len %lxh\n",
951 __func__, __LINE__, len);
952 DBG("%s:%d: not found: aligned_bus %lxh\n",
953 __func__, __LINE__, aligned_bus);
954 DBG("%s:%d: not found: aligned_len %lxh\n",
955 __func__, __LINE__, aligned_len);
956 BUG();
957 }
958
959 c->usage_count--;
960
961 if (!c->usage_count) {
962 list_del(&c->link);
963 dma_ioc0_free_chunk(c);
964 }
965
966 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
967 DBG("%s: end\n", __func__);
968 return 0;
969}
970
657/** 971/**
658 * dma_region_create_linear - Setup a linear dma maping for a device. 972 * dma_sb_region_create_linear - Setup a linear dma mapping for a device.
659 * @r: Pointer to a struct ps3_dma_region. 973 * @r: Pointer to a struct ps3_dma_region.
660 * 974 *
661 * This routine creates an HV dma region for the device and maps all available 975 * This routine creates an HV dma region for the device and maps all available
662 * ram into the io controller bus address space. 976 * ram into the io controller bus address space.
663 */ 977 */
664 978
665static int dma_region_create_linear(struct ps3_dma_region *r) 979static int dma_sb_region_create_linear(struct ps3_dma_region *r)
666{ 980{
667 int result; 981 int result;
668 unsigned long tmp; 982 unsigned long virt_addr, len, tmp;
669 983
670 /* force 16M dma pages for linear mapping */ 984 if (r->len > 16*1024*1024) { /* FIXME: need proper fix */
671 985 /* force 16M dma pages for linear mapping */
672 if (r->page_size != PS3_DMA_16M) { 986 if (r->page_size != PS3_DMA_16M) {
673 pr_info("%s:%d: forcing 16M pages for linear map\n", 987 pr_info("%s:%d: forcing 16M pages for linear map\n",
674 __func__, __LINE__); 988 __func__, __LINE__);
675 r->page_size = PS3_DMA_16M; 989 r->page_size = PS3_DMA_16M;
990 r->len = _ALIGN_UP(r->len, 1 << r->page_size);
991 }
676 } 992 }
677 993
678 result = dma_region_create(r); 994 result = dma_sb_region_create(r);
679 BUG_ON(result); 995 BUG_ON(result);
680 996
681 result = dma_map_area(r, map.rm.base, map.rm.size, &tmp); 997 if (r->offset < map.rm.size) {
682 BUG_ON(result); 998 /* Map (part of) 1st RAM chunk */
683 999 virt_addr = map.rm.base + r->offset;
684 if (USE_LPAR_ADDR) 1000 len = map.rm.size - r->offset;
685 result = dma_map_area(r, map.r1.base, map.r1.size, 1001 if (len > r->len)
686 &tmp); 1002 len = r->len;
687 else 1003 result = dma_sb_map_area(r, virt_addr, len, &tmp,
688 result = dma_map_area(r, map.rm.size, map.r1.size, 1004 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
689 &tmp); 1005 BUG_ON(result);
1006 }
690 1007
691 BUG_ON(result); 1008 if (r->offset + r->len > map.rm.size) {
1009 /* Map (part of) 2nd RAM chunk */
1010 virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
1011 len = r->len;
1012 if (r->offset >= map.rm.size)
1013 virt_addr += r->offset - map.rm.size;
1014 else
1015 len -= map.rm.size - r->offset;
1016 result = dma_sb_map_area(r, virt_addr, len, &tmp,
1017 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
1018 BUG_ON(result);
1019 }
692 1020
693 return result; 1021 return result;
694} 1022}
695 1023
696/** 1024/**
697 * dma_region_free_linear - Free a linear dma mapping for a device. 1025 * dma_sb_region_free_linear - Free a linear dma mapping for a device.
698 * @r: Pointer to a struct ps3_dma_region. 1026 * @r: Pointer to a struct ps3_dma_region.
699 * 1027 *
700 * This routine will unmap all mapped areas and free the HV dma region. 1028 * This routine will unmap all mapped areas and free the HV dma region.
701 */ 1029 */
702 1030
703static int dma_region_free_linear(struct ps3_dma_region *r) 1031static int dma_sb_region_free_linear(struct ps3_dma_region *r)
704{ 1032{
705 int result; 1033 int result;
1034 unsigned long bus_addr, len, lpar_addr;
1035
1036 if (r->offset < map.rm.size) {
1037 /* Unmap (part of) 1st RAM chunk */
1038 lpar_addr = map.rm.base + r->offset;
1039 len = map.rm.size - r->offset;
1040 if (len > r->len)
1041 len = r->len;
1042 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1043 result = dma_sb_unmap_area(r, bus_addr, len);
1044 BUG_ON(result);
1045 }
706 1046
707 result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size); 1047 if (r->offset + r->len > map.rm.size) {
708 BUG_ON(result); 1048 /* Unmap (part of) 2nd RAM chunk */
709 1049 lpar_addr = map.r1.base;
710 result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base), 1050 len = r->len;
711 map.r1.size); 1051 if (r->offset >= map.rm.size)
712 BUG_ON(result); 1052 lpar_addr += r->offset - map.rm.size;
1053 else
1054 len -= map.rm.size - r->offset;
1055 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1056 result = dma_sb_unmap_area(r, bus_addr, len);
1057 BUG_ON(result);
1058 }
713 1059
714 result = dma_region_free(r); 1060 result = dma_sb_region_free(r);
715 BUG_ON(result); 1061 BUG_ON(result);
716 1062
717 return result; 1063 return result;
718} 1064}
719 1065
720/** 1066/**
721 * dma_map_area_linear - Map an area of memory into a device dma region. 1067 * dma_sb_map_area_linear - Map an area of memory into a device dma region.
722 * @r: Pointer to a struct ps3_dma_region. 1068 * @r: Pointer to a struct ps3_dma_region.
723 * @virt_addr: Starting virtual address of the area to map. 1069 * @virt_addr: Starting virtual address of the area to map.
724 * @len: Length in bytes of the area to map. 1070 * @len: Length in bytes of the area to map.
725 * @bus_addr: A pointer to return the starting ioc bus address of the area to 1071 * @bus_addr: A pointer to return the starting ioc bus address of the area to
726 * map. 1072 * map.
727 * 1073 *
728 * This routine just returns the coresponding bus address. Actual mapping 1074 * This routine just returns the corresponding bus address. Actual mapping
729 * occurs in dma_region_create_linear(). 1075 * occurs in dma_region_create_linear().
730 */ 1076 */
731 1077
732static int dma_map_area_linear(struct ps3_dma_region *r, 1078static int dma_sb_map_area_linear(struct ps3_dma_region *r,
733 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr) 1079 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr,
1080 u64 iopte_flag)
734{ 1081{
735 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 1082 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
736 : virt_addr; 1083 : virt_addr;
737 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 1084 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
738 return 0; 1085 return 0;
739} 1086}
740 1087
@@ -744,42 +1091,98 @@ static int dma_map_area_linear(struct ps3_dma_region *r,
744 * @bus_addr: The starting ioc bus address of the area to unmap. 1091 * @bus_addr: The starting ioc bus address of the area to unmap.
745 * @len: Length in bytes of the area to unmap. 1092 * @len: Length in bytes of the area to unmap.
746 * 1093 *
747 * This routine does nothing. Unmapping occurs in dma_region_free_linear(). 1094 * This routine does nothing. Unmapping occurs in dma_sb_region_free_linear().
748 */ 1095 */
749 1096
750static int dma_unmap_area_linear(struct ps3_dma_region *r, 1097static int dma_sb_unmap_area_linear(struct ps3_dma_region *r,
751 unsigned long bus_addr, unsigned long len) 1098 unsigned long bus_addr, unsigned long len)
752{ 1099{
753 return 0; 1100 return 0;
1101};
1102
1103static const struct ps3_dma_region_ops ps3_dma_sb_region_ops = {
1104 .create = dma_sb_region_create,
1105 .free = dma_sb_region_free,
1106 .map = dma_sb_map_area,
1107 .unmap = dma_sb_unmap_area
1108};
1109
1110static const struct ps3_dma_region_ops ps3_dma_sb_region_linear_ops = {
1111 .create = dma_sb_region_create_linear,
1112 .free = dma_sb_region_free_linear,
1113 .map = dma_sb_map_area_linear,
1114 .unmap = dma_sb_unmap_area_linear
1115};
1116
1117static const struct ps3_dma_region_ops ps3_dma_ioc0_region_ops = {
1118 .create = dma_ioc0_region_create,
1119 .free = dma_ioc0_region_free,
1120 .map = dma_ioc0_map_area,
1121 .unmap = dma_ioc0_unmap_area
1122};
1123
1124int ps3_dma_region_init(struct ps3_system_bus_device *dev,
1125 struct ps3_dma_region *r, enum ps3_dma_page_size page_size,
1126 enum ps3_dma_region_type region_type, void *addr, unsigned long len)
1127{
1128 unsigned long lpar_addr;
1129
1130 lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0;
1131
1132 r->dev = dev;
1133 r->page_size = page_size;
1134 r->region_type = region_type;
1135 r->offset = lpar_addr;
1136 if (r->offset >= map.rm.size)
1137 r->offset -= map.r1.offset;
1138 r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
1139
1140 switch (dev->dev_type) {
1141 case PS3_DEVICE_TYPE_SB:
1142 r->region_ops = (USE_DYNAMIC_DMA)
1143 ? &ps3_dma_sb_region_ops
1144 : &ps3_dma_sb_region_linear_ops;
1145 break;
1146 case PS3_DEVICE_TYPE_IOC0:
1147 r->region_ops = &ps3_dma_ioc0_region_ops;
1148 break;
1149 default:
1150 BUG();
1151 return -EINVAL;
1152 }
1153 return 0;
754} 1154}
1155EXPORT_SYMBOL(ps3_dma_region_init);
755 1156
756int ps3_dma_region_create(struct ps3_dma_region *r) 1157int ps3_dma_region_create(struct ps3_dma_region *r)
757{ 1158{
758 return (USE_DYNAMIC_DMA) 1159 BUG_ON(!r);
759 ? dma_region_create(r) 1160 BUG_ON(!r->region_ops);
760 : dma_region_create_linear(r); 1161 BUG_ON(!r->region_ops->create);
1162 return r->region_ops->create(r);
761} 1163}
1164EXPORT_SYMBOL(ps3_dma_region_create);
762 1165
763int ps3_dma_region_free(struct ps3_dma_region *r) 1166int ps3_dma_region_free(struct ps3_dma_region *r)
764{ 1167{
765 return (USE_DYNAMIC_DMA) 1168 BUG_ON(!r);
766 ? dma_region_free(r) 1169 BUG_ON(!r->region_ops);
767 : dma_region_free_linear(r); 1170 BUG_ON(!r->region_ops->free);
1171 return r->region_ops->free(r);
768} 1172}
1173EXPORT_SYMBOL(ps3_dma_region_free);
769 1174
770int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, 1175int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
771 unsigned long len, unsigned long *bus_addr) 1176 unsigned long len, unsigned long *bus_addr,
1177 u64 iopte_flag)
772{ 1178{
773 return (USE_DYNAMIC_DMA) 1179 return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag);
774 ? dma_map_area(r, virt_addr, len, bus_addr)
775 : dma_map_area_linear(r, virt_addr, len, bus_addr);
776} 1180}
777 1181
778int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, 1182int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
779 unsigned long len) 1183 unsigned long len)
780{ 1184{
781 return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len) 1185 return r->region_ops->unmap(r, bus_addr, len);
782 : dma_unmap_area_linear(r, bus_addr, len);
783} 1186}
784 1187
785/*============================================================================*/ 1188/*============================================================================*/
@@ -810,12 +1213,13 @@ void __init ps3_mm_init(void)
810 BUG_ON(map.rm.base); 1213 BUG_ON(map.rm.base);
811 BUG_ON(!map.rm.size); 1214 BUG_ON(!map.rm.size);
812 1215
813 lmb_add(map.rm.base, map.rm.size);
814 lmb_analyze();
815 1216
816 /* arrange to do this in ps3_mm_add_memory */ 1217 /* arrange to do this in ps3_mm_add_memory */
817 ps3_mm_region_create(&map.r1, map.total - map.rm.size); 1218 ps3_mm_region_create(&map.r1, map.total - map.rm.size);
818 1219
1220 /* correct map.total for the real total amount of memory we use */
1221 map.total = map.rm.size + map.r1.size;
1222
819 DBG(" <- %s:%d\n", __func__, __LINE__); 1223 DBG(" <- %s:%d\n", __func__, __LINE__);
820} 1224}
821 1225
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index 5c3da08bc0c4..b70e474014f0 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -133,7 +133,7 @@ struct saved_params {
133} static saved_params; 133} static saved_params;
134 134
135#define dump_header(_a) _dump_header(_a, __func__, __LINE__) 135#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
136static void _dump_header(const struct os_area_header __iomem *h, const char* func, 136static void _dump_header(const struct os_area_header *h, const char *func,
137 int line) 137 int line)
138{ 138{
139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, 139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
@@ -151,7 +151,7 @@ static void _dump_header(const struct os_area_header __iomem *h, const char* fun
151} 151}
152 152
153#define dump_params(_a) _dump_params(_a, __func__, __LINE__) 153#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
154static void _dump_params(const struct os_area_params __iomem *p, const char* func, 154static void _dump_params(const struct os_area_params *p, const char *func,
155 int line) 155 int line)
156{ 156{
157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); 157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag);
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index ca04f03305c7..87d52060fec0 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -41,6 +41,7 @@ void ps3_mm_shutdown(void);
41/* irq */ 41/* irq */
42 42
43void ps3_init_IRQ(void); 43void ps3_init_IRQ(void);
44void ps3_shutdown_IRQ(int cpu);
44void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); 45void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
45 46
46/* smp */ 47/* smp */
@@ -82,6 +83,7 @@ enum ps3_dev_type {
82 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ 83 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
83 PS3_DEV_TYPE_SB_GPIO = 6, 84 PS3_DEV_TYPE_SB_GPIO = 6,
84 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ 85 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
86 PS3_DEV_TYPE_NOACCESS = 255,
85}; 87};
86 88
87int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 89int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -129,24 +131,28 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
129/* repository bus enumerators */ 131/* repository bus enumerators */
130 132
131struct ps3_repository_device { 133struct ps3_repository_device {
134 enum ps3_bus_type bus_type;
132 unsigned int bus_index; 135 unsigned int bus_index;
136 unsigned int bus_id;
137 enum ps3_dev_type dev_type;
133 unsigned int dev_index; 138 unsigned int dev_index;
134 struct ps3_device_id did; 139 unsigned int dev_id;
135}; 140};
136 141
137int ps3_repository_find_device(enum ps3_bus_type bus_type, 142static inline struct ps3_repository_device *ps3_repository_bump_device(
138 enum ps3_dev_type dev_type, 143 struct ps3_repository_device *repo)
139 const struct ps3_repository_device *start_dev,
140 struct ps3_repository_device *dev);
141static inline int ps3_repository_find_first_device(
142 enum ps3_bus_type bus_type, enum ps3_dev_type dev_type,
143 struct ps3_repository_device *dev)
144{ 144{
145 return ps3_repository_find_device(bus_type, dev_type, NULL, dev); 145 repo->dev_index++;
146 return repo;
146} 147}
147int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 148int ps3_repository_find_device(struct ps3_repository_device *repo);
149int ps3_repository_find_devices(enum ps3_bus_type bus_type,
150 int (*callback)(const struct ps3_repository_device *repo));
151int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
152 unsigned int *bus_index);
153int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
148 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); 154 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id);
149int ps3_repository_find_reg(const struct ps3_repository_device *dev, 155int ps3_repository_find_reg(const struct ps3_repository_device *repo,
150 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); 156 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len);
151 157
152/* repository block device info */ 158/* repository block device info */
@@ -216,4 +222,19 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id);
216int ps3_repository_read_spu_resource_id(unsigned int res_index, 222int ps3_repository_read_spu_resource_id(unsigned int res_index,
217 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); 223 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id);
218 224
225/* repository vuart info */
226
227int ps3_repository_read_vuart_av_port(unsigned int *port);
228int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
229
230/* Page table entries */
231#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
232#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
233#define IOPTE_M 0x2000000000000000ul /* coherency required */
234#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
235#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
236#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
237#define IOPTE_H 0x0000000000000800ul /* cache hint */
238#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
239
219#endif 240#endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index ae586a0e5d3f..8cc37cfea0f2 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -138,7 +138,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", 138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
139 __func__, __LINE__, ps3_result(result)); 139 __func__, __LINE__, ps3_result(result));
140 dump_node_name(lpar_id, n1, n2, n3, n4); 140 dump_node_name(lpar_id, n1, n2, n3, n4);
141 return result; 141 return -ENOENT;
142 } 142 }
143 143
144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2); 144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
@@ -155,7 +155,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", 155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
156 __func__, __LINE__, v2); 156 __func__, __LINE__, v2);
157 157
158 return result; 158 return 0;
159} 159}
160 160
161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -314,324 +314,140 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
314 reg_index, bus_addr, len); 314 reg_index, bus_addr, len);
315} 315}
316 316
317#if defined(DEBUG)
318int ps3_repository_dump_resource_info(unsigned int bus_index,
319 unsigned int dev_index)
320{
321 int result = 0;
322 unsigned int res_index;
323 317
324 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
325 bus_index, dev_index);
326 318
327 for (res_index = 0; res_index < 10; res_index++) { 319int ps3_repository_find_device(struct ps3_repository_device *repo)
328 enum ps3_interrupt_type intr_type; 320{
329 unsigned int interrupt_id; 321 int result;
322 struct ps3_repository_device tmp = *repo;
323 unsigned int num_dev;
330 324
331 result = ps3_repository_read_dev_intr(bus_index, dev_index, 325 BUG_ON(repo->bus_index > 10);
332 res_index, &intr_type, &interrupt_id); 326 BUG_ON(repo->dev_index > 10);
333 327
334 if (result) { 328 result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
335 if (result != LV1_NO_ENTRY)
336 pr_debug("%s:%d ps3_repository_read_dev_intr"
337 " (%u:%u) failed\n", __func__, __LINE__,
338 bus_index, dev_index);
339 break;
340 }
341 329
342 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", 330 if (result) {
343 __func__, __LINE__, bus_index, dev_index, intr_type, 331 pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
344 interrupt_id); 332 return result;
345 } 333 }
346 334
347 for (res_index = 0; res_index < 10; res_index++) { 335 pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n",
348 enum ps3_reg_type reg_type; 336 __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
349 u64 bus_addr; 337 num_dev);
350 u64 len;
351
352 result = ps3_repository_read_dev_reg(bus_index, dev_index,
353 res_index, &reg_type, &bus_addr, &len);
354 338
355 if (result) { 339 if (tmp.dev_index >= num_dev) {
356 if (result != LV1_NO_ENTRY) 340 pr_debug("%s:%d: no device found\n", __func__, __LINE__);
357 pr_debug("%s:%d ps3_repository_read_dev_reg" 341 return -ENODEV;
358 " (%u:%u) failed\n", __func__, __LINE__,
359 bus_index, dev_index);
360 break;
361 }
362
363 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
364 __func__, __LINE__, bus_index, dev_index, reg_type,
365 bus_addr, len);
366 } 342 }
367 343
368 pr_debug(" <- %s:%d\n", __func__, __LINE__); 344 result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
369 return result; 345 &tmp.dev_type);
370}
371
372static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index)
373{
374 int result = 0;
375 unsigned int num_regions, region_index;
376 u64 port, blk_size, num_blocks;
377
378 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
379 bus_index, dev_index);
380 346
381 result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port,
382 &blk_size, &num_blocks, &num_regions);
383 if (result) { 347 if (result) {
384 pr_debug("%s:%d ps3_repository_read_stor_dev_info" 348 pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__);
385 " (%u:%u) failed\n", __func__, __LINE__, 349 return result;
386 bus_index, dev_index);
387 goto out;
388 } 350 }
389 351
390 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " 352 result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
391 "%lu, num_regions %u\n", 353 &tmp.dev_id);
392 __func__, __LINE__, bus_index, dev_index, port,
393 blk_size, num_blocks, num_regions);
394
395 for (region_index = 0; region_index < num_regions; region_index++) {
396 unsigned int region_id;
397 u64 region_start, region_size;
398
399 result = ps3_repository_read_stor_dev_region(bus_index,
400 dev_index, region_index, &region_id, &region_start,
401 &region_size);
402 if (result) {
403 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
404 " (%u:%u) failed\n", __func__, __LINE__,
405 bus_index, dev_index);
406 break;
407 }
408 354
409 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", 355 if (result) {
410 __func__, __LINE__, bus_index, dev_index, region_id, 356 pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
411 region_start, region_size); 357 __LINE__);
358 return result;
412 } 359 }
413 360
414out: 361 pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n",
415 pr_debug(" <- %s:%d\n", __func__, __LINE__); 362 __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
416 return result;
417}
418
419static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type,
420 unsigned int num_dev)
421{
422 int result = 0;
423 unsigned int dev_index;
424
425 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
426
427 for (dev_index = 0; dev_index < num_dev; dev_index++) {
428 enum ps3_dev_type dev_type;
429 unsigned int dev_id;
430
431 result = ps3_repository_read_dev_type(bus_index, dev_index,
432 &dev_type);
433
434 if (result) {
435 pr_debug("%s:%d ps3_repository_read_dev_type"
436 " (%u:%u) failed\n", __func__, __LINE__,
437 bus_index, dev_index);
438 break;
439 }
440
441 result = ps3_repository_read_dev_id(bus_index, dev_index,
442 &dev_id);
443
444 if (result) {
445 pr_debug("%s:%d ps3_repository_read_dev_id"
446 " (%u:%u) failed\n", __func__, __LINE__,
447 bus_index, dev_index);
448 continue;
449 }
450 363
451 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, 364 *repo = tmp;
452 __LINE__, bus_index, dev_index, dev_type, dev_id); 365 return 0;
453
454 ps3_repository_dump_resource_info(bus_index, dev_index);
455
456 if (bus_type == PS3_BUS_TYPE_STORAGE)
457 dump_stor_dev_info(bus_index, dev_index);
458 }
459
460 pr_debug(" <- %s:%d\n", __func__, __LINE__);
461 return result;
462} 366}
463 367
464int ps3_repository_dump_bus_info(void) 368int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
369 int (*callback)(const struct ps3_repository_device *repo))
465{ 370{
466 int result = 0; 371 int result = 0;
467 unsigned int bus_index; 372 struct ps3_repository_device repo;
468 373
469 pr_debug(" -> %s:%d\n", __func__, __LINE__); 374 pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
470 375
471 for (bus_index = 0; bus_index < 10; bus_index++) { 376 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
472 enum ps3_bus_type bus_type;
473 unsigned int bus_id;
474 unsigned int num_dev;
475 377
476 result = ps3_repository_read_bus_type(bus_index, &bus_type); 378 result = ps3_repository_read_bus_type(repo.bus_index,
379 &repo.bus_type);
477 380
478 if (result) { 381 if (result) {
479 pr_debug("%s:%d read_bus_type(%u) failed\n", 382 pr_debug("%s:%d read_bus_type(%u) failed\n",
480 __func__, __LINE__, bus_index); 383 __func__, __LINE__, repo.bus_index);
481 break; 384 break;
482 } 385 }
483 386
484 result = ps3_repository_read_bus_id(bus_index, &bus_id); 387 if (repo.bus_type != bus_type) {
485 388 pr_debug("%s:%d: skip, bus_type %u\n", __func__,
486 if (result) { 389 __LINE__, repo.bus_type);
487 pr_debug("%s:%d read_bus_id(%u) failed\n",
488 __func__, __LINE__, bus_index);
489 continue; 390 continue;
490 } 391 }
491 392
492 if (bus_index != bus_id) 393 result = ps3_repository_read_bus_id(repo.bus_index,
493 pr_debug("%s:%d bus_index != bus_id\n", 394 &repo.bus_id);
494 __func__, __LINE__);
495
496 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
497 395
498 if (result) { 396 if (result) {
499 pr_debug("%s:%d read_bus_num_dev(%u) failed\n", 397 pr_debug("%s:%d read_bus_id(%u) failed\n",
500 __func__, __LINE__, bus_index); 398 __func__, __LINE__, repo.bus_index);
501 continue; 399 continue;
502 } 400 }
503 401
504 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", 402 for (repo.dev_index = 0; ; repo.dev_index++) {
505 __func__, __LINE__, bus_index, bus_type, bus_id, 403 result = ps3_repository_find_device(&repo);
506 num_dev);
507 404
508 dump_device_info(bus_index, bus_type, num_dev); 405 if (result == -ENODEV) {
509 } 406 result = 0;
407 break;
408 } else if (result)
409 break;
510 410
511 pr_debug(" <- %s:%d\n", __func__, __LINE__); 411 result = callback(&repo);
512 return result;
513}
514#endif /* defined(DEBUG) */
515
516static int find_device(unsigned int bus_index, unsigned int num_dev,
517 unsigned int start_dev_index, enum ps3_dev_type dev_type,
518 struct ps3_repository_device *dev)
519{
520 int result = 0;
521 unsigned int dev_index;
522 412
523 pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); 413 if (result) {
524 414 pr_debug("%s:%d: abort at callback\n", __func__,
525 dev->dev_index = UINT_MAX; 415 __LINE__);
526 416 break;
527 for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { 417 }
528 enum ps3_dev_type x;
529
530 result = ps3_repository_read_dev_type(bus_index, dev_index,
531 &x);
532
533 if (result) {
534 pr_debug("%s:%d read_dev_type failed\n",
535 __func__, __LINE__);
536 return result;
537 } 418 }
538 419 break;
539 if (x == dev_type)
540 break;
541 }
542
543 if (dev_index == num_dev)
544 return -1;
545
546 pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
547 __func__, __LINE__, dev_type, dev_index);
548
549 result = ps3_repository_read_dev_id(bus_index, dev_index,
550 &dev->did.dev_id);
551
552 if (result) {
553 pr_debug("%s:%d read_dev_id failed\n",
554 __func__, __LINE__);
555 return result;
556 } 420 }
557 421
558 dev->dev_index = dev_index; 422 pr_debug(" <- %s:%d\n", __func__, __LINE__);
559
560 pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
561 dev->did.dev_id);
562
563 return result; 423 return result;
564} 424}
565 425
566int ps3_repository_find_device (enum ps3_bus_type bus_type, 426int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
567 enum ps3_dev_type dev_type, 427 unsigned int *bus_index)
568 const struct ps3_repository_device *start_dev,
569 struct ps3_repository_device *dev)
570{ 428{
571 int result = 0; 429 unsigned int i;
572 unsigned int bus_index; 430 enum ps3_bus_type type;
573 unsigned int num_dev; 431 int error;
574
575 pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
576 bus_type, dev_type);
577
578 BUG_ON(start_dev && start_dev->bus_index > 10);
579
580 for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
581 bus_index++) {
582 enum ps3_bus_type x;
583
584 result = ps3_repository_read_bus_type(bus_index, &x);
585 432
586 if (result) { 433 for (i = from; i < 10; i++) {
434 error = ps3_repository_read_bus_type(i, &type);
435 if (error) {
587 pr_debug("%s:%d read_bus_type failed\n", 436 pr_debug("%s:%d read_bus_type failed\n",
588 __func__, __LINE__); 437 __func__, __LINE__);
589 dev->bus_index = UINT_MAX; 438 *bus_index = UINT_MAX;
590 return result; 439 return error;
440 }
441 if (type == bus_type) {
442 *bus_index = i;
443 return 0;
591 } 444 }
592 if (x == bus_type)
593 break;
594 }
595
596 if (bus_index >= 10)
597 return -ENODEV;
598
599 pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
600 __func__, __LINE__, bus_type, bus_index);
601
602 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
603
604 if (result) {
605 pr_debug("%s:%d read_bus_num_dev failed\n",
606 __func__, __LINE__);
607 return result;
608 }
609
610 result = find_device(bus_index, num_dev, start_dev
611 ? start_dev->dev_index + 1 : 0, dev_type, dev);
612
613 if (result) {
614 pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
615 return result;
616 }
617
618 result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
619
620 if (result) {
621 pr_debug("%s:%d read_bus_id failed\n",
622 __func__, __LINE__);
623 return result;
624 } 445 }
625 446 *bus_index = UINT_MAX;
626 dev->bus_index = bus_index; 447 return -ENODEV;
627
628 pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
629 __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
630
631 return result;
632} 448}
633 449
634int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 450int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
635 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) 451 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
636{ 452{
637 int result = 0; 453 int result = 0;
@@ -645,8 +461,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
645 enum ps3_interrupt_type t; 461 enum ps3_interrupt_type t;
646 unsigned int id; 462 unsigned int id;
647 463
648 result = ps3_repository_read_dev_intr(dev->bus_index, 464 result = ps3_repository_read_dev_intr(repo->bus_index,
649 dev->dev_index, res_index, &t, &id); 465 repo->dev_index, res_index, &t, &id);
650 466
651 if (result) { 467 if (result) {
652 pr_debug("%s:%d read_dev_intr failed\n", 468 pr_debug("%s:%d read_dev_intr failed\n",
@@ -669,7 +485,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
669 return result; 485 return result;
670} 486}
671 487
672int ps3_repository_find_reg(const struct ps3_repository_device *dev, 488int ps3_repository_find_reg(const struct ps3_repository_device *repo,
673 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) 489 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
674{ 490{
675 int result = 0; 491 int result = 0;
@@ -684,8 +500,8 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev,
684 u64 a; 500 u64 a;
685 u64 l; 501 u64 l;
686 502
687 result = ps3_repository_read_dev_reg(dev->bus_index, 503 result = ps3_repository_read_dev_reg(repo->bus_index,
688 dev->dev_index, res_index, &t, &a, &l); 504 repo->dev_index, res_index, &t, &a, &l);
689 505
690 if (result) { 506 if (result) {
691 pr_debug("%s:%d read_dev_reg failed\n", 507 pr_debug("%s:%d read_dev_reg failed\n",
@@ -965,6 +781,36 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
965 return result; 781 return result;
966} 782}
967 783
784int ps3_repository_read_vuart_av_port(unsigned int *port)
785{
786 int result;
787 u64 v1;
788
789 result = read_node(PS3_LPAR_ID_CURRENT,
790 make_first_field("bi", 0),
791 make_field("vir_uart", 0),
792 make_field("port", 0),
793 make_field("avset", 0),
794 &v1, 0);
795 *port = v1;
796 return result;
797}
798
799int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
800{
801 int result;
802 u64 v1;
803
804 result = read_node(PS3_LPAR_ID_CURRENT,
805 make_first_field("bi", 0),
806 make_field("vir_uart", 0),
807 make_field("port", 0),
808 make_field("sysmgr", 0),
809 &v1, 0);
810 *port = v1;
811 return result;
812}
813
968/** 814/**
969 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. 815 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
970 * address: lpar address of cell_ext_os_area 816 * address: lpar address of cell_ext_os_area
@@ -1026,3 +872,205 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
1026 return result ? result 872 return result ? result
1027 : ps3_repository_read_tb_freq(node_id, tb_freq); 873 : ps3_repository_read_tb_freq(node_id, tb_freq);
1028} 874}
875
876#if defined(DEBUG)
877
878int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
879{
880 int result = 0;
881 unsigned int res_index;
882
883 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
884 repo->bus_index, repo->dev_index);
885
886 for (res_index = 0; res_index < 10; res_index++) {
887 enum ps3_interrupt_type intr_type;
888 unsigned int interrupt_id;
889
890 result = ps3_repository_read_dev_intr(repo->bus_index,
891 repo->dev_index, res_index, &intr_type, &interrupt_id);
892
893 if (result) {
894 if (result != LV1_NO_ENTRY)
895 pr_debug("%s:%d ps3_repository_read_dev_intr"
896 " (%u:%u) failed\n", __func__, __LINE__,
897 repo->bus_index, repo->dev_index);
898 break;
899 }
900
901 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
902 __func__, __LINE__, repo->bus_index, repo->dev_index,
903 intr_type, interrupt_id);
904 }
905
906 for (res_index = 0; res_index < 10; res_index++) {
907 enum ps3_reg_type reg_type;
908 u64 bus_addr;
909 u64 len;
910
911 result = ps3_repository_read_dev_reg(repo->bus_index,
912 repo->dev_index, res_index, &reg_type, &bus_addr, &len);
913
914 if (result) {
915 if (result != LV1_NO_ENTRY)
916 pr_debug("%s:%d ps3_repository_read_dev_reg"
917 " (%u:%u) failed\n", __func__, __LINE__,
918 repo->bus_index, repo->dev_index);
919 break;
920 }
921
922 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
923 __func__, __LINE__, repo->bus_index, repo->dev_index,
924 reg_type, bus_addr, len);
925 }
926
927 pr_debug(" <- %s:%d\n", __func__, __LINE__);
928 return result;
929}
930
931static int dump_stor_dev_info(struct ps3_repository_device *repo)
932{
933 int result = 0;
934 unsigned int num_regions, region_index;
935 u64 port, blk_size, num_blocks;
936
937 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
938 repo->bus_index, repo->dev_index);
939
940 result = ps3_repository_read_stor_dev_info(repo->bus_index,
941 repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
942 if (result) {
943 pr_debug("%s:%d ps3_repository_read_stor_dev_info"
944 " (%u:%u) failed\n", __func__, __LINE__,
945 repo->bus_index, repo->dev_index);
946 goto out;
947 }
948
949 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks "
950 "%lu, num_regions %u\n",
951 __func__, __LINE__, repo->bus_index, repo->dev_index, port,
952 blk_size, num_blocks, num_regions);
953
954 for (region_index = 0; region_index < num_regions; region_index++) {
955 unsigned int region_id;
956 u64 region_start, region_size;
957
958 result = ps3_repository_read_stor_dev_region(repo->bus_index,
959 repo->dev_index, region_index, &region_id,
960 &region_start, &region_size);
961 if (result) {
962 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
963 " (%u:%u) failed\n", __func__, __LINE__,
964 repo->bus_index, repo->dev_index);
965 break;
966 }
967
968 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
969 __func__, __LINE__, repo->bus_index, repo->dev_index,
970 region_id, region_start, region_size);
971 }
972
973out:
974 pr_debug(" <- %s:%d\n", __func__, __LINE__);
975 return result;
976}
977
978static int dump_device_info(struct ps3_repository_device *repo,
979 unsigned int num_dev)
980{
981 int result = 0;
982
983 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
984
985 for (repo->dev_index = 0; repo->dev_index < num_dev;
986 repo->dev_index++) {
987
988 result = ps3_repository_read_dev_type(repo->bus_index,
989 repo->dev_index, &repo->dev_type);
990
991 if (result) {
992 pr_debug("%s:%d ps3_repository_read_dev_type"
993 " (%u:%u) failed\n", __func__, __LINE__,
994 repo->bus_index, repo->dev_index);
995 break;
996 }
997
998 result = ps3_repository_read_dev_id(repo->bus_index,
999 repo->dev_index, &repo->dev_id);
1000
1001 if (result) {
1002 pr_debug("%s:%d ps3_repository_read_dev_id"
1003 " (%u:%u) failed\n", __func__, __LINE__,
1004 repo->bus_index, repo->dev_index);
1005 continue;
1006 }
1007
1008 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
1009 __LINE__, repo->bus_index, repo->dev_index,
1010 repo->dev_type, repo->dev_id);
1011
1012 ps3_repository_dump_resource_info(repo);
1013
1014 if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
1015 dump_stor_dev_info(repo);
1016 }
1017
1018 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1019 return result;
1020}
1021
1022int ps3_repository_dump_bus_info(void)
1023{
1024 int result = 0;
1025 struct ps3_repository_device repo;
1026
1027 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1028
1029 memset(&repo, 0, sizeof(repo));
1030
1031 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
1032 unsigned int num_dev;
1033
1034 result = ps3_repository_read_bus_type(repo.bus_index,
1035 &repo.bus_type);
1036
1037 if (result) {
1038 pr_debug("%s:%d read_bus_type(%u) failed\n",
1039 __func__, __LINE__, repo.bus_index);
1040 break;
1041 }
1042
1043 result = ps3_repository_read_bus_id(repo.bus_index,
1044 &repo.bus_id);
1045
1046 if (result) {
1047 pr_debug("%s:%d read_bus_id(%u) failed\n",
1048 __func__, __LINE__, repo.bus_index);
1049 continue;
1050 }
1051
1052 if (repo.bus_index != repo.bus_id)
1053 pr_debug("%s:%d bus_index != bus_id\n",
1054 __func__, __LINE__);
1055
1056 result = ps3_repository_read_bus_num_dev(repo.bus_index,
1057 &num_dev);
1058
1059 if (result) {
1060 pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
1061 __func__, __LINE__, repo.bus_index);
1062 continue;
1063 }
1064
1065 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
1066 __func__, __LINE__, repo.bus_index, repo.bus_type,
1067 repo.bus_id, num_dev);
1068
1069 dump_device_info(&repo, num_dev);
1070 }
1071
1072 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1073 return result;
1074}
1075
1076#endif /* defined(DEBUG) */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 935396766621..aa05288de64e 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -37,27 +37,35 @@
37#include "platform.h" 37#include "platform.h"
38 38
39#if defined(DEBUG) 39#if defined(DEBUG)
40#define DBG(fmt...) udbg_printf(fmt) 40#define DBG udbg_printf
41#else 41#else
42#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 42#define DBG pr_debug
43#endif 43#endif
44 44
45#if !defined(CONFIG_SMP) 45#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {} 46static void smp_send_stop(void) {}
47#endif 47#endif
48 48
49int ps3_get_firmware_version(union ps3_firmware_version *v) 49static union ps3_firmware_version ps3_firmware_version;
50
51void ps3_get_firmware_version(union ps3_firmware_version *v)
50{ 52{
51 int result = lv1_get_version_info(&v->raw); 53 *v = ps3_firmware_version;
54}
55EXPORT_SYMBOL_GPL(ps3_get_firmware_version);
52 56
53 if (result) { 57int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
54 v->raw = 0; 58{
55 return -1; 59 union ps3_firmware_version x;
56 } 60
61 x.pad = 0;
62 x.major = major;
63 x.minor = minor;
64 x.rev = rev;
57 65
58 return result; 66 return (ps3_firmware_version.raw - x.raw);
59} 67}
60EXPORT_SYMBOL_GPL(ps3_get_firmware_version); 68EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
61 69
62static void ps3_power_save(void) 70static void ps3_power_save(void)
63{ 71{
@@ -99,7 +107,8 @@ static void ps3_panic(char *str)
99 while(1); 107 while(1);
100} 108}
101 109
102#ifdef CONFIG_FB_PS3 110#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
111 defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
103static void prealloc(struct ps3_prealloc *p) 112static void prealloc(struct ps3_prealloc *p)
104{ 113{
105 if (!p->size) 114 if (!p->size)
@@ -115,12 +124,15 @@ static void prealloc(struct ps3_prealloc *p)
115 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, 124 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
116 p->address); 125 p->address);
117} 126}
127#endif
118 128
129#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
119struct ps3_prealloc ps3fb_videomemory = { 130struct ps3_prealloc ps3fb_videomemory = {
120 .name = "ps3fb videomemory", 131 .name = "ps3fb videomemory",
121 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, 132 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
122 .align = 1024*1024 /* the GPU requires 1 MiB alignment */ 133 .align = 1024*1024 /* the GPU requires 1 MiB alignment */
123}; 134};
135EXPORT_SYMBOL_GPL(ps3fb_videomemory);
124#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory) 136#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
125 137
126static int __init early_parse_ps3fb(char *p) 138static int __init early_parse_ps3fb(char *p)
@@ -137,6 +149,30 @@ early_param("ps3fb", early_parse_ps3fb);
137#define prealloc_ps3fb_videomemory() do { } while (0) 149#define prealloc_ps3fb_videomemory() do { } while (0)
138#endif 150#endif
139 151
152#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
153struct ps3_prealloc ps3flash_bounce_buffer = {
154 .name = "ps3flash bounce buffer",
155 .size = 256*1024,
156 .align = 256*1024
157};
158EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer);
159#define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer)
160
161static int __init early_parse_ps3flash(char *p)
162{
163 if (!p)
164 return 1;
165
166 if (!strcmp(p, "off"))
167 ps3flash_bounce_buffer.size = 0;
168
169 return 0;
170}
171early_param("ps3flash", early_parse_ps3flash);
172#else
173#define prealloc_ps3flash_bounce_buffer() do { } while (0)
174#endif
175
140static int ps3_set_dabr(u64 dabr) 176static int ps3_set_dabr(u64 dabr)
141{ 177{
142 enum {DABR_USER = 1, DABR_KERNEL = 2,}; 178 enum {DABR_USER = 1, DABR_KERNEL = 2,};
@@ -146,13 +182,13 @@ static int ps3_set_dabr(u64 dabr)
146 182
147static void __init ps3_setup_arch(void) 183static void __init ps3_setup_arch(void)
148{ 184{
149 union ps3_firmware_version v;
150 185
151 DBG(" -> %s:%d\n", __func__, __LINE__); 186 DBG(" -> %s:%d\n", __func__, __LINE__);
152 187
153 ps3_get_firmware_version(&v); 188 lv1_get_version_info(&ps3_firmware_version.raw);
154 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", v.major, v.minor, 189 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n",
155 v.rev); 190 ps3_firmware_version.major, ps3_firmware_version.minor,
191 ps3_firmware_version.rev);
156 192
157 ps3_spu_set_platform(); 193 ps3_spu_set_platform();
158 ps3_map_htab(); 194 ps3_map_htab();
@@ -166,6 +202,8 @@ static void __init ps3_setup_arch(void)
166#endif 202#endif
167 203
168 prealloc_ps3fb_videomemory(); 204 prealloc_ps3fb_videomemory();
205 prealloc_ps3flash_bounce_buffer();
206
169 ppc_md.power_save = ps3_power_save; 207 ppc_md.power_save = ps3_power_save;
170 208
171 DBG(" <- %s:%d\n", __func__, __LINE__); 209 DBG(" <- %s:%d\n", __func__, __LINE__);
@@ -184,7 +222,7 @@ static int __init ps3_probe(void)
184 DBG(" -> %s:%d\n", __func__, __LINE__); 222 DBG(" -> %s:%d\n", __func__, __LINE__);
185 223
186 dt_root = of_get_flat_dt_root(); 224 dt_root = of_get_flat_dt_root();
187 if (!of_flat_dt_is_compatible(dt_root, "PS3")) 225 if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
188 return 0; 226 return 0;
189 227
190 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; 228 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
@@ -201,31 +239,12 @@ static int __init ps3_probe(void)
201#if defined(CONFIG_KEXEC) 239#if defined(CONFIG_KEXEC)
202static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) 240static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
203{ 241{
204 DBG(" -> %s:%d\n", __func__, __LINE__); 242 int cpu = smp_processor_id();
205
206 if (secondary) {
207 int cpu;
208 for_each_online_cpu(cpu)
209 if (cpu)
210 ps3_smp_cleanup_cpu(cpu);
211 } else
212 ps3_smp_cleanup_cpu(0);
213
214 DBG(" <- %s:%d\n", __func__, __LINE__);
215}
216
217static void ps3_machine_kexec(struct kimage *image)
218{
219 unsigned long ppe_id;
220
221 DBG(" -> %s:%d\n", __func__, __LINE__);
222 243
223 lv1_get_logical_ppe_id(&ppe_id); 244 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
224 lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
225 ps3_mm_shutdown();
226 ps3_mm_vas_destroy();
227 245
228 default_machine_kexec(image); 246 ps3_smp_cleanup_cpu(cpu);
247 ps3_shutdown_IRQ(cpu);
229 248
230 DBG(" <- %s:%d\n", __func__, __LINE__); 249 DBG(" <- %s:%d\n", __func__, __LINE__);
231} 250}
@@ -247,7 +266,7 @@ define_machine(ps3) {
247 .power_off = ps3_power_off, 266 .power_off = ps3_power_off,
248#if defined(CONFIG_KEXEC) 267#if defined(CONFIG_KEXEC)
249 .kexec_cpu_down = ps3_kexec_cpu_down, 268 .kexec_cpu_down = ps3_kexec_cpu_down,
250 .machine_kexec = ps3_machine_kexec, 269 .machine_kexec = default_machine_kexec,
251 .machine_kexec_prepare = default_machine_kexec_prepare, 270 .machine_kexec_prepare = default_machine_kexec_prepare,
252 .machine_crash_shutdown = default_machine_crash_shutdown, 271 .machine_crash_shutdown = default_machine_crash_shutdown,
253#endif 272#endif
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 53416ec5198b..f0b12f212363 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -27,9 +27,9 @@
27#include "platform.h" 27#include "platform.h"
28 28
29#if defined(DEBUG) 29#if defined(DEBUG)
30#define DBG(fmt...) udbg_printf(fmt) 30#define DBG udbg_printf
31#else 31#else
32#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 32#define DBG pr_debug
33#endif 33#endif
34 34
35static irqreturn_t ipi_function_handler(int irq, void *msg) 35static irqreturn_t ipi_function_handler(int irq, void *msg)
@@ -39,11 +39,11 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
39} 39}
40 40
41/** 41/**
42 * virqs - a per cpu array of virqs for ipi use 42 * ps3_ipi_virqs - a per cpu array of virqs for ipi use
43 */ 43 */
44 44
45#define MSG_COUNT 4 45#define MSG_COUNT 4
46static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); 46static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
47 47
48static const char *names[MSG_COUNT] = { 48static const char *names[MSG_COUNT] = {
49 "ipi call", 49 "ipi call",
@@ -62,7 +62,7 @@ static void do_message_pass(int target, int msg)
62 return; 62 return;
63 } 63 }
64 64
65 virq = per_cpu(virqs, target)[msg]; 65 virq = per_cpu(ps3_ipi_virqs, target)[msg];
66 result = ps3_send_event_locally(virq); 66 result = ps3_send_event_locally(virq);
67 67
68 if (result) 68 if (result)
@@ -94,13 +94,13 @@ static int ps3_smp_probe(void)
94static void __init ps3_smp_setup_cpu(int cpu) 94static void __init ps3_smp_setup_cpu(int cpu)
95{ 95{
96 int result; 96 int result;
97 unsigned int *virqs = per_cpu(virqs, cpu); 97 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
98 int i; 98 int i;
99 99
100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
101 101
102 /* 102 /*
103 * Check assumptions on virqs[] indexing. If this 103 * Check assumptions on ps3_ipi_virqs[] indexing. If this
104 * check fails, then a different mapping of PPC_MSG_ 104 * check fails, then a different mapping of PPC_MSG_
105 * to index needs to be setup. 105 * to index needs to be setup.
106 */ 106 */
@@ -132,13 +132,13 @@ static void __init ps3_smp_setup_cpu(int cpu)
132 132
133void ps3_smp_cleanup_cpu(int cpu) 133void ps3_smp_cleanup_cpu(int cpu)
134{ 134{
135 unsigned int *virqs = per_cpu(virqs, cpu); 135 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
136 int i; 136 int i;
137 137
138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
139 139
140 for (i = 0; i < MSG_COUNT; i++) { 140 for (i = 0; i < MSG_COUNT; i++) {
141 free_irq(virqs[i], (void*)(long)i); 141 /* Can't call free_irq from interrupt context. */
142 ps3_event_receive_port_destroy(virqs[i]); 142 ps3_event_receive_port_destroy(virqs[i]);
143 virqs[i] = NO_IRQ; 143 virqs[i] = NO_IRQ;
144 } 144 }
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index 651437cb2c18..c7f734c89462 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -182,15 +182,18 @@ static int __init setup_areas(struct spu *spu)
182{ 182{
183 struct table {char* name; unsigned long addr; unsigned long size;}; 183 struct table {char* name; unsigned long addr; unsigned long size;};
184 184
185 spu_pdata(spu)->shadow = __ioremap( 185 spu_pdata(spu)->shadow = ioremap_flags(spu_pdata(spu)->shadow_addr,
186 spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), 186 sizeof(struct spe_shadow),
187 pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED); 187 pgprot_val(PAGE_READONLY) |
188 _PAGE_NO_CACHE);
188 if (!spu_pdata(spu)->shadow) { 189 if (!spu_pdata(spu)->shadow) {
189 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); 190 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
190 goto fail_ioremap; 191 goto fail_ioremap;
191 } 192 }
192 193
193 spu->local_store = ioremap(spu->local_store_phys, LS_SIZE); 194 spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
195 LS_SIZE, _PAGE_NO_CACHE);
196
194 if (!spu->local_store) { 197 if (!spu->local_store) {
195 pr_debug("%s:%d: ioremap local_store failed\n", 198 pr_debug("%s:%d: ioremap local_store failed\n",
196 __func__, __LINE__); 199 __func__, __LINE__);
@@ -199,6 +202,7 @@ static int __init setup_areas(struct spu *spu)
199 202
200 spu->problem = ioremap(spu->problem_phys, 203 spu->problem = ioremap(spu->problem_phys,
201 sizeof(struct spu_problem)); 204 sizeof(struct spu_problem));
205
202 if (!spu->problem) { 206 if (!spu->problem) {
203 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); 207 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
204 goto fail_ioremap; 208 goto fail_ioremap;
@@ -206,6 +210,7 @@ static int __init setup_areas(struct spu *spu)
206 210
207 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, 211 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
208 sizeof(struct spu_priv2)); 212 sizeof(struct spu_priv2));
213
209 if (!spu->priv2) { 214 if (!spu->priv2) {
210 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); 215 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
211 goto fail_ioremap; 216 goto fail_ioremap;
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6bda51027cc6..4bb634a17e43 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -30,22 +30,228 @@
30 30
31#include "platform.h" 31#include "platform.h"
32 32
33static struct device ps3_system_bus = {
34 .bus_id = "ps3_system",
35};
36
37/* FIXME: need device usage counters! */
38struct {
39 struct mutex mutex;
40 int sb_11; /* usb 0 */
41 int sb_12; /* usb 0 */
42 int gpu;
43} static usage_hack;
44
45static int ps3_is_device(struct ps3_system_bus_device *dev,
46 unsigned int bus_id, unsigned int dev_id)
47{
48 return dev->bus_id == bus_id && dev->dev_id == dev_id;
49}
50
51static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
52{
53 int result;
54
55 BUG_ON(!dev->bus_id);
56 mutex_lock(&usage_hack.mutex);
57
58 if (ps3_is_device(dev, 1, 1)) {
59 usage_hack.sb_11++;
60 if (usage_hack.sb_11 > 1) {
61 result = 0;
62 goto done;
63 }
64 }
65
66 if (ps3_is_device(dev, 1, 2)) {
67 usage_hack.sb_12++;
68 if (usage_hack.sb_12 > 1) {
69 result = 0;
70 goto done;
71 }
72 }
73
74 result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
75
76 if (result) {
77 pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
78 __LINE__, ps3_result(result));
79 result = -EPERM;
80 }
81
82done:
83 mutex_unlock(&usage_hack.mutex);
84 return result;
85}
86
87static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
88{
89 int result;
90
91 BUG_ON(!dev->bus_id);
92 mutex_lock(&usage_hack.mutex);
93
94 if (ps3_is_device(dev, 1, 1)) {
95 usage_hack.sb_11--;
96 if (usage_hack.sb_11) {
97 result = 0;
98 goto done;
99 }
100 }
101
102 if (ps3_is_device(dev, 1, 2)) {
103 usage_hack.sb_12--;
104 if (usage_hack.sb_12) {
105 result = 0;
106 goto done;
107 }
108 }
109
110 result = lv1_close_device(dev->bus_id, dev->dev_id);
111 BUG_ON(result);
112
113done:
114 mutex_unlock(&usage_hack.mutex);
115 return result;
116}
117
118static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
119{
120 int result;
121
122 mutex_lock(&usage_hack.mutex);
123
124 usage_hack.gpu++;
125 if (usage_hack.gpu > 1) {
126 result = 0;
127 goto done;
128 }
129
130 result = lv1_gpu_open(0);
131
132 if (result) {
133 pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
134 __LINE__, ps3_result(result));
135 result = -EPERM;
136 }
137
138done:
139 mutex_unlock(&usage_hack.mutex);
140 return result;
141}
142
143static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
144{
145 int result;
146
147 mutex_lock(&usage_hack.mutex);
148
149 usage_hack.gpu--;
150 if (usage_hack.gpu) {
151 result = 0;
152 goto done;
153 }
154
155 result = lv1_gpu_close();
156 BUG_ON(result);
157
158done:
159 mutex_unlock(&usage_hack.mutex);
160 return result;
161}
162
163int ps3_open_hv_device(struct ps3_system_bus_device *dev)
164{
165 BUG_ON(!dev);
166 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
167
168 switch (dev->match_id) {
169 case PS3_MATCH_ID_EHCI:
170 case PS3_MATCH_ID_OHCI:
171 case PS3_MATCH_ID_GELIC:
172 case PS3_MATCH_ID_STOR_DISK:
173 case PS3_MATCH_ID_STOR_ROM:
174 case PS3_MATCH_ID_STOR_FLASH:
175 return ps3_open_hv_device_sb(dev);
176
177 case PS3_MATCH_ID_SOUND:
178 case PS3_MATCH_ID_GRAPHICS:
179 return ps3_open_hv_device_gpu(dev);
180
181 case PS3_MATCH_ID_AV_SETTINGS:
182 case PS3_MATCH_ID_SYSTEM_MANAGER:
183 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
184 __LINE__, dev->match_id);
185 pr_debug("%s:%d: bus_id: %u\n", __func__,
186 __LINE__, dev->bus_id);
187 BUG();
188 return -EINVAL;
189
190 default:
191 break;
192 }
193
194 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
195 dev->match_id);
196 BUG();
197 return -ENODEV;
198}
199EXPORT_SYMBOL_GPL(ps3_open_hv_device);
200
201int ps3_close_hv_device(struct ps3_system_bus_device *dev)
202{
203 BUG_ON(!dev);
204 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
205
206 switch (dev->match_id) {
207 case PS3_MATCH_ID_EHCI:
208 case PS3_MATCH_ID_OHCI:
209 case PS3_MATCH_ID_GELIC:
210 case PS3_MATCH_ID_STOR_DISK:
211 case PS3_MATCH_ID_STOR_ROM:
212 case PS3_MATCH_ID_STOR_FLASH:
213 return ps3_close_hv_device_sb(dev);
214
215 case PS3_MATCH_ID_SOUND:
216 case PS3_MATCH_ID_GRAPHICS:
217 return ps3_close_hv_device_gpu(dev);
218
219 case PS3_MATCH_ID_AV_SETTINGS:
220 case PS3_MATCH_ID_SYSTEM_MANAGER:
221 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
222 __LINE__, dev->match_id);
223 pr_debug("%s:%d: bus_id: %u\n", __func__,
224 __LINE__, dev->bus_id);
225 BUG();
226 return -EINVAL;
227
228 default:
229 break;
230 }
231
232 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
233 dev->match_id);
234 BUG();
235 return -ENODEV;
236}
237EXPORT_SYMBOL_GPL(ps3_close_hv_device);
238
33#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) 239#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
34static void _dump_mmio_region(const struct ps3_mmio_region* r, 240static void _dump_mmio_region(const struct ps3_mmio_region* r,
35 const char* func, int line) 241 const char* func, int line)
36{ 242{
37 pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 243 pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
38 r->did.dev_id); 244 r->dev->dev_id);
39 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 245 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
40 pr_debug("%s:%d: len %lxh\n", func, line, r->len); 246 pr_debug("%s:%d: len %lxh\n", func, line, r->len);
41 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr); 247 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
42} 248}
43 249
44int ps3_mmio_region_create(struct ps3_mmio_region *r) 250static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
45{ 251{
46 int result; 252 int result;
47 253
48 result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id, 254 result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
49 r->bus_addr, r->len, r->page_size, &r->lpar_addr); 255 r->bus_addr, r->len, r->page_size, &r->lpar_addr);
50 256
51 if (result) { 257 if (result) {
@@ -57,13 +263,26 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r)
57 dump_mmio_region(r); 263 dump_mmio_region(r);
58 return result; 264 return result;
59} 265}
266
267static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
268{
269 /* device specific; do nothing currently */
270 return 0;
271}
272
273int ps3_mmio_region_create(struct ps3_mmio_region *r)
274{
275 return r->mmio_ops->create(r);
276}
60EXPORT_SYMBOL_GPL(ps3_mmio_region_create); 277EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
61 278
62int ps3_free_mmio_region(struct ps3_mmio_region *r) 279static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
63{ 280{
64 int result; 281 int result;
65 282
66 result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, 283 dump_mmio_region(r);
284;
285 result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
67 r->lpar_addr); 286 r->lpar_addr);
68 287
69 if (result) 288 if (result)
@@ -73,14 +292,60 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r)
73 r->lpar_addr = 0; 292 r->lpar_addr = 0;
74 return result; 293 return result;
75} 294}
295
296static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
297{
298 /* device specific; do nothing currently */
299 return 0;
300}
301
302
303int ps3_free_mmio_region(struct ps3_mmio_region *r)
304{
305 return r->mmio_ops->free(r);
306}
307
76EXPORT_SYMBOL_GPL(ps3_free_mmio_region); 308EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
77 309
310static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
311 .create = ps3_sb_mmio_region_create,
312 .free = ps3_sb_free_mmio_region
313};
314
315static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
316 .create = ps3_ioc0_mmio_region_create,
317 .free = ps3_ioc0_free_mmio_region
318};
319
320int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
321 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
322 enum ps3_mmio_page_size page_size)
323{
324 r->dev = dev;
325 r->bus_addr = bus_addr;
326 r->len = len;
327 r->page_size = page_size;
328 switch (dev->dev_type) {
329 case PS3_DEVICE_TYPE_SB:
330 r->mmio_ops = &ps3_mmio_sb_region_ops;
331 break;
332 case PS3_DEVICE_TYPE_IOC0:
333 r->mmio_ops = &ps3_mmio_ioc0_region_ops;
334 break;
335 default:
336 BUG();
337 return -EINVAL;
338 }
339 return 0;
340}
341EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
342
78static int ps3_system_bus_match(struct device *_dev, 343static int ps3_system_bus_match(struct device *_dev,
79 struct device_driver *_drv) 344 struct device_driver *_drv)
80{ 345{
81 int result; 346 int result;
82 struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv); 347 struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
83 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 348 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
84 349
85 result = dev->match_id == drv->match_id; 350 result = dev->match_id == drv->match_id;
86 351
@@ -92,32 +357,14 @@ static int ps3_system_bus_match(struct device *_dev,
92 357
93static int ps3_system_bus_probe(struct device *_dev) 358static int ps3_system_bus_probe(struct device *_dev)
94{ 359{
95 int result; 360 int result = 0;
96 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 361 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
97 struct ps3_system_bus_driver *drv = 362 struct ps3_system_bus_driver *drv;
98 to_ps3_system_bus_driver(_dev->driver);
99
100 result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
101
102 if (result) {
103 pr_debug("%s:%d: lv1_open_device failed (%d)\n",
104 __func__, __LINE__, result);
105 result = -EACCES;
106 goto clean_none;
107 }
108
109 if (dev->d_region->did.bus_id) {
110 result = ps3_dma_region_create(dev->d_region);
111 363
112 if (result) { 364 BUG_ON(!dev);
113 pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n", 365 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
114 __func__, __LINE__, result);
115 BUG_ON("check region type");
116 result = -EINVAL;
117 goto clean_device;
118 }
119 }
120 366
367 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
121 BUG_ON(!drv); 368 BUG_ON(!drv);
122 369
123 if (drv->probe) 370 if (drv->probe)
@@ -126,56 +373,127 @@ static int ps3_system_bus_probe(struct device *_dev)
126 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, 373 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
127 dev->core.bus_id); 374 dev->core.bus_id);
128 375
129 if (result) { 376 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
130 pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
131 goto clean_dma;
132 }
133
134 return result;
135
136clean_dma:
137 ps3_dma_region_free(dev->d_region);
138clean_device:
139 lv1_close_device(dev->did.bus_id, dev->did.dev_id);
140clean_none:
141 return result; 377 return result;
142} 378}
143 379
144static int ps3_system_bus_remove(struct device *_dev) 380static int ps3_system_bus_remove(struct device *_dev)
145{ 381{
146 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 382 int result = 0;
147 struct ps3_system_bus_driver *drv = 383 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
148 to_ps3_system_bus_driver(_dev->driver); 384 struct ps3_system_bus_driver *drv;
385
386 BUG_ON(!dev);
387 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
388
389 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
390 BUG_ON(!drv);
149 391
150 if (drv->remove) 392 if (drv->remove)
151 drv->remove(dev); 393 result = drv->remove(dev);
152 else 394 else
153 pr_info("%s:%d: %s no remove method\n", __func__, __LINE__, 395 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
154 dev->core.bus_id); 396 __func__, __LINE__, drv->core.name);
397
398 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
399 return result;
400}
401
402static void ps3_system_bus_shutdown(struct device *_dev)
403{
404 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
405 struct ps3_system_bus_driver *drv;
406
407 BUG_ON(!dev);
408
409 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
410 dev->match_id);
411
412 if (!dev->core.driver) {
413 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
414 __LINE__);
415 return;
416 }
417
418 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
419
420 BUG_ON(!drv);
421
422 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
423 dev->core.bus_id, drv->core.name);
424
425 if (drv->shutdown)
426 drv->shutdown(dev);
427 else if (drv->remove) {
428 dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
429 __func__, __LINE__, drv->core.name);
430 drv->remove(dev);
431 } else {
432 dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
433 __func__, __LINE__, drv->core.name);
434 BUG();
435 }
436
437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
438}
439
440static int ps3_system_bus_uevent(struct device *_dev, char **envp,
441 int num_envp, char *buffer, int buffer_size)
442{
443 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
444 int i = 0, length = 0;
155 445
156 ps3_dma_region_free(dev->d_region); 446 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
157 ps3_free_mmio_region(dev->m_region); 447 &length, "MODALIAS=ps3:%d",
158 lv1_close_device(dev->did.bus_id, dev->did.dev_id); 448 dev->match_id))
449 return -ENOMEM;
159 450
451 envp[i] = NULL;
160 return 0; 452 return 0;
161} 453}
162 454
455static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
456 char *buf)
457{
458 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
459 int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id);
460
461 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
462}
463
464static struct device_attribute ps3_system_bus_dev_attrs[] = {
465 __ATTR_RO(modalias),
466 __ATTR_NULL,
467};
468
163struct bus_type ps3_system_bus_type = { 469struct bus_type ps3_system_bus_type = {
164 .name = "ps3_system_bus", 470 .name = "ps3_system_bus",
165 .match = ps3_system_bus_match, 471 .match = ps3_system_bus_match,
472 .uevent = ps3_system_bus_uevent,
166 .probe = ps3_system_bus_probe, 473 .probe = ps3_system_bus_probe,
167 .remove = ps3_system_bus_remove, 474 .remove = ps3_system_bus_remove,
475 .shutdown = ps3_system_bus_shutdown,
476 .dev_attrs = ps3_system_bus_dev_attrs,
168}; 477};
169 478
170int __init ps3_system_bus_init(void) 479static int __init ps3_system_bus_init(void)
171{ 480{
172 int result; 481 int result;
173 482
174 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 483 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
175 return -ENODEV; 484 return -ENODEV;
176 485
486 pr_debug(" -> %s:%d\n", __func__, __LINE__);
487
488 mutex_init(&usage_hack.mutex);
489
490 result = device_register(&ps3_system_bus);
491 BUG_ON(result);
492
177 result = bus_register(&ps3_system_bus_type); 493 result = bus_register(&ps3_system_bus_type);
178 BUG_ON(result); 494 BUG_ON(result);
495
496 pr_debug(" <- %s:%d\n", __func__, __LINE__);
179 return result; 497 return result;
180} 498}
181 499
@@ -185,16 +503,13 @@ core_initcall(ps3_system_bus_init);
185 * Returns the virtual address of the buffer and sets dma_handle 503 * Returns the virtual address of the buffer and sets dma_handle
186 * to the dma address (mapping) of the first page. 504 * to the dma address (mapping) of the first page.
187 */ 505 */
188
189static void * ps3_alloc_coherent(struct device *_dev, size_t size, 506static void * ps3_alloc_coherent(struct device *_dev, size_t size,
190 dma_addr_t *dma_handle, gfp_t flag) 507 dma_addr_t *dma_handle, gfp_t flag)
191{ 508{
192 int result; 509 int result;
193 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 510 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
194 unsigned long virt_addr; 511 unsigned long virt_addr;
195 512
196 BUG_ON(!dev->d_region->bus_addr);
197
198 flag &= ~(__GFP_DMA | __GFP_HIGHMEM); 513 flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
199 flag |= __GFP_ZERO; 514 flag |= __GFP_ZERO;
200 515
@@ -205,7 +520,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
205 goto clean_none; 520 goto clean_none;
206 } 521 }
207 522
208 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle); 523 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
524 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
209 525
210 if (result) { 526 if (result) {
211 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 527 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -226,7 +542,7 @@ clean_none:
226static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, 542static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
227 dma_addr_t dma_handle) 543 dma_addr_t dma_handle)
228{ 544{
229 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 545 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
230 546
231 ps3_dma_unmap(dev->d_region, dma_handle, size); 547 ps3_dma_unmap(dev->d_region, dma_handle, size);
232 free_pages((unsigned long)vaddr, get_order(size)); 548 free_pages((unsigned long)vaddr, get_order(size));
@@ -239,15 +555,16 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
239 * byte within the page as vaddr. 555 * byte within the page as vaddr.
240 */ 556 */
241 557
242static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size, 558static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
243 enum dma_data_direction direction) 559 enum dma_data_direction direction)
244{ 560{
245 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 561 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
246 int result; 562 int result;
247 unsigned long bus_addr; 563 unsigned long bus_addr;
248 564
249 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 565 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
250 &bus_addr); 566 &bus_addr,
567 IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M);
251 568
252 if (result) { 569 if (result) {
253 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 570 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -257,10 +574,44 @@ static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
257 return bus_addr; 574 return bus_addr;
258} 575}
259 576
577static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
578 size_t size,
579 enum dma_data_direction direction)
580{
581 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
582 int result;
583 unsigned long bus_addr;
584 u64 iopte_flag;
585
586 iopte_flag = IOPTE_M;
587 switch (direction) {
588 case DMA_BIDIRECTIONAL:
589 iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW;
590 break;
591 case DMA_TO_DEVICE:
592 iopte_flag |= IOPTE_PP_R | IOPTE_SO_R;
593 break;
594 case DMA_FROM_DEVICE:
595 iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW;
596 break;
597 default:
598 /* not happned */
599 BUG();
600 };
601 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
602 &bus_addr, iopte_flag);
603
604 if (result) {
605 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
606 __func__, __LINE__, result);
607 }
608 return bus_addr;
609}
610
260static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, 611static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
261 size_t size, enum dma_data_direction direction) 612 size_t size, enum dma_data_direction direction)
262{ 613{
263 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 614 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
264 int result; 615 int result;
265 616
266 result = ps3_dma_unmap(dev->d_region, dma_addr, size); 617 result = ps3_dma_unmap(dev->d_region, dma_addr, size);
@@ -271,20 +622,20 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
271 } 622 }
272} 623}
273 624
274static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, 625static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
275 enum dma_data_direction direction) 626 enum dma_data_direction direction)
276{ 627{
277#if defined(CONFIG_PS3_DYNAMIC_DMA) 628#if defined(CONFIG_PS3_DYNAMIC_DMA)
278 BUG_ON("do"); 629 BUG_ON("do");
279 return -EPERM; 630 return -EPERM;
280#else 631#else
281 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 632 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
282 int i; 633 int i;
283 634
284 for (i = 0; i < nents; i++, sg++) { 635 for (i = 0; i < nents; i++, sg++) {
285 int result = ps3_dma_map(dev->d_region, 636 int result = ps3_dma_map(dev->d_region,
286 page_to_phys(sg->page) + sg->offset, sg->length, 637 page_to_phys(sg->page) + sg->offset, sg->length,
287 &sg->dma_address); 638 &sg->dma_address, 0);
288 639
289 if (result) { 640 if (result) {
290 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 641 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -299,7 +650,15 @@ static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
299#endif 650#endif
300} 651}
301 652
302static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, 653static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
654 int nents,
655 enum dma_data_direction direction)
656{
657 BUG();
658 return 0;
659}
660
661static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
303 int nents, enum dma_data_direction direction) 662 int nents, enum dma_data_direction direction)
304{ 663{
305#if defined(CONFIG_PS3_DYNAMIC_DMA) 664#if defined(CONFIG_PS3_DYNAMIC_DMA)
@@ -307,18 +666,34 @@ static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
307#endif 666#endif
308} 667}
309 668
669static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
670 int nents, enum dma_data_direction direction)
671{
672 BUG();
673}
674
310static int ps3_dma_supported(struct device *_dev, u64 mask) 675static int ps3_dma_supported(struct device *_dev, u64 mask)
311{ 676{
312 return mask >= DMA_32BIT_MASK; 677 return mask >= DMA_32BIT_MASK;
313} 678}
314 679
315static struct dma_mapping_ops ps3_dma_ops = { 680static struct dma_mapping_ops ps3_sb_dma_ops = {
316 .alloc_coherent = ps3_alloc_coherent, 681 .alloc_coherent = ps3_alloc_coherent,
317 .free_coherent = ps3_free_coherent, 682 .free_coherent = ps3_free_coherent,
318 .map_single = ps3_map_single, 683 .map_single = ps3_sb_map_single,
319 .unmap_single = ps3_unmap_single, 684 .unmap_single = ps3_unmap_single,
320 .map_sg = ps3_map_sg, 685 .map_sg = ps3_sb_map_sg,
321 .unmap_sg = ps3_unmap_sg, 686 .unmap_sg = ps3_sb_unmap_sg,
687 .dma_supported = ps3_dma_supported
688};
689
690static struct dma_mapping_ops ps3_ioc0_dma_ops = {
691 .alloc_coherent = ps3_alloc_coherent,
692 .free_coherent = ps3_free_coherent,
693 .map_single = ps3_ioc0_map_single,
694 .unmap_single = ps3_unmap_single,
695 .map_sg = ps3_ioc0_map_sg,
696 .unmap_sg = ps3_ioc0_unmap_sg,
322 .dma_supported = ps3_dma_supported 697 .dma_supported = ps3_dma_supported
323}; 698};
324 699
@@ -328,7 +703,7 @@ static struct dma_mapping_ops ps3_dma_ops = {
328 703
329static void ps3_system_bus_release_device(struct device *_dev) 704static void ps3_system_bus_release_device(struct device *_dev)
330{ 705{
331 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 706 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
332 kfree(dev); 707 kfree(dev);
333} 708}
334 709
@@ -343,19 +718,38 @@ static void ps3_system_bus_release_device(struct device *_dev)
343int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) 718int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
344{ 719{
345 int result; 720 int result;
346 static unsigned int dev_count = 1; 721 static unsigned int dev_ioc0_count;
722 static unsigned int dev_sb_count;
723 static unsigned int dev_vuart_count;
347 724
348 dev->core.parent = NULL; 725 if (!dev->core.parent)
726 dev->core.parent = &ps3_system_bus;
349 dev->core.bus = &ps3_system_bus_type; 727 dev->core.bus = &ps3_system_bus_type;
350 dev->core.release = ps3_system_bus_release_device; 728 dev->core.release = ps3_system_bus_release_device;
351 729
730 switch (dev->dev_type) {
731 case PS3_DEVICE_TYPE_IOC0:
732 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
733 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
734 "ioc0_%02x", ++dev_ioc0_count);
735 break;
736 case PS3_DEVICE_TYPE_SB:
737 dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
738 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
739 "sb_%02x", ++dev_sb_count);
740
741 break;
742 case PS3_DEVICE_TYPE_VUART:
743 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
744 "vuart_%02x", ++dev_vuart_count);
745 break;
746 default:
747 BUG();
748 };
749
352 dev->core.archdata.of_node = NULL; 750 dev->core.archdata.of_node = NULL;
353 dev->core.archdata.dma_ops = &ps3_dma_ops;
354 dev->core.archdata.numa_node = 0; 751 dev->core.archdata.numa_node = 0;
355 752
356 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
357 dev_count++);
358
359 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 753 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
360 754
361 result = device_register(&dev->core); 755 result = device_register(&dev->core);
@@ -368,9 +762,15 @@ int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
368{ 762{
369 int result; 763 int result;
370 764
765 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
766
767 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
768 return -ENODEV;
769
371 drv->core.bus = &ps3_system_bus_type; 770 drv->core.bus = &ps3_system_bus_type;
372 771
373 result = driver_register(&drv->core); 772 result = driver_register(&drv->core);
773 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
374 return result; 774 return result;
375} 775}
376 776
@@ -378,7 +778,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
378 778
379void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) 779void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
380{ 780{
781 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
381 driver_unregister(&drv->core); 782 driver_unregister(&drv->core);
783 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
382} 784}
383 785
384EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); 786EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index 1bae8b19b363..802a9ccacb5e 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -39,7 +39,7 @@ static void _dump_tm(const struct rtc_time *tm, const char* func, int line)
39} 39}
40 40
41#define dump_time(_a) _dump_time(_a, __func__, __LINE__) 41#define dump_time(_a) _dump_time(_a, __func__, __LINE__)
42static void __attribute__ ((unused)) _dump_time(int time, const char* func, 42static void __maybe_unused _dump_time(int time, const char *func,
43 int line) 43 int line)
44{ 44{
45 struct rtc_time tm; 45 struct rtc_time tm;