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 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 386 struct ps3_system_bus_driver *drv; 387 388 BUG_ON(!dev); 389 dev_dbg(_dev, "%s:%d\n", __func__, __LINE__); 390 391 drv = ps3_system_bus_dev_to_system_bus_drv(dev); 392 BUG_ON(!drv); 393 394 if (drv->remove) 395 drv->remove(dev); 396 else 397 dev_dbg(&dev->core, "%s:%d %s: no remove method\n", 398 __func__, __LINE__, drv->core.name); 399 400 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core)); 401 return 0; 402 } 403 404 static void ps3_system_bus_shutdown(struct device *_dev) 405 { 406 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 407 struct ps3_system_bus_driver *drv; 408 409 BUG_ON(!dev); 410 411 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, 412 dev->match_id); 413 414 if (!dev->core.driver) { 415 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, 416 __LINE__); 417 return; 418 } 419 420 drv = ps3_system_bus_dev_to_system_bus_drv(dev); 421 422 BUG_ON(!drv); 423 424 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__, 425 dev_name(&dev->core), drv->core.name); 426 427 if (drv->shutdown) 428 drv->shutdown(dev); 429 else if (drv->remove) { 430 dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n", 431 __func__, __LINE__, drv->core.name); 432 drv->remove(dev); 433 } else { 434 dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n", 435 __func__, __LINE__, drv->core.name); 436 BUG(); 437 } 438 439 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 440 } 441 442 static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env) 443 { 444 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 445 446 if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id, 447 dev->match_sub_id)) 448 return -ENOMEM; 449 return 0; 450 } 451 452 static ssize_t modalias_show(struct device *_dev, struct device_attribute *a, 453 char *buf) 454 { 455 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 456 int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id, 457 dev->match_sub_id); 458 459 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; 460 } 461 static DEVICE_ATTR_RO(modalias); 462 463 static struct attribute *ps3_system_bus_dev_attrs[] = { 464 &dev_attr_modalias.attr, 465 NULL, 466 }; 467 ATTRIBUTE_GROUPS(ps3_system_bus_dev); 468 469 struct bus_type ps3_system_bus_type = { 470 .name = "ps3_system_bus", 471 .match = ps3_system_bus_match, 472 .uevent = ps3_system_bus_uevent, 473 .probe = ps3_system_bus_probe, 474 .remove = ps3_system_bus_remove, 475 .shutdown = ps3_system_bus_shutdown, 476 .dev_groups = ps3_system_bus_dev_groups, 477 }; 478 479 static int __init ps3_system_bus_init(void) 480 { 481 int result; 482 483 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 484 return -ENODEV; 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 493 result = bus_register(&ps3_system_bus_type); 494 BUG_ON(result); 495 496 pr_debug(" <- %s:%d\n", __func__, __LINE__); 497 return result; 498 } 499 500 core_initcall(ps3_system_bus_init); 501 502 /* Allocates a contiguous real buffer and creates mappings over it. 503 * Returns the virtual address of the buffer and sets dma_handle 504 * to the dma address (mapping) of the first page. 505 */ 506 static void * ps3_alloc_coherent(struct device *_dev, size_t size, 507 dma_addr_t *dma_handle, gfp_t flag, 508 unsigned long attrs) 509 { 510 int result; 511 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 512 unsigned long virt_addr; 513 514 flag &= ~(__GFP_DMA | __GFP_HIGHMEM); 515 flag |= __GFP_ZERO; 516 517 virt_addr = __get_free_pages(flag, get_order(size)); 518 519 if (!virt_addr) { 520 pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__); 521 goto clean_none; 522 } 523 524 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle, 525 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | 526 CBE_IOPTE_SO_RW | CBE_IOPTE_M); 527 528 if (result) { 529 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 530 __func__, __LINE__, result); 531 BUG_ON("check region type"); 532 goto clean_alloc; 533 } 534 535 return (void*)virt_addr; 536 537 clean_alloc: 538 free_pages(virt_addr, get_order(size)); 539 clean_none: 540 dma_handle = NULL; 541 return NULL; 542 } 543 544 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, 545 dma_addr_t dma_handle, unsigned long attrs) 546 { 547 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 548 549 ps3_dma_unmap(dev->d_region, dma_handle, size); 550 free_pages((unsigned long)vaddr, get_order(size)); 551 } 552 553 /* Creates TCEs for a user provided buffer. The user buffer must be 554 * contiguous real kernel storage (not vmalloc). The address passed here 555 * comprises a page address and offset into that page. The dma_addr_t 556 * returned will point to the same byte within the page as was passed in. 557 */ 558 559 static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, 560 unsigned long offset, size_t size, enum dma_data_direction direction, 561 unsigned long attrs) 562 { 563 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 564 int result; 565 dma_addr_t bus_addr; 566 void *ptr = page_address(page) + offset; 567 568 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 569 &bus_addr, 570 CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | 571 CBE_IOPTE_SO_RW | CBE_IOPTE_M); 572 573 if (result) { 574 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 575 __func__, __LINE__, result); 576 } 577 578 return bus_addr; 579 } 580 581 static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, 582 unsigned long offset, size_t size, 583 enum dma_data_direction direction, 584 unsigned long attrs) 585 { 586 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 587 int result; 588 dma_addr_t bus_addr; 589 u64 iopte_flag; 590 void *ptr = page_address(page) + offset; 591 592 iopte_flag = CBE_IOPTE_M; 593 switch (direction) { 594 case DMA_BIDIRECTIONAL: 595 iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW; 596 break; 597 case DMA_TO_DEVICE: 598 iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R; 599 break; 600 case DMA_FROM_DEVICE: 601 iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW; 602 break; 603 default: 604 /* not happned */ 605 BUG(); 606 }; 607 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 608 &bus_addr, iopte_flag); 609 610 if (result) { 611 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 612 __func__, __LINE__, result); 613 } 614 return bus_addr; 615 } 616 617 static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr, 618 size_t size, enum dma_data_direction direction, unsigned long attrs) 619 { 620 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 621 int result; 622 623 result = ps3_dma_unmap(dev->d_region, dma_addr, size); 624 625 if (result) { 626 pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n", 627 __func__, __LINE__, result); 628 } 629 } 630 631 static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, 632 int nents, enum dma_data_direction direction, unsigned long attrs) 633 { 634 #if defined(CONFIG_PS3_DYNAMIC_DMA) 635 BUG_ON("do"); 636 return -EPERM; 637 #else 638 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 639 struct scatterlist *sg; 640 int i; 641 642 for_each_sg(sgl, sg, nents, i) { 643 int result = ps3_dma_map(dev->d_region, sg_phys(sg), 644 sg->length, &sg->dma_address, 0); 645 646 if (result) { 647 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 648 __func__, __LINE__, result); 649 return -EINVAL; 650 } 651 652 sg->dma_length = sg->length; 653 } 654 655 return nents; 656 #endif 657 } 658 659 static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, 660 int nents, 661 enum dma_data_direction direction, 662 unsigned long attrs) 663 { 664 BUG(); 665 return 0; 666 } 667 668 static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, 669 int nents, enum dma_data_direction direction, unsigned long attrs) 670 { 671 #if defined(CONFIG_PS3_DYNAMIC_DMA) 672 BUG_ON("do"); 673 #endif 674 } 675 676 static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg, 677 int nents, enum dma_data_direction direction, 678 unsigned long attrs) 679 { 680 BUG(); 681 } 682 683 static int ps3_dma_supported(struct device *_dev, u64 mask) 684 { 685 return mask >= DMA_BIT_MASK(32); 686 } 687 688 static const struct dma_map_ops ps3_sb_dma_ops = { 689 .alloc = ps3_alloc_coherent, 690 .free = ps3_free_coherent, 691 .map_sg = ps3_sb_map_sg, 692 .unmap_sg = ps3_sb_unmap_sg, 693 .dma_supported = ps3_dma_supported, 694 .map_page = ps3_sb_map_page, 695 .unmap_page = ps3_unmap_page, 696 .mmap = dma_common_mmap, 697 .get_sgtable = dma_common_get_sgtable, 698 .alloc_pages = dma_common_alloc_pages, 699 .free_pages = dma_common_free_pages, 700 }; 701 702 static const struct dma_map_ops ps3_ioc0_dma_ops = { 703 .alloc = ps3_alloc_coherent, 704 .free = ps3_free_coherent, 705 .map_sg = ps3_ioc0_map_sg, 706 .unmap_sg = ps3_ioc0_unmap_sg, 707 .dma_supported = ps3_dma_supported, 708 .map_page = ps3_ioc0_map_page, 709 .unmap_page = ps3_unmap_page, 710 .mmap = dma_common_mmap, 711 .get_sgtable = dma_common_get_sgtable, 712 .alloc_pages = dma_common_alloc_pages, 713 .free_pages = dma_common_free_pages, 714 }; 715 716 /** 717 * ps3_system_bus_release_device - remove a device from the system bus 718 */ 719 720 static void ps3_system_bus_release_device(struct device *_dev) 721 { 722 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 723 kfree(dev); 724 } 725 726 /** 727 * ps3_system_bus_device_register - add a device to the system bus 728 * 729 * ps3_system_bus_device_register() expects the dev object to be allocated 730 * dynamically by the caller. The system bus takes ownership of the dev 731 * object and frees the object in ps3_system_bus_release_device(). 732 */ 733 734 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) 735 { 736 int result; 737 static unsigned int dev_ioc0_count; 738 static unsigned int dev_sb_count; 739 static unsigned int dev_vuart_count; 740 static unsigned int dev_lpm_count; 741 742 if (!dev->core.parent) 743 dev->core.parent = &ps3_system_bus; 744 dev->core.bus = &ps3_system_bus_type; 745 dev->core.release = ps3_system_bus_release_device; 746 747 switch (dev->dev_type) { 748 case PS3_DEVICE_TYPE_IOC0: 749 dev->core.dma_ops = &ps3_ioc0_dma_ops; 750 dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count); 751 break; 752 case PS3_DEVICE_TYPE_SB: 753 dev->core.dma_ops = &ps3_sb_dma_ops; 754 dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count); 755 756 break; 757 case PS3_DEVICE_TYPE_VUART: 758 dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count); 759 break; 760 case PS3_DEVICE_TYPE_LPM: 761 dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count); 762 break; 763 default: 764 BUG(); 765 }; 766 767 dev->core.of_node = NULL; 768 set_dev_node(&dev->core, 0); 769 770 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core)); 771 772 result = device_register(&dev->core); 773 return result; 774 } 775 776 EXPORT_SYMBOL_GPL(ps3_system_bus_device_register); 777 778 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv) 779 { 780 int result; 781 782 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name); 783 784 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 785 return -ENODEV; 786 787 drv->core.bus = &ps3_system_bus_type; 788 789 result = driver_register(&drv->core); 790 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name); 791 return result; 792 } 793 794 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register); 795 796 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) 797 { 798 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name); 799 driver_unregister(&drv->core); 800 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name); 801 } 802 803 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); 804