1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  PS3 system bus driver.
4  *
5  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
6  *  Copyright 2006 Sony Corp.
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/export.h>
12 #include <linux/dma-map-ops.h>
13 #include <linux/err.h>
14 #include <linux/slab.h>
15 
16 #include <asm/udbg.h>
17 #include <asm/lv1call.h>
18 #include <asm/firmware.h>
19 #include <asm/cell-regs.h>
20 
21 #include "platform.h"
22 
23 static struct device ps3_system_bus = {
24 	.init_name = "ps3_system",
25 };
26 
27 /* FIXME: need device usage counters! */
28 static struct {
29 	struct mutex mutex;
30 	int sb_11; /* usb 0 */
31 	int sb_12; /* usb 0 */
32 	int gpu;
33 } usage_hack;
34 
35 static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
36 			 u64 dev_id)
37 {
38 	return dev->bus_id == bus_id && dev->dev_id == dev_id;
39 }
40 
41 static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
42 {
43 	int result;
44 
45 	BUG_ON(!dev->bus_id);
46 	mutex_lock(&usage_hack.mutex);
47 
48 	if (ps3_is_device(dev, 1, 1)) {
49 		usage_hack.sb_11++;
50 		if (usage_hack.sb_11 > 1) {
51 			result = 0;
52 			goto done;
53 		}
54 	}
55 
56 	if (ps3_is_device(dev, 1, 2)) {
57 		usage_hack.sb_12++;
58 		if (usage_hack.sb_12 > 1) {
59 			result = 0;
60 			goto done;
61 		}
62 	}
63 
64 	result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
65 
66 	if (result) {
67 		pr_warn("%s:%d: lv1_open_device dev=%u.%u(%s) failed: %s\n",
68 			__func__, __LINE__, dev->match_id, dev->match_sub_id,
69 			dev_name(&dev->core), ps3_result(result));
70 		result = -EPERM;
71 	}
72 
73 done:
74 	mutex_unlock(&usage_hack.mutex);
75 	return result;
76 }
77 
78 static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
79 {
80 	int result;
81 
82 	BUG_ON(!dev->bus_id);
83 	mutex_lock(&usage_hack.mutex);
84 
85 	if (ps3_is_device(dev, 1, 1)) {
86 		usage_hack.sb_11--;
87 		if (usage_hack.sb_11) {
88 			result = 0;
89 			goto done;
90 		}
91 	}
92 
93 	if (ps3_is_device(dev, 1, 2)) {
94 		usage_hack.sb_12--;
95 		if (usage_hack.sb_12) {
96 			result = 0;
97 			goto done;
98 		}
99 	}
100 
101 	result = lv1_close_device(dev->bus_id, dev->dev_id);
102 	BUG_ON(result);
103 
104 done:
105 	mutex_unlock(&usage_hack.mutex);
106 	return result;
107 }
108 
109 static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
110 {
111 	int result;
112 
113 	mutex_lock(&usage_hack.mutex);
114 
115 	usage_hack.gpu++;
116 	if (usage_hack.gpu > 1) {
117 		result = 0;
118 		goto done;
119 	}
120 
121 	result = lv1_gpu_open(0);
122 
123 	if (result) {
124 		pr_warn("%s:%d: lv1_gpu_open failed: %s\n", __func__,
125 			__LINE__, ps3_result(result));
126 			result = -EPERM;
127 	}
128 
129 done:
130 	mutex_unlock(&usage_hack.mutex);
131 	return result;
132 }
133 
134 static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
135 {
136 	int result;
137 
138 	mutex_lock(&usage_hack.mutex);
139 
140 	usage_hack.gpu--;
141 	if (usage_hack.gpu) {
142 		result = 0;
143 		goto done;
144 	}
145 
146 	result = lv1_gpu_close();
147 	BUG_ON(result);
148 
149 done:
150 	mutex_unlock(&usage_hack.mutex);
151 	return result;
152 }
153 
154 int ps3_open_hv_device(struct ps3_system_bus_device *dev)
155 {
156 	BUG_ON(!dev);
157 	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
158 
159 	switch (dev->match_id) {
160 	case PS3_MATCH_ID_EHCI:
161 	case PS3_MATCH_ID_OHCI:
162 	case PS3_MATCH_ID_GELIC:
163 	case PS3_MATCH_ID_STOR_DISK:
164 	case PS3_MATCH_ID_STOR_ROM:
165 	case PS3_MATCH_ID_STOR_FLASH:
166 		return ps3_open_hv_device_sb(dev);
167 
168 	case PS3_MATCH_ID_SOUND:
169 	case PS3_MATCH_ID_GPU:
170 		return ps3_open_hv_device_gpu(dev);
171 
172 	case PS3_MATCH_ID_AV_SETTINGS:
173 	case PS3_MATCH_ID_SYSTEM_MANAGER:
174 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
175 			__LINE__, dev->match_id);
176 		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
177 			dev->bus_id);
178 		BUG();
179 		return -EINVAL;
180 
181 	default:
182 		break;
183 	}
184 
185 	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
186 		dev->match_id);
187 	BUG();
188 	return -ENODEV;
189 }
190 EXPORT_SYMBOL_GPL(ps3_open_hv_device);
191 
192 int ps3_close_hv_device(struct ps3_system_bus_device *dev)
193 {
194 	BUG_ON(!dev);
195 	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
196 
197 	switch (dev->match_id) {
198 	case PS3_MATCH_ID_EHCI:
199 	case PS3_MATCH_ID_OHCI:
200 	case PS3_MATCH_ID_GELIC:
201 	case PS3_MATCH_ID_STOR_DISK:
202 	case PS3_MATCH_ID_STOR_ROM:
203 	case PS3_MATCH_ID_STOR_FLASH:
204 		return ps3_close_hv_device_sb(dev);
205 
206 	case PS3_MATCH_ID_SOUND:
207 	case PS3_MATCH_ID_GPU:
208 		return ps3_close_hv_device_gpu(dev);
209 
210 	case PS3_MATCH_ID_AV_SETTINGS:
211 	case PS3_MATCH_ID_SYSTEM_MANAGER:
212 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
213 			__LINE__, dev->match_id);
214 		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
215 			dev->bus_id);
216 		BUG();
217 		return -EINVAL;
218 
219 	default:
220 		break;
221 	}
222 
223 	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
224 		dev->match_id);
225 	BUG();
226 	return -ENODEV;
227 }
228 EXPORT_SYMBOL_GPL(ps3_close_hv_device);
229 
230 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
231 static void _dump_mmio_region(const struct ps3_mmio_region* r,
232 	const char* func, int line)
233 {
234 	pr_debug("%s:%d: dev       %llu:%llu\n", func, line, r->dev->bus_id,
235 		r->dev->dev_id);
236 	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
237 	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
238 	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
239 }
240 
241 static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
242 {
243 	int result;
244 	u64 lpar_addr;
245 
246 	result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
247 		r->bus_addr, r->len, r->page_size, &lpar_addr);
248 	r->lpar_addr = lpar_addr;
249 
250 	if (result) {
251 		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
252 			__func__, __LINE__, ps3_result(result));
253 		r->lpar_addr = 0;
254 	}
255 
256 	dump_mmio_region(r);
257 	return result;
258 }
259 
260 static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
261 {
262 	/* device specific; do nothing currently */
263 	return 0;
264 }
265 
266 int ps3_mmio_region_create(struct ps3_mmio_region *r)
267 {
268 	return r->mmio_ops->create(r);
269 }
270 EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
271 
272 static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
273 {
274 	int result;
275 
276 	dump_mmio_region(r);
277 	result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
278 		r->lpar_addr);
279 
280 	if (result)
281 		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
282 			__func__, __LINE__, ps3_result(result));
283 
284 	r->lpar_addr = 0;
285 	return result;
286 }
287 
288 static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
289 {
290 	/* device specific; do nothing currently */
291 	return 0;
292 }
293 
294 
295 int ps3_free_mmio_region(struct ps3_mmio_region *r)
296 {
297 	return r->mmio_ops->free(r);
298 }
299 
300 EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
301 
302 static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
303 	.create = ps3_sb_mmio_region_create,
304 	.free = ps3_sb_free_mmio_region
305 };
306 
307 static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
308 	.create = ps3_ioc0_mmio_region_create,
309 	.free = ps3_ioc0_free_mmio_region
310 };
311 
312 int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
313 	struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
314 	enum ps3_mmio_page_size page_size)
315 {
316 	r->dev = dev;
317 	r->bus_addr = bus_addr;
318 	r->len = len;
319 	r->page_size = page_size;
320 	switch (dev->dev_type) {
321 	case PS3_DEVICE_TYPE_SB:
322 		r->mmio_ops = &ps3_mmio_sb_region_ops;
323 		break;
324 	case PS3_DEVICE_TYPE_IOC0:
325 		r->mmio_ops = &ps3_mmio_ioc0_region_ops;
326 		break;
327 	default:
328 		BUG();
329 		return -EINVAL;
330 	}
331 	return 0;
332 }
333 EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
334 
335 static int ps3_system_bus_match(struct device *_dev,
336 	struct device_driver *_drv)
337 {
338 	int result;
339 	struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
340 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
341 
342 	if (!dev->match_sub_id)
343 		result = dev->match_id == drv->match_id;
344 	else
345 		result = dev->match_sub_id == drv->match_sub_id &&
346 			dev->match_id == drv->match_id;
347 
348 	if (result)
349 		pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
350 			__func__, __LINE__,
351 			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
352 			drv->match_id, drv->match_sub_id, drv->core.name);
353 	else
354 		pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
355 			__func__, __LINE__,
356 			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
357 			drv->match_id, drv->match_sub_id, drv->core.name);
358 
359 	return result;
360 }
361 
362 static int ps3_system_bus_probe(struct device *_dev)
363 {
364 	int result = 0;
365 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
366 	struct ps3_system_bus_driver *drv;
367 
368 	BUG_ON(!dev);
369 	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
370 
371 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
372 	BUG_ON(!drv);
373 
374 	if (drv->probe)
375 		result = drv->probe(dev);
376 	else
377 		pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
378 			dev_name(&dev->core));
379 
380 	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
381 	return result;
382 }
383 
384 static int ps3_system_bus_remove(struct device *_dev)
385 {
386 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
387 	struct ps3_system_bus_driver *drv;
388 
389 	BUG_ON(!dev);
390 	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
391 
392 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
393 	BUG_ON(!drv);
394 
395 	if (drv->remove)
396 		drv->remove(dev);
397 	else
398 		dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
399 			__func__, __LINE__, drv->core.name);
400 
401 	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
402 	return 0;
403 }
404 
405 static void ps3_system_bus_shutdown(struct device *_dev)
406 {
407 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
408 	struct ps3_system_bus_driver *drv;
409 
410 	BUG_ON(!dev);
411 
412 	dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
413 		dev->match_id);
414 
415 	if (!dev->core.driver) {
416 		dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
417 			__LINE__);
418 		return;
419 	}
420 
421 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
422 
423 	BUG_ON(!drv);
424 
425 	dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
426 		dev_name(&dev->core), drv->core.name);
427 
428 	if (drv->shutdown)
429 		drv->shutdown(dev);
430 	else if (drv->remove) {
431 		dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
432 			__func__, __LINE__, drv->core.name);
433 		drv->remove(dev);
434 	} else {
435 		dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
436 			__func__, __LINE__, drv->core.name);
437 		BUG();
438 	}
439 
440 	dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
441 }
442 
443 static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
444 {
445 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
446 
447 	if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
448 			   dev->match_sub_id))
449 		return -ENOMEM;
450 	return 0;
451 }
452 
453 static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
454 	char *buf)
455 {
456 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
457 	int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
458 			   dev->match_sub_id);
459 
460 	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
461 }
462 static DEVICE_ATTR_RO(modalias);
463 
464 static struct attribute *ps3_system_bus_dev_attrs[] = {
465 	&dev_attr_modalias.attr,
466 	NULL,
467 };
468 ATTRIBUTE_GROUPS(ps3_system_bus_dev);
469 
470 struct bus_type ps3_system_bus_type = {
471 	.name = "ps3_system_bus",
472 	.match = ps3_system_bus_match,
473 	.uevent = ps3_system_bus_uevent,
474 	.probe = ps3_system_bus_probe,
475 	.remove = ps3_system_bus_remove,
476 	.shutdown = ps3_system_bus_shutdown,
477 	.dev_groups = ps3_system_bus_dev_groups,
478 };
479 
480 static int __init ps3_system_bus_init(void)
481 {
482 	int result;
483 
484 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
485 		return -ENODEV;
486 
487 	pr_debug(" -> %s:%d\n", __func__, __LINE__);
488 
489 	mutex_init(&usage_hack.mutex);
490 
491 	result = device_register(&ps3_system_bus);
492 	BUG_ON(result);
493 
494 	result = bus_register(&ps3_system_bus_type);
495 	BUG_ON(result);
496 
497 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
498 	return result;
499 }
500 
501 core_initcall(ps3_system_bus_init);
502 
503 /* Allocates a contiguous real buffer and creates mappings over it.
504  * Returns the virtual address of the buffer and sets dma_handle
505  * to the dma address (mapping) of the first page.
506  */
507 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
508 				 dma_addr_t *dma_handle, gfp_t flag,
509 				 unsigned long attrs)
510 {
511 	int result;
512 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
513 	unsigned long virt_addr;
514 
515 	flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
516 	flag |= __GFP_ZERO;
517 
518 	virt_addr = __get_free_pages(flag, get_order(size));
519 
520 	if (!virt_addr) {
521 		pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
522 		goto clean_none;
523 	}
524 
525 	result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
526 			     CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
527 			     CBE_IOPTE_SO_RW | CBE_IOPTE_M);
528 
529 	if (result) {
530 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
531 			__func__, __LINE__, result);
532 		BUG_ON("check region type");
533 		goto clean_alloc;
534 	}
535 
536 	return (void*)virt_addr;
537 
538 clean_alloc:
539 	free_pages(virt_addr, get_order(size));
540 clean_none:
541 	dma_handle = NULL;
542 	return NULL;
543 }
544 
545 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
546 			      dma_addr_t dma_handle, unsigned long attrs)
547 {
548 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
549 
550 	ps3_dma_unmap(dev->d_region, dma_handle, size);
551 	free_pages((unsigned long)vaddr, get_order(size));
552 }
553 
554 /* Creates TCEs for a user provided buffer.  The user buffer must be
555  * contiguous real kernel storage (not vmalloc).  The address passed here
556  * comprises a page address and offset into that page. The dma_addr_t
557  * returned will point to the same byte within the page as was passed in.
558  */
559 
560 static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
561 	unsigned long offset, size_t size, enum dma_data_direction direction,
562 	unsigned long attrs)
563 {
564 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
565 	int result;
566 	dma_addr_t bus_addr;
567 	void *ptr = page_address(page) + offset;
568 
569 	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
570 			     &bus_addr,
571 			     CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
572 			     CBE_IOPTE_SO_RW | CBE_IOPTE_M);
573 
574 	if (result) {
575 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
576 			__func__, __LINE__, result);
577 	}
578 
579 	return bus_addr;
580 }
581 
582 static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
583 				    unsigned long offset, size_t size,
584 				    enum dma_data_direction direction,
585 				    unsigned long attrs)
586 {
587 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
588 	int result;
589 	dma_addr_t bus_addr;
590 	u64 iopte_flag;
591 	void *ptr = page_address(page) + offset;
592 
593 	iopte_flag = CBE_IOPTE_M;
594 	switch (direction) {
595 	case DMA_BIDIRECTIONAL:
596 		iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
597 		break;
598 	case DMA_TO_DEVICE:
599 		iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
600 		break;
601 	case DMA_FROM_DEVICE:
602 		iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
603 		break;
604 	default:
605 		/* not happned */
606 		BUG();
607 	};
608 	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
609 			     &bus_addr, iopte_flag);
610 
611 	if (result) {
612 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
613 			__func__, __LINE__, result);
614 	}
615 	return bus_addr;
616 }
617 
618 static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
619 	size_t size, enum dma_data_direction direction, unsigned long attrs)
620 {
621 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
622 	int result;
623 
624 	result = ps3_dma_unmap(dev->d_region, dma_addr, size);
625 
626 	if (result) {
627 		pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
628 			__func__, __LINE__, result);
629 	}
630 }
631 
632 static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
633 	int nents, enum dma_data_direction direction, unsigned long attrs)
634 {
635 #if defined(CONFIG_PS3_DYNAMIC_DMA)
636 	BUG_ON("do");
637 	return -EPERM;
638 #else
639 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
640 	struct scatterlist *sg;
641 	int i;
642 
643 	for_each_sg(sgl, sg, nents, i) {
644 		int result = ps3_dma_map(dev->d_region, sg_phys(sg),
645 					sg->length, &sg->dma_address, 0);
646 
647 		if (result) {
648 			pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
649 				__func__, __LINE__, result);
650 			return -EINVAL;
651 		}
652 
653 		sg->dma_length = sg->length;
654 	}
655 
656 	return nents;
657 #endif
658 }
659 
660 static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
661 			   int nents,
662 			   enum dma_data_direction direction,
663 			   unsigned long attrs)
664 {
665 	BUG();
666 	return 0;
667 }
668 
669 static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
670 	int nents, enum dma_data_direction direction, unsigned long attrs)
671 {
672 #if defined(CONFIG_PS3_DYNAMIC_DMA)
673 	BUG_ON("do");
674 #endif
675 }
676 
677 static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
678 			    int nents, enum dma_data_direction direction,
679 			    unsigned long attrs)
680 {
681 	BUG();
682 }
683 
684 static int ps3_dma_supported(struct device *_dev, u64 mask)
685 {
686 	return mask >= DMA_BIT_MASK(32);
687 }
688 
689 static const struct dma_map_ops ps3_sb_dma_ops = {
690 	.alloc = ps3_alloc_coherent,
691 	.free = ps3_free_coherent,
692 	.map_sg = ps3_sb_map_sg,
693 	.unmap_sg = ps3_sb_unmap_sg,
694 	.dma_supported = ps3_dma_supported,
695 	.map_page = ps3_sb_map_page,
696 	.unmap_page = ps3_unmap_page,
697 	.mmap = dma_common_mmap,
698 	.get_sgtable = dma_common_get_sgtable,
699 	.alloc_pages = dma_common_alloc_pages,
700 	.free_pages = dma_common_free_pages,
701 };
702 
703 static const struct dma_map_ops ps3_ioc0_dma_ops = {
704 	.alloc = ps3_alloc_coherent,
705 	.free = ps3_free_coherent,
706 	.map_sg = ps3_ioc0_map_sg,
707 	.unmap_sg = ps3_ioc0_unmap_sg,
708 	.dma_supported = ps3_dma_supported,
709 	.map_page = ps3_ioc0_map_page,
710 	.unmap_page = ps3_unmap_page,
711 	.mmap = dma_common_mmap,
712 	.get_sgtable = dma_common_get_sgtable,
713 	.alloc_pages = dma_common_alloc_pages,
714 	.free_pages = dma_common_free_pages,
715 };
716 
717 /**
718  * ps3_system_bus_release_device - remove a device from the system bus
719  */
720 
721 static void ps3_system_bus_release_device(struct device *_dev)
722 {
723 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
724 	kfree(dev);
725 }
726 
727 /**
728  * ps3_system_bus_device_register - add a device to the system bus
729  *
730  * ps3_system_bus_device_register() expects the dev object to be allocated
731  * dynamically by the caller.  The system bus takes ownership of the dev
732  * object and frees the object in ps3_system_bus_release_device().
733  */
734 
735 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
736 {
737 	int result;
738 	static unsigned int dev_ioc0_count;
739 	static unsigned int dev_sb_count;
740 	static unsigned int dev_vuart_count;
741 	static unsigned int dev_lpm_count;
742 
743 	if (!dev->core.parent)
744 		dev->core.parent = &ps3_system_bus;
745 	dev->core.bus = &ps3_system_bus_type;
746 	dev->core.release = ps3_system_bus_release_device;
747 
748 	switch (dev->dev_type) {
749 	case PS3_DEVICE_TYPE_IOC0:
750 		dev->core.dma_ops = &ps3_ioc0_dma_ops;
751 		dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
752 		break;
753 	case PS3_DEVICE_TYPE_SB:
754 		dev->core.dma_ops = &ps3_sb_dma_ops;
755 		dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);
756 
757 		break;
758 	case PS3_DEVICE_TYPE_VUART:
759 		dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
760 		break;
761 	case PS3_DEVICE_TYPE_LPM:
762 		dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
763 		break;
764 	default:
765 		BUG();
766 	};
767 
768 	dev->core.of_node = NULL;
769 	set_dev_node(&dev->core, 0);
770 
771 	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));
772 
773 	result = device_register(&dev->core);
774 	return result;
775 }
776 
777 EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
778 
779 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
780 {
781 	int result;
782 
783 	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
784 
785 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
786 		return -ENODEV;
787 
788 	drv->core.bus = &ps3_system_bus_type;
789 
790 	result = driver_register(&drv->core);
791 	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
792 	return result;
793 }
794 
795 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
796 
797 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
798 {
799 	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
800 	driver_unregister(&drv->core);
801 	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
802 }
803 
804 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
805