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