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-mapping.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 u64 ps3_dma_get_required_mask(struct device *_dev) 690 { 691 return DMA_BIT_MASK(32); 692 } 693 694 static const struct dma_map_ops ps3_sb_dma_ops = { 695 .alloc = ps3_alloc_coherent, 696 .free = ps3_free_coherent, 697 .map_sg = ps3_sb_map_sg, 698 .unmap_sg = ps3_sb_unmap_sg, 699 .dma_supported = ps3_dma_supported, 700 .get_required_mask = ps3_dma_get_required_mask, 701 .map_page = ps3_sb_map_page, 702 .unmap_page = ps3_unmap_page, 703 }; 704 705 static const struct dma_map_ops ps3_ioc0_dma_ops = { 706 .alloc = ps3_alloc_coherent, 707 .free = ps3_free_coherent, 708 .map_sg = ps3_ioc0_map_sg, 709 .unmap_sg = ps3_ioc0_unmap_sg, 710 .dma_supported = ps3_dma_supported, 711 .get_required_mask = ps3_dma_get_required_mask, 712 .map_page = ps3_ioc0_map_page, 713 .unmap_page = ps3_unmap_page, 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