linux/arch/powerpc/platforms/ps3/system-bus.c
<<
>>
Prefs
   1/*
   2 *  PS3 system bus driver.
   3 *
   4 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
   5 *  Copyright 2006 Sony Corp.
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License as published by
   9 *  the Free Software Foundation; version 2 of the License.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20
  21#include <linux/kernel.h>
  22#include <linux/init.h>
  23#include <linux/export.h>
  24#include <linux/dma-mapping.h>
  25#include <linux/err.h>
  26#include <linux/slab.h>
  27
  28#include <asm/udbg.h>
  29#include <asm/lv1call.h>
  30#include <asm/firmware.h>
  31#include <asm/cell-regs.h>
  32
  33#include "platform.h"
  34
  35static struct device ps3_system_bus = {
  36        .init_name = "ps3_system",
  37};
  38
  39/* FIXME: need device usage counters! */
  40struct {
  41        struct mutex mutex;
  42        int sb_11; /* usb 0 */
  43        int sb_12; /* usb 0 */
  44        int gpu;
  45} static usage_hack;
  46
  47static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
  48                         u64 dev_id)
  49{
  50        return dev->bus_id == bus_id && dev->dev_id == dev_id;
  51}
  52
  53static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
  54{
  55        int result;
  56
  57        BUG_ON(!dev->bus_id);
  58        mutex_lock(&usage_hack.mutex);
  59
  60        if (ps3_is_device(dev, 1, 1)) {
  61                usage_hack.sb_11++;
  62                if (usage_hack.sb_11 > 1) {
  63                        result = 0;
  64                        goto done;
  65                }
  66        }
  67
  68        if (ps3_is_device(dev, 1, 2)) {
  69                usage_hack.sb_12++;
  70                if (usage_hack.sb_12 > 1) {
  71                        result = 0;
  72                        goto done;
  73                }
  74        }
  75
  76        result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
  77
  78        if (result) {
  79                pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
  80                        __LINE__, ps3_result(result));
  81                        result = -EPERM;
  82        }
  83
  84done:
  85        mutex_unlock(&usage_hack.mutex);
  86        return result;
  87}
  88
  89static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
  90{
  91        int result;
  92
  93        BUG_ON(!dev->bus_id);
  94        mutex_lock(&usage_hack.mutex);
  95
  96        if (ps3_is_device(dev, 1, 1)) {
  97                usage_hack.sb_11--;
  98                if (usage_hack.sb_11) {
  99                        result = 0;
 100                        goto done;
 101                }
 102        }
 103
 104        if (ps3_is_device(dev, 1, 2)) {
 105                usage_hack.sb_12--;
 106                if (usage_hack.sb_12) {
 107                        result = 0;
 108                        goto done;
 109                }
 110        }
 111
 112        result = lv1_close_device(dev->bus_id, dev->dev_id);
 113        BUG_ON(result);
 114
 115done:
 116        mutex_unlock(&usage_hack.mutex);
 117        return result;
 118}
 119
 120static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
 121{
 122        int result;
 123
 124        mutex_lock(&usage_hack.mutex);
 125
 126        usage_hack.gpu++;
 127        if (usage_hack.gpu > 1) {
 128                result = 0;
 129                goto done;
 130        }
 131
 132        result = lv1_gpu_open(0);
 133
 134        if (result) {
 135                pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
 136                        __LINE__, ps3_result(result));
 137                        result = -EPERM;
 138        }
 139
 140done:
 141        mutex_unlock(&usage_hack.mutex);
 142        return result;
 143}
 144
 145static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
 146{
 147        int result;
 148
 149        mutex_lock(&usage_hack.mutex);
 150
 151        usage_hack.gpu--;
 152        if (usage_hack.gpu) {
 153                result = 0;
 154                goto done;
 155        }
 156
 157        result = lv1_gpu_close();
 158        BUG_ON(result);
 159
 160done:
 161        mutex_unlock(&usage_hack.mutex);
 162        return result;
 163}
 164
 165int ps3_open_hv_device(struct ps3_system_bus_device *dev)
 166{
 167        BUG_ON(!dev);
 168        pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
 169
 170        switch (dev->match_id) {
 171        case PS3_MATCH_ID_EHCI:
 172        case PS3_MATCH_ID_OHCI:
 173        case PS3_MATCH_ID_GELIC:
 174        case PS3_MATCH_ID_STOR_DISK:
 175        case PS3_MATCH_ID_STOR_ROM:
 176        case PS3_MATCH_ID_STOR_FLASH:
 177                return ps3_open_hv_device_sb(dev);
 178
 179        case PS3_MATCH_ID_SOUND:
 180        case PS3_MATCH_ID_GPU:
 181                return ps3_open_hv_device_gpu(dev);
 182
 183        case PS3_MATCH_ID_AV_SETTINGS:
 184        case PS3_MATCH_ID_SYSTEM_MANAGER:
 185                pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
 186                        __LINE__, dev->match_id);
 187                pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
 188                        dev->bus_id);
 189                BUG();
 190                return -EINVAL;
 191
 192        default:
 193                break;
 194        }
 195
 196        pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
 197                dev->match_id);
 198        BUG();
 199        return -ENODEV;
 200}
 201EXPORT_SYMBOL_GPL(ps3_open_hv_device);
 202
 203int ps3_close_hv_device(struct ps3_system_bus_device *dev)
 204{
 205        BUG_ON(!dev);
 206        pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
 207
 208        switch (dev->match_id) {
 209        case PS3_MATCH_ID_EHCI:
 210        case PS3_MATCH_ID_OHCI:
 211        case PS3_MATCH_ID_GELIC:
 212        case PS3_MATCH_ID_STOR_DISK:
 213        case PS3_MATCH_ID_STOR_ROM:
 214        case PS3_MATCH_ID_STOR_FLASH:
 215                return ps3_close_hv_device_sb(dev);
 216
 217        case PS3_MATCH_ID_SOUND:
 218        case PS3_MATCH_ID_GPU:
 219                return ps3_close_hv_device_gpu(dev);
 220
 221        case PS3_MATCH_ID_AV_SETTINGS:
 222        case PS3_MATCH_ID_SYSTEM_MANAGER:
 223                pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
 224                        __LINE__, dev->match_id);
 225                pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
 226                        dev->bus_id);
 227                BUG();
 228                return -EINVAL;
 229
 230        default:
 231                break;
 232        }
 233
 234        pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
 235                dev->match_id);
 236        BUG();
 237        return -ENODEV;
 238}
 239EXPORT_SYMBOL_GPL(ps3_close_hv_device);
 240
 241#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
 242static void _dump_mmio_region(const struct ps3_mmio_region* r,
 243        const char* func, int line)
 244{
 245        pr_debug("%s:%d: dev       %llu:%llu\n", func, line, r->dev->bus_id,
 246                r->dev->dev_id);
 247        pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
 248        pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
 249        pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
 250}
 251
 252static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
 253{
 254        int result;
 255        u64 lpar_addr;
 256
 257        result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
 258                r->bus_addr, r->len, r->page_size, &lpar_addr);
 259        r->lpar_addr = lpar_addr;
 260
 261        if (result) {
 262                pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
 263                        __func__, __LINE__, ps3_result(result));
 264                r->lpar_addr = 0;
 265        }
 266
 267        dump_mmio_region(r);
 268        return result;
 269}
 270
 271static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
 272{
 273        /* device specific; do nothing currently */
 274        return 0;
 275}
 276
 277int ps3_mmio_region_create(struct ps3_mmio_region *r)
 278{
 279        return r->mmio_ops->create(r);
 280}
 281EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
 282
 283static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
 284{
 285        int result;
 286
 287        dump_mmio_region(r);
 288        result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
 289                r->lpar_addr);
 290
 291        if (result)
 292                pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
 293                        __func__, __LINE__, ps3_result(result));
 294
 295        r->lpar_addr = 0;
 296        return result;
 297}
 298
 299static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
 300{
 301        /* device specific; do nothing currently */
 302        return 0;
 303}
 304
 305
 306int ps3_free_mmio_region(struct ps3_mmio_region *r)
 307{
 308        return r->mmio_ops->free(r);
 309}
 310
 311EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
 312
 313static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
 314        .create = ps3_sb_mmio_region_create,
 315        .free = ps3_sb_free_mmio_region
 316};
 317
 318static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
 319        .create = ps3_ioc0_mmio_region_create,
 320        .free = ps3_ioc0_free_mmio_region
 321};
 322
 323int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
 324        struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
 325        enum ps3_mmio_page_size page_size)
 326{
 327        r->dev = dev;
 328        r->bus_addr = bus_addr;
 329        r->len = len;
 330        r->page_size = page_size;
 331        switch (dev->dev_type) {
 332        case PS3_DEVICE_TYPE_SB:
 333                r->mmio_ops = &ps3_mmio_sb_region_ops;
 334                break;
 335        case PS3_DEVICE_TYPE_IOC0:
 336                r->mmio_ops = &ps3_mmio_ioc0_region_ops;
 337                break;
 338        default:
 339                BUG();
 340                return -EINVAL;
 341        }
 342        return 0;
 343}
 344EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
 345
 346static int ps3_system_bus_match(struct device *_dev,
 347        struct device_driver *_drv)
 348{
 349        int result;
 350        struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
 351        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 352
 353        if (!dev->match_sub_id)
 354                result = dev->match_id == drv->match_id;
 355        else
 356                result = dev->match_sub_id == drv->match_sub_id &&
 357                        dev->match_id == drv->match_id;
 358
 359        if (result)
 360                pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
 361                        __func__, __LINE__,
 362                        dev->match_id, dev->match_sub_id, dev_name(&dev->core),
 363                        drv->match_id, drv->match_sub_id, drv->core.name);
 364        else
 365                pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
 366                        __func__, __LINE__,
 367                        dev->match_id, dev->match_sub_id, dev_name(&dev->core),
 368                        drv->match_id, drv->match_sub_id, drv->core.name);
 369
 370        return result;
 371}
 372
 373static int ps3_system_bus_probe(struct device *_dev)
 374{
 375        int result = 0;
 376        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 377        struct ps3_system_bus_driver *drv;
 378
 379        BUG_ON(!dev);
 380        dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
 381
 382        drv = ps3_system_bus_dev_to_system_bus_drv(dev);
 383        BUG_ON(!drv);
 384
 385        if (drv->probe)
 386                result = drv->probe(dev);
 387        else
 388                pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
 389                        dev_name(&dev->core));
 390
 391        pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
 392        return result;
 393}
 394
 395static int ps3_system_bus_remove(struct device *_dev)
 396{
 397        int result = 0;
 398        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 399        struct ps3_system_bus_driver *drv;
 400
 401        BUG_ON(!dev);
 402        dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
 403
 404        drv = ps3_system_bus_dev_to_system_bus_drv(dev);
 405        BUG_ON(!drv);
 406
 407        if (drv->remove)
 408                result = drv->remove(dev);
 409        else
 410                dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
 411                        __func__, __LINE__, drv->core.name);
 412
 413        pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
 414        return result;
 415}
 416
 417static void ps3_system_bus_shutdown(struct device *_dev)
 418{
 419        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 420        struct ps3_system_bus_driver *drv;
 421
 422        BUG_ON(!dev);
 423
 424        dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
 425                dev->match_id);
 426
 427        if (!dev->core.driver) {
 428                dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
 429                        __LINE__);
 430                return;
 431        }
 432
 433        drv = ps3_system_bus_dev_to_system_bus_drv(dev);
 434
 435        BUG_ON(!drv);
 436
 437        dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
 438                dev_name(&dev->core), drv->core.name);
 439
 440        if (drv->shutdown)
 441                drv->shutdown(dev);
 442        else if (drv->remove) {
 443                dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
 444                        __func__, __LINE__, drv->core.name);
 445                drv->remove(dev);
 446        } else {
 447                dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
 448                        __func__, __LINE__, drv->core.name);
 449                BUG();
 450        }
 451
 452        dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
 453}
 454
 455static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
 456{
 457        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 458
 459        if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
 460                           dev->match_sub_id))
 461                return -ENOMEM;
 462        return 0;
 463}
 464
 465static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
 466        char *buf)
 467{
 468        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 469        int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
 470                           dev->match_sub_id);
 471
 472        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 473}
 474
 475static struct device_attribute ps3_system_bus_dev_attrs[] = {
 476        __ATTR_RO(modalias),
 477        __ATTR_NULL,
 478};
 479
 480struct bus_type ps3_system_bus_type = {
 481        .name = "ps3_system_bus",
 482        .match = ps3_system_bus_match,
 483        .uevent = ps3_system_bus_uevent,
 484        .probe = ps3_system_bus_probe,
 485        .remove = ps3_system_bus_remove,
 486        .shutdown = ps3_system_bus_shutdown,
 487        .dev_attrs = ps3_system_bus_dev_attrs,
 488};
 489
 490static int __init ps3_system_bus_init(void)
 491{
 492        int result;
 493
 494        if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 495                return -ENODEV;
 496
 497        pr_debug(" -> %s:%d\n", __func__, __LINE__);
 498
 499        mutex_init(&usage_hack.mutex);
 500
 501        result = device_register(&ps3_system_bus);
 502        BUG_ON(result);
 503
 504        result = bus_register(&ps3_system_bus_type);
 505        BUG_ON(result);
 506
 507        pr_debug(" <- %s:%d\n", __func__, __LINE__);
 508        return result;
 509}
 510
 511core_initcall(ps3_system_bus_init);
 512
 513/* Allocates a contiguous real buffer and creates mappings over it.
 514 * Returns the virtual address of the buffer and sets dma_handle
 515 * to the dma address (mapping) of the first page.
 516 */
 517static void * ps3_alloc_coherent(struct device *_dev, size_t size,
 518                                      dma_addr_t *dma_handle, gfp_t flag)
 519{
 520        int result;
 521        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 522        unsigned long virt_addr;
 523
 524        flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
 525        flag |= __GFP_ZERO;
 526
 527        virt_addr = __get_free_pages(flag, get_order(size));
 528
 529        if (!virt_addr) {
 530                pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
 531                goto clean_none;
 532        }
 533
 534        result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
 535                             CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
 536                             CBE_IOPTE_SO_RW | CBE_IOPTE_M);
 537
 538        if (result) {
 539                pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
 540                        __func__, __LINE__, result);
 541                BUG_ON("check region type");
 542                goto clean_alloc;
 543        }
 544
 545        return (void*)virt_addr;
 546
 547clean_alloc:
 548        free_pages(virt_addr, get_order(size));
 549clean_none:
 550        dma_handle = NULL;
 551        return NULL;
 552}
 553
 554static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
 555        dma_addr_t dma_handle)
 556{
 557        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 558
 559        ps3_dma_unmap(dev->d_region, dma_handle, size);
 560        free_pages((unsigned long)vaddr, get_order(size));
 561}
 562
 563/* Creates TCEs for a user provided buffer.  The user buffer must be
 564 * contiguous real kernel storage (not vmalloc).  The address passed here
 565 * comprises a page address and offset into that page. The dma_addr_t
 566 * returned will point to the same byte within the page as was passed in.
 567 */
 568
 569static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
 570        unsigned long offset, size_t size, enum dma_data_direction direction,
 571        struct dma_attrs *attrs)
 572{
 573        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 574        int result;
 575        dma_addr_t bus_addr;
 576        void *ptr = page_address(page) + offset;
 577
 578        result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
 579                             &bus_addr,
 580                             CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
 581                             CBE_IOPTE_SO_RW | CBE_IOPTE_M);
 582
 583        if (result) {
 584                pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
 585                        __func__, __LINE__, result);
 586        }
 587
 588        return bus_addr;
 589}
 590
 591static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
 592                                    unsigned long offset, size_t size,
 593                                    enum dma_data_direction direction,
 594                                    struct dma_attrs *attrs)
 595{
 596        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 597        int result;
 598        dma_addr_t bus_addr;
 599        u64 iopte_flag;
 600        void *ptr = page_address(page) + offset;
 601
 602        iopte_flag = CBE_IOPTE_M;
 603        switch (direction) {
 604        case DMA_BIDIRECTIONAL:
 605                iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
 606                break;
 607        case DMA_TO_DEVICE:
 608                iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
 609                break;
 610        case DMA_FROM_DEVICE:
 611                iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
 612                break;
 613        default:
 614                /* not happned */
 615                BUG();
 616        };
 617        result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
 618                             &bus_addr, iopte_flag);
 619
 620        if (result) {
 621                pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
 622                        __func__, __LINE__, result);
 623        }
 624        return bus_addr;
 625}
 626
 627static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
 628        size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
 629{
 630        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 631        int result;
 632
 633        result = ps3_dma_unmap(dev->d_region, dma_addr, size);
 634
 635        if (result) {
 636                pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
 637                        __func__, __LINE__, result);
 638        }
 639}
 640
 641static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
 642        int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 643{
 644#if defined(CONFIG_PS3_DYNAMIC_DMA)
 645        BUG_ON("do");
 646        return -EPERM;
 647#else
 648        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 649        struct scatterlist *sg;
 650        int i;
 651
 652        for_each_sg(sgl, sg, nents, i) {
 653                int result = ps3_dma_map(dev->d_region, sg_phys(sg),
 654                                        sg->length, &sg->dma_address, 0);
 655
 656                if (result) {
 657                        pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
 658                                __func__, __LINE__, result);
 659                        return -EINVAL;
 660                }
 661
 662                sg->dma_length = sg->length;
 663        }
 664
 665        return nents;
 666#endif
 667}
 668
 669static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
 670                           int nents,
 671                           enum dma_data_direction direction,
 672                           struct dma_attrs *attrs)
 673{
 674        BUG();
 675        return 0;
 676}
 677
 678static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
 679        int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 680{
 681#if defined(CONFIG_PS3_DYNAMIC_DMA)
 682        BUG_ON("do");
 683#endif
 684}
 685
 686static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
 687                            int nents, enum dma_data_direction direction,
 688                            struct dma_attrs *attrs)
 689{
 690        BUG();
 691}
 692
 693static int ps3_dma_supported(struct device *_dev, u64 mask)
 694{
 695        return mask >= DMA_BIT_MASK(32);
 696}
 697
 698static u64 ps3_dma_get_required_mask(struct device *_dev)
 699{
 700        return DMA_BIT_MASK(32);
 701}
 702
 703static struct dma_map_ops ps3_sb_dma_ops = {
 704        .alloc_coherent = ps3_alloc_coherent,
 705        .free_coherent = ps3_free_coherent,
 706        .map_sg = ps3_sb_map_sg,
 707        .unmap_sg = ps3_sb_unmap_sg,
 708        .dma_supported = ps3_dma_supported,
 709        .get_required_mask = ps3_dma_get_required_mask,
 710        .map_page = ps3_sb_map_page,
 711        .unmap_page = ps3_unmap_page,
 712};
 713
 714static struct dma_map_ops ps3_ioc0_dma_ops = {
 715        .alloc_coherent = ps3_alloc_coherent,
 716        .free_coherent = ps3_free_coherent,
 717        .map_sg = ps3_ioc0_map_sg,
 718        .unmap_sg = ps3_ioc0_unmap_sg,
 719        .dma_supported = ps3_dma_supported,
 720        .get_required_mask = ps3_dma_get_required_mask,
 721        .map_page = ps3_ioc0_map_page,
 722        .unmap_page = ps3_unmap_page,
 723};
 724
 725/**
 726 * ps3_system_bus_release_device - remove a device from the system bus
 727 */
 728
 729static void ps3_system_bus_release_device(struct device *_dev)
 730{
 731        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 732        kfree(dev);
 733}
 734
 735/**
 736 * ps3_system_bus_device_register - add a device to the system bus
 737 *
 738 * ps3_system_bus_device_register() expects the dev object to be allocated
 739 * dynamically by the caller.  The system bus takes ownership of the dev
 740 * object and frees the object in ps3_system_bus_release_device().
 741 */
 742
 743int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
 744{
 745        int result;
 746        static unsigned int dev_ioc0_count;
 747        static unsigned int dev_sb_count;
 748        static unsigned int dev_vuart_count;
 749        static unsigned int dev_lpm_count;
 750
 751        if (!dev->core.parent)
 752                dev->core.parent = &ps3_system_bus;
 753        dev->core.bus = &ps3_system_bus_type;
 754        dev->core.release = ps3_system_bus_release_device;
 755
 756        switch (dev->dev_type) {
 757        case PS3_DEVICE_TYPE_IOC0:
 758                dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
 759                dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
 760                break;
 761        case PS3_DEVICE_TYPE_SB:
 762                dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
 763                dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);
 764
 765                break;
 766        case PS3_DEVICE_TYPE_VUART:
 767                dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
 768                break;
 769        case PS3_DEVICE_TYPE_LPM:
 770                dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
 771                break;
 772        default:
 773                BUG();
 774        };
 775
 776        dev->core.of_node = NULL;
 777        set_dev_node(&dev->core, 0);
 778
 779        pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));
 780
 781        result = device_register(&dev->core);
 782        return result;
 783}
 784
 785EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
 786
 787int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
 788{
 789        int result;
 790
 791        pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 792
 793        if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 794                return -ENODEV;
 795
 796        drv->core.bus = &ps3_system_bus_type;
 797
 798        result = driver_register(&drv->core);
 799        pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 800        return result;
 801}
 802
 803EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
 804
 805void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
 806{
 807        pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 808        driver_unregister(&drv->core);
 809        pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 810}
 811
 812EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
 813