Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  PS3 system bus driver.
0004  *
0005  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
0006  *  Copyright 2006 Sony Corp.
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/export.h>
0012 #include <linux/dma-map-ops.h>
0013 #include <linux/err.h>
0014 #include <linux/slab.h>
0015 
0016 #include <asm/udbg.h>
0017 #include <asm/lv1call.h>
0018 #include <asm/firmware.h>
0019 #include <asm/cell-regs.h>
0020 
0021 #include "platform.h"
0022 
0023 static struct device ps3_system_bus = {
0024     .init_name = "ps3_system",
0025 };
0026 
0027 /* FIXME: need device usage counters! */
0028 static struct {
0029     struct mutex mutex;
0030     int sb_11; /* usb 0 */
0031     int sb_12; /* usb 0 */
0032     int gpu;
0033 } usage_hack;
0034 
0035 static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
0036              u64 dev_id)
0037 {
0038     return dev->bus_id == bus_id && dev->dev_id == dev_id;
0039 }
0040 
0041 static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
0042 {
0043     int result;
0044 
0045     BUG_ON(!dev->bus_id);
0046     mutex_lock(&usage_hack.mutex);
0047 
0048     if (ps3_is_device(dev, 1, 1)) {
0049         usage_hack.sb_11++;
0050         if (usage_hack.sb_11 > 1) {
0051             result = 0;
0052             goto done;
0053         }
0054     }
0055 
0056     if (ps3_is_device(dev, 1, 2)) {
0057         usage_hack.sb_12++;
0058         if (usage_hack.sb_12 > 1) {
0059             result = 0;
0060             goto done;
0061         }
0062     }
0063 
0064     result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
0065 
0066     if (result) {
0067         pr_warn("%s:%d: lv1_open_device dev=%u.%u(%s) failed: %s\n",
0068             __func__, __LINE__, dev->match_id, dev->match_sub_id,
0069             dev_name(&dev->core), ps3_result(result));
0070         result = -EPERM;
0071     }
0072 
0073 done:
0074     mutex_unlock(&usage_hack.mutex);
0075     return result;
0076 }
0077 
0078 static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
0079 {
0080     int result;
0081 
0082     BUG_ON(!dev->bus_id);
0083     mutex_lock(&usage_hack.mutex);
0084 
0085     if (ps3_is_device(dev, 1, 1)) {
0086         usage_hack.sb_11--;
0087         if (usage_hack.sb_11) {
0088             result = 0;
0089             goto done;
0090         }
0091     }
0092 
0093     if (ps3_is_device(dev, 1, 2)) {
0094         usage_hack.sb_12--;
0095         if (usage_hack.sb_12) {
0096             result = 0;
0097             goto done;
0098         }
0099     }
0100 
0101     result = lv1_close_device(dev->bus_id, dev->dev_id);
0102     BUG_ON(result);
0103 
0104 done:
0105     mutex_unlock(&usage_hack.mutex);
0106     return result;
0107 }
0108 
0109 static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
0110 {
0111     int result;
0112 
0113     mutex_lock(&usage_hack.mutex);
0114 
0115     usage_hack.gpu++;
0116     if (usage_hack.gpu > 1) {
0117         result = 0;
0118         goto done;
0119     }
0120 
0121     result = lv1_gpu_open(0);
0122 
0123     if (result) {
0124         pr_warn("%s:%d: lv1_gpu_open failed: %s\n", __func__,
0125             __LINE__, ps3_result(result));
0126             result = -EPERM;
0127     }
0128 
0129 done:
0130     mutex_unlock(&usage_hack.mutex);
0131     return result;
0132 }
0133 
0134 static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
0135 {
0136     int result;
0137 
0138     mutex_lock(&usage_hack.mutex);
0139 
0140     usage_hack.gpu--;
0141     if (usage_hack.gpu) {
0142         result = 0;
0143         goto done;
0144     }
0145 
0146     result = lv1_gpu_close();
0147     BUG_ON(result);
0148 
0149 done:
0150     mutex_unlock(&usage_hack.mutex);
0151     return result;
0152 }
0153 
0154 int ps3_open_hv_device(struct ps3_system_bus_device *dev)
0155 {
0156     BUG_ON(!dev);
0157     pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
0158 
0159     switch (dev->match_id) {
0160     case PS3_MATCH_ID_EHCI:
0161     case PS3_MATCH_ID_OHCI:
0162     case PS3_MATCH_ID_GELIC:
0163     case PS3_MATCH_ID_STOR_DISK:
0164     case PS3_MATCH_ID_STOR_ROM:
0165     case PS3_MATCH_ID_STOR_FLASH:
0166         return ps3_open_hv_device_sb(dev);
0167 
0168     case PS3_MATCH_ID_SOUND:
0169     case PS3_MATCH_ID_GPU:
0170         return ps3_open_hv_device_gpu(dev);
0171 
0172     case PS3_MATCH_ID_AV_SETTINGS:
0173     case PS3_MATCH_ID_SYSTEM_MANAGER:
0174         pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
0175             __LINE__, dev->match_id);
0176         pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
0177             dev->bus_id);
0178         BUG();
0179         return -EINVAL;
0180 
0181     default:
0182         break;
0183     }
0184 
0185     pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
0186         dev->match_id);
0187     BUG();
0188     return -ENODEV;
0189 }
0190 EXPORT_SYMBOL_GPL(ps3_open_hv_device);
0191 
0192 int ps3_close_hv_device(struct ps3_system_bus_device *dev)
0193 {
0194     BUG_ON(!dev);
0195     pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
0196 
0197     switch (dev->match_id) {
0198     case PS3_MATCH_ID_EHCI:
0199     case PS3_MATCH_ID_OHCI:
0200     case PS3_MATCH_ID_GELIC:
0201     case PS3_MATCH_ID_STOR_DISK:
0202     case PS3_MATCH_ID_STOR_ROM:
0203     case PS3_MATCH_ID_STOR_FLASH:
0204         return ps3_close_hv_device_sb(dev);
0205 
0206     case PS3_MATCH_ID_SOUND:
0207     case PS3_MATCH_ID_GPU:
0208         return ps3_close_hv_device_gpu(dev);
0209 
0210     case PS3_MATCH_ID_AV_SETTINGS:
0211     case PS3_MATCH_ID_SYSTEM_MANAGER:
0212         pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
0213             __LINE__, dev->match_id);
0214         pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
0215             dev->bus_id);
0216         BUG();
0217         return -EINVAL;
0218 
0219     default:
0220         break;
0221     }
0222 
0223     pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
0224         dev->match_id);
0225     BUG();
0226     return -ENODEV;
0227 }
0228 EXPORT_SYMBOL_GPL(ps3_close_hv_device);
0229 
0230 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
0231 static void _dump_mmio_region(const struct ps3_mmio_region* r,
0232     const char* func, int line)
0233 {
0234     pr_debug("%s:%d: dev       %llu:%llu\n", func, line, r->dev->bus_id,
0235         r->dev->dev_id);
0236     pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
0237     pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
0238     pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
0239 }
0240 
0241 static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
0242 {
0243     int result;
0244     u64 lpar_addr;
0245 
0246     result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
0247         r->bus_addr, r->len, r->page_size, &lpar_addr);
0248     r->lpar_addr = lpar_addr;
0249 
0250     if (result) {
0251         pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
0252             __func__, __LINE__, ps3_result(result));
0253         r->lpar_addr = 0;
0254     }
0255 
0256     dump_mmio_region(r);
0257     return result;
0258 }
0259 
0260 static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
0261 {
0262     /* device specific; do nothing currently */
0263     return 0;
0264 }
0265 
0266 int ps3_mmio_region_create(struct ps3_mmio_region *r)
0267 {
0268     return r->mmio_ops->create(r);
0269 }
0270 EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
0271 
0272 static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
0273 {
0274     int result;
0275 
0276     dump_mmio_region(r);
0277     result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
0278         r->lpar_addr);
0279 
0280     if (result)
0281         pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
0282             __func__, __LINE__, ps3_result(result));
0283 
0284     r->lpar_addr = 0;
0285     return result;
0286 }
0287 
0288 static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
0289 {
0290     /* device specific; do nothing currently */
0291     return 0;
0292 }
0293 
0294 
0295 int ps3_free_mmio_region(struct ps3_mmio_region *r)
0296 {
0297     return r->mmio_ops->free(r);
0298 }
0299 
0300 EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
0301 
0302 static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
0303     .create = ps3_sb_mmio_region_create,
0304     .free = ps3_sb_free_mmio_region
0305 };
0306 
0307 static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
0308     .create = ps3_ioc0_mmio_region_create,
0309     .free = ps3_ioc0_free_mmio_region
0310 };
0311 
0312 int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
0313     struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
0314     enum ps3_mmio_page_size page_size)
0315 {
0316     r->dev = dev;
0317     r->bus_addr = bus_addr;
0318     r->len = len;
0319     r->page_size = page_size;
0320     switch (dev->dev_type) {
0321     case PS3_DEVICE_TYPE_SB:
0322         r->mmio_ops = &ps3_mmio_sb_region_ops;
0323         break;
0324     case PS3_DEVICE_TYPE_IOC0:
0325         r->mmio_ops = &ps3_mmio_ioc0_region_ops;
0326         break;
0327     default:
0328         BUG();
0329         return -EINVAL;
0330     }
0331     return 0;
0332 }
0333 EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
0334 
0335 static int ps3_system_bus_match(struct device *_dev,
0336     struct device_driver *_drv)
0337 {
0338     int result;
0339     struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
0340     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0341 
0342     if (!dev->match_sub_id)
0343         result = dev->match_id == drv->match_id;
0344     else
0345         result = dev->match_sub_id == drv->match_sub_id &&
0346             dev->match_id == drv->match_id;
0347 
0348     if (result)
0349         pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
0350             __func__, __LINE__,
0351             dev->match_id, dev->match_sub_id, dev_name(&dev->core),
0352             drv->match_id, drv->match_sub_id, drv->core.name);
0353     else
0354         pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
0355             __func__, __LINE__,
0356             dev->match_id, dev->match_sub_id, dev_name(&dev->core),
0357             drv->match_id, drv->match_sub_id, drv->core.name);
0358 
0359     return result;
0360 }
0361 
0362 static int ps3_system_bus_probe(struct device *_dev)
0363 {
0364     int result = 0;
0365     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0366     struct ps3_system_bus_driver *drv;
0367 
0368     BUG_ON(!dev);
0369     dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
0370 
0371     drv = ps3_system_bus_dev_to_system_bus_drv(dev);
0372     BUG_ON(!drv);
0373 
0374     if (drv->probe)
0375         result = drv->probe(dev);
0376     else
0377         pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
0378             dev_name(&dev->core));
0379 
0380     pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
0381     return result;
0382 }
0383 
0384 static void ps3_system_bus_remove(struct device *_dev)
0385 {
0386     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0387     struct ps3_system_bus_driver *drv;
0388 
0389     BUG_ON(!dev);
0390     dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
0391 
0392     drv = ps3_system_bus_dev_to_system_bus_drv(dev);
0393     BUG_ON(!drv);
0394 
0395     if (drv->remove)
0396         drv->remove(dev);
0397     else
0398         dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
0399             __func__, __LINE__, drv->core.name);
0400 
0401     pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
0402 }
0403 
0404 static void ps3_system_bus_shutdown(struct device *_dev)
0405 {
0406     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0407     struct ps3_system_bus_driver *drv;
0408 
0409     BUG_ON(!dev);
0410 
0411     dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
0412         dev->match_id);
0413 
0414     if (!dev->core.driver) {
0415         dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
0416             __LINE__);
0417         return;
0418     }
0419 
0420     drv = ps3_system_bus_dev_to_system_bus_drv(dev);
0421 
0422     BUG_ON(!drv);
0423 
0424     dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
0425         dev_name(&dev->core), drv->core.name);
0426 
0427     if (drv->shutdown)
0428         drv->shutdown(dev);
0429     else if (drv->remove) {
0430         dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
0431             __func__, __LINE__, drv->core.name);
0432         drv->remove(dev);
0433     } else {
0434         dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
0435             __func__, __LINE__, drv->core.name);
0436         BUG();
0437     }
0438 
0439     dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
0440 }
0441 
0442 static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
0443 {
0444     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0445 
0446     if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
0447                dev->match_sub_id))
0448         return -ENOMEM;
0449     return 0;
0450 }
0451 
0452 static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
0453     char *buf)
0454 {
0455     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0456     int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
0457                dev->match_sub_id);
0458 
0459     return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
0460 }
0461 static DEVICE_ATTR_RO(modalias);
0462 
0463 static struct attribute *ps3_system_bus_dev_attrs[] = {
0464     &dev_attr_modalias.attr,
0465     NULL,
0466 };
0467 ATTRIBUTE_GROUPS(ps3_system_bus_dev);
0468 
0469 struct bus_type ps3_system_bus_type = {
0470     .name = "ps3_system_bus",
0471     .match = ps3_system_bus_match,
0472     .uevent = ps3_system_bus_uevent,
0473     .probe = ps3_system_bus_probe,
0474     .remove = ps3_system_bus_remove,
0475     .shutdown = ps3_system_bus_shutdown,
0476     .dev_groups = ps3_system_bus_dev_groups,
0477 };
0478 
0479 static int __init ps3_system_bus_init(void)
0480 {
0481     int result;
0482 
0483     if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
0484         return -ENODEV;
0485 
0486     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0487 
0488     mutex_init(&usage_hack.mutex);
0489 
0490     result = device_register(&ps3_system_bus);
0491     BUG_ON(result);
0492 
0493     result = bus_register(&ps3_system_bus_type);
0494     BUG_ON(result);
0495 
0496     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0497     return result;
0498 }
0499 
0500 core_initcall(ps3_system_bus_init);
0501 
0502 /* Allocates a contiguous real buffer and creates mappings over it.
0503  * Returns the virtual address of the buffer and sets dma_handle
0504  * to the dma address (mapping) of the first page.
0505  */
0506 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
0507                  dma_addr_t *dma_handle, gfp_t flag,
0508                  unsigned long attrs)
0509 {
0510     int result;
0511     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0512     unsigned long virt_addr;
0513 
0514     flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
0515     flag |= __GFP_ZERO;
0516 
0517     virt_addr = __get_free_pages(flag, get_order(size));
0518 
0519     if (!virt_addr) {
0520         pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
0521         goto clean_none;
0522     }
0523 
0524     result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
0525                  CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
0526                  CBE_IOPTE_SO_RW | CBE_IOPTE_M);
0527 
0528     if (result) {
0529         pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
0530             __func__, __LINE__, result);
0531         BUG_ON("check region type");
0532         goto clean_alloc;
0533     }
0534 
0535     return (void*)virt_addr;
0536 
0537 clean_alloc:
0538     free_pages(virt_addr, get_order(size));
0539 clean_none:
0540     dma_handle = NULL;
0541     return NULL;
0542 }
0543 
0544 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
0545                   dma_addr_t dma_handle, unsigned long attrs)
0546 {
0547     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0548 
0549     ps3_dma_unmap(dev->d_region, dma_handle, size);
0550     free_pages((unsigned long)vaddr, get_order(size));
0551 }
0552 
0553 /* Creates TCEs for a user provided buffer.  The user buffer must be
0554  * contiguous real kernel storage (not vmalloc).  The address passed here
0555  * comprises a page address and offset into that page. The dma_addr_t
0556  * returned will point to the same byte within the page as was passed in.
0557  */
0558 
0559 static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
0560     unsigned long offset, size_t size, enum dma_data_direction direction,
0561     unsigned long attrs)
0562 {
0563     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0564     int result;
0565     dma_addr_t bus_addr;
0566     void *ptr = page_address(page) + offset;
0567 
0568     result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
0569                  &bus_addr,
0570                  CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
0571                  CBE_IOPTE_SO_RW | CBE_IOPTE_M);
0572 
0573     if (result) {
0574         pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
0575             __func__, __LINE__, result);
0576     }
0577 
0578     return bus_addr;
0579 }
0580 
0581 static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
0582                     unsigned long offset, size_t size,
0583                     enum dma_data_direction direction,
0584                     unsigned long attrs)
0585 {
0586     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0587     int result;
0588     dma_addr_t bus_addr;
0589     u64 iopte_flag;
0590     void *ptr = page_address(page) + offset;
0591 
0592     iopte_flag = CBE_IOPTE_M;
0593     switch (direction) {
0594     case DMA_BIDIRECTIONAL:
0595         iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
0596         break;
0597     case DMA_TO_DEVICE:
0598         iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
0599         break;
0600     case DMA_FROM_DEVICE:
0601         iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
0602         break;
0603     default:
0604         /* not happened */
0605         BUG();
0606     }
0607     result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
0608                  &bus_addr, iopte_flag);
0609 
0610     if (result) {
0611         pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
0612             __func__, __LINE__, result);
0613     }
0614     return bus_addr;
0615 }
0616 
0617 static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
0618     size_t size, enum dma_data_direction direction, unsigned long attrs)
0619 {
0620     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0621     int result;
0622 
0623     result = ps3_dma_unmap(dev->d_region, dma_addr, size);
0624 
0625     if (result) {
0626         pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
0627             __func__, __LINE__, result);
0628     }
0629 }
0630 
0631 static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
0632     int nents, enum dma_data_direction direction, unsigned long attrs)
0633 {
0634 #if defined(CONFIG_PS3_DYNAMIC_DMA)
0635     BUG_ON("do");
0636     return -EPERM;
0637 #else
0638     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0639     struct scatterlist *sg;
0640     int i;
0641 
0642     for_each_sg(sgl, sg, nents, i) {
0643         int result = ps3_dma_map(dev->d_region, sg_phys(sg),
0644                     sg->length, &sg->dma_address, 0);
0645 
0646         if (result) {
0647             pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
0648                 __func__, __LINE__, result);
0649             return -EINVAL;
0650         }
0651 
0652         sg->dma_length = sg->length;
0653     }
0654 
0655     return nents;
0656 #endif
0657 }
0658 
0659 static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
0660                int nents,
0661                enum dma_data_direction direction,
0662                unsigned long attrs)
0663 {
0664     BUG();
0665     return -EINVAL;
0666 }
0667 
0668 static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
0669     int nents, enum dma_data_direction direction, unsigned long attrs)
0670 {
0671 #if defined(CONFIG_PS3_DYNAMIC_DMA)
0672     BUG_ON("do");
0673 #endif
0674 }
0675 
0676 static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
0677                 int nents, enum dma_data_direction direction,
0678                 unsigned long attrs)
0679 {
0680     BUG();
0681 }
0682 
0683 static int ps3_dma_supported(struct device *_dev, u64 mask)
0684 {
0685     return mask >= DMA_BIT_MASK(32);
0686 }
0687 
0688 static const struct dma_map_ops ps3_sb_dma_ops = {
0689     .alloc = ps3_alloc_coherent,
0690     .free = ps3_free_coherent,
0691     .map_sg = ps3_sb_map_sg,
0692     .unmap_sg = ps3_sb_unmap_sg,
0693     .dma_supported = ps3_dma_supported,
0694     .map_page = ps3_sb_map_page,
0695     .unmap_page = ps3_unmap_page,
0696     .mmap = dma_common_mmap,
0697     .get_sgtable = dma_common_get_sgtable,
0698     .alloc_pages = dma_common_alloc_pages,
0699     .free_pages = dma_common_free_pages,
0700 };
0701 
0702 static const struct dma_map_ops ps3_ioc0_dma_ops = {
0703     .alloc = ps3_alloc_coherent,
0704     .free = ps3_free_coherent,
0705     .map_sg = ps3_ioc0_map_sg,
0706     .unmap_sg = ps3_ioc0_unmap_sg,
0707     .dma_supported = ps3_dma_supported,
0708     .map_page = ps3_ioc0_map_page,
0709     .unmap_page = ps3_unmap_page,
0710     .mmap = dma_common_mmap,
0711     .get_sgtable = dma_common_get_sgtable,
0712     .alloc_pages = dma_common_alloc_pages,
0713     .free_pages = dma_common_free_pages,
0714 };
0715 
0716 /**
0717  * ps3_system_bus_release_device - remove a device from the system bus
0718  */
0719 
0720 static void ps3_system_bus_release_device(struct device *_dev)
0721 {
0722     struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
0723     kfree(dev);
0724 }
0725 
0726 /**
0727  * ps3_system_bus_device_register - add a device to the system bus
0728  *
0729  * ps3_system_bus_device_register() expects the dev object to be allocated
0730  * dynamically by the caller.  The system bus takes ownership of the dev
0731  * object and frees the object in ps3_system_bus_release_device().
0732  */
0733 
0734 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
0735 {
0736     int result;
0737     static unsigned int dev_ioc0_count;
0738     static unsigned int dev_sb_count;
0739     static unsigned int dev_vuart_count;
0740     static unsigned int dev_lpm_count;
0741 
0742     if (!dev->core.parent)
0743         dev->core.parent = &ps3_system_bus;
0744     dev->core.bus = &ps3_system_bus_type;
0745     dev->core.release = ps3_system_bus_release_device;
0746 
0747     switch (dev->dev_type) {
0748     case PS3_DEVICE_TYPE_IOC0:
0749         dev->core.dma_ops = &ps3_ioc0_dma_ops;
0750         dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
0751         break;
0752     case PS3_DEVICE_TYPE_SB:
0753         dev->core.dma_ops = &ps3_sb_dma_ops;
0754         dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);
0755 
0756         break;
0757     case PS3_DEVICE_TYPE_VUART:
0758         dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
0759         break;
0760     case PS3_DEVICE_TYPE_LPM:
0761         dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
0762         break;
0763     default:
0764         BUG();
0765     }
0766 
0767     dev->core.of_node = NULL;
0768     set_dev_node(&dev->core, 0);
0769 
0770     pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));
0771 
0772     result = device_register(&dev->core);
0773     return result;
0774 }
0775 
0776 EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
0777 
0778 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
0779 {
0780     int result;
0781 
0782     pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
0783 
0784     if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
0785         return -ENODEV;
0786 
0787     drv->core.bus = &ps3_system_bus_type;
0788 
0789     result = driver_register(&drv->core);
0790     pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
0791     return result;
0792 }
0793 
0794 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
0795 
0796 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
0797 {
0798     pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
0799     driver_unregister(&drv->core);
0800     pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
0801 }
0802 
0803 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);