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_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
68 			__LINE__, ps3_result(result));
69 			result = -EPERM;
70 	}
71 
72 done:
73 	mutex_unlock(&usage_hack.mutex);
74 	return result;
75 }
76 
77 static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
78 {
79 	int result;
80 
81 	BUG_ON(!dev->bus_id);
82 	mutex_lock(&usage_hack.mutex);
83 
84 	if (ps3_is_device(dev, 1, 1)) {
85 		usage_hack.sb_11--;
86 		if (usage_hack.sb_11) {
87 			result = 0;
88 			goto done;
89 		}
90 	}
91 
92 	if (ps3_is_device(dev, 1, 2)) {
93 		usage_hack.sb_12--;
94 		if (usage_hack.sb_12) {
95 			result = 0;
96 			goto done;
97 		}
98 	}
99 
100 	result = lv1_close_device(dev->bus_id, dev->dev_id);
101 	BUG_ON(result);
102 
103 done:
104 	mutex_unlock(&usage_hack.mutex);
105 	return result;
106 }
107 
108 static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
109 {
110 	int result;
111 
112 	mutex_lock(&usage_hack.mutex);
113 
114 	usage_hack.gpu++;
115 	if (usage_hack.gpu > 1) {
116 		result = 0;
117 		goto done;
118 	}
119 
120 	result = lv1_gpu_open(0);
121 
122 	if (result) {
123 		pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
124 			__LINE__, ps3_result(result));
125 			result = -EPERM;
126 	}
127 
128 done:
129 	mutex_unlock(&usage_hack.mutex);
130 	return result;
131 }
132 
133 static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
134 {
135 	int result;
136 
137 	mutex_lock(&usage_hack.mutex);
138 
139 	usage_hack.gpu--;
140 	if (usage_hack.gpu) {
141 		result = 0;
142 		goto done;
143 	}
144 
145 	result = lv1_gpu_close();
146 	BUG_ON(result);
147 
148 done:
149 	mutex_unlock(&usage_hack.mutex);
150 	return result;
151 }
152 
153 int ps3_open_hv_device(struct ps3_system_bus_device *dev)
154 {
155 	BUG_ON(!dev);
156 	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
157 
158 	switch (dev->match_id) {
159 	case PS3_MATCH_ID_EHCI:
160 	case PS3_MATCH_ID_OHCI:
161 	case PS3_MATCH_ID_GELIC:
162 	case PS3_MATCH_ID_STOR_DISK:
163 	case PS3_MATCH_ID_STOR_ROM:
164 	case PS3_MATCH_ID_STOR_FLASH:
165 		return ps3_open_hv_device_sb(dev);
166 
167 	case PS3_MATCH_ID_SOUND:
168 	case PS3_MATCH_ID_GPU:
169 		return ps3_open_hv_device_gpu(dev);
170 
171 	case PS3_MATCH_ID_AV_SETTINGS:
172 	case PS3_MATCH_ID_SYSTEM_MANAGER:
173 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
174 			__LINE__, dev->match_id);
175 		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
176 			dev->bus_id);
177 		BUG();
178 		return -EINVAL;
179 
180 	default:
181 		break;
182 	}
183 
184 	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
185 		dev->match_id);
186 	BUG();
187 	return -ENODEV;
188 }
189 EXPORT_SYMBOL_GPL(ps3_open_hv_device);
190 
191 int ps3_close_hv_device(struct ps3_system_bus_device *dev)
192 {
193 	BUG_ON(!dev);
194 	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
195 
196 	switch (dev->match_id) {
197 	case PS3_MATCH_ID_EHCI:
198 	case PS3_MATCH_ID_OHCI:
199 	case PS3_MATCH_ID_GELIC:
200 	case PS3_MATCH_ID_STOR_DISK:
201 	case PS3_MATCH_ID_STOR_ROM:
202 	case PS3_MATCH_ID_STOR_FLASH:
203 		return ps3_close_hv_device_sb(dev);
204 
205 	case PS3_MATCH_ID_SOUND:
206 	case PS3_MATCH_ID_GPU:
207 		return ps3_close_hv_device_gpu(dev);
208 
209 	case PS3_MATCH_ID_AV_SETTINGS:
210 	case PS3_MATCH_ID_SYSTEM_MANAGER:
211 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
212 			__LINE__, dev->match_id);
213 		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
214 			dev->bus_id);
215 		BUG();
216 		return -EINVAL;
217 
218 	default:
219 		break;
220 	}
221 
222 	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
223 		dev->match_id);
224 	BUG();
225 	return -ENODEV;
226 }
227 EXPORT_SYMBOL_GPL(ps3_close_hv_device);
228 
229 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
230 static void _dump_mmio_region(const struct ps3_mmio_region* r,
231 	const char* func, int line)
232 {
233 	pr_debug("%s:%d: dev       %llu:%llu\n", func, line, r->dev->bus_id,
234 		r->dev->dev_id);
235 	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
236 	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
237 	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
238 }
239 
240 static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
241 {
242 	int result;
243 	u64 lpar_addr;
244 
245 	result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
246 		r->bus_addr, r->len, r->page_size, &lpar_addr);
247 	r->lpar_addr = lpar_addr;
248 
249 	if (result) {
250 		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
251 			__func__, __LINE__, ps3_result(result));
252 		r->lpar_addr = 0;
253 	}
254 
255 	dump_mmio_region(r);
256 	return result;
257 }
258 
259 static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
260 {
261 	/* device specific; do nothing currently */
262 	return 0;
263 }
264 
265 int ps3_mmio_region_create(struct ps3_mmio_region *r)
266 {
267 	return r->mmio_ops->create(r);
268 }
269 EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
270 
271 static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
272 {
273 	int result;
274 
275 	dump_mmio_region(r);
276 	result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
277 		r->lpar_addr);
278 
279 	if (result)
280 		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
281 			__func__, __LINE__, ps3_result(result));
282 
283 	r->lpar_addr = 0;
284 	return result;
285 }
286 
287 static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
288 {
289 	/* device specific; do nothing currently */
290 	return 0;
291 }
292 
293 
294 int ps3_free_mmio_region(struct ps3_mmio_region *r)
295 {
296 	return r->mmio_ops->free(r);
297 }
298 
299 EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
300 
301 static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
302 	.create = ps3_sb_mmio_region_create,
303 	.free = ps3_sb_free_mmio_region
304 };
305 
306 static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
307 	.create = ps3_ioc0_mmio_region_create,
308 	.free = ps3_ioc0_free_mmio_region
309 };
310 
311 int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
312 	struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
313 	enum ps3_mmio_page_size page_size)
314 {
315 	r->dev = dev;
316 	r->bus_addr = bus_addr;
317 	r->len = len;
318 	r->page_size = page_size;
319 	switch (dev->dev_type) {
320 	case PS3_DEVICE_TYPE_SB:
321 		r->mmio_ops = &ps3_mmio_sb_region_ops;
322 		break;
323 	case PS3_DEVICE_TYPE_IOC0:
324 		r->mmio_ops = &ps3_mmio_ioc0_region_ops;
325 		break;
326 	default:
327 		BUG();
328 		return -EINVAL;
329 	}
330 	return 0;
331 }
332 EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
333 
334 static int ps3_system_bus_match(struct device *_dev,
335 	struct device_driver *_drv)
336 {
337 	int result;
338 	struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
339 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
340 
341 	if (!dev->match_sub_id)
342 		result = dev->match_id == drv->match_id;
343 	else
344 		result = dev->match_sub_id == drv->match_sub_id &&
345 			dev->match_id == drv->match_id;
346 
347 	if (result)
348 		pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
349 			__func__, __LINE__,
350 			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
351 			drv->match_id, drv->match_sub_id, drv->core.name);
352 	else
353 		pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
354 			__func__, __LINE__,
355 			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
356 			drv->match_id, drv->match_sub_id, drv->core.name);
357 
358 	return result;
359 }
360 
361 static int ps3_system_bus_probe(struct device *_dev)
362 {
363 	int result = 0;
364 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
365 	struct ps3_system_bus_driver *drv;
366 
367 	BUG_ON(!dev);
368 	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
369 
370 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
371 	BUG_ON(!drv);
372 
373 	if (drv->probe)
374 		result = drv->probe(dev);
375 	else
376 		pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
377 			dev_name(&dev->core));
378 
379 	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
380 	return result;
381 }
382 
383 static int ps3_system_bus_remove(struct device *_dev)
384 {
385 	int result = 0;
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 		result = 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 result;
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