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