linux/drivers/staging/csr/sdio_mmc.c
<<
>>
Prefs
   1/*
   2 * ---------------------------------------------------------------------------
   3 *
   4 * FILE: sdio_mmc.c
   5 *
   6 * PURPOSE: SDIO driver interface for generic MMC stack.
   7 *
   8 * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
   9 *
  10 * ---------------------------------------------------------------------------
  11 */
  12#include <linux/module.h>
  13#include <linux/init.h>
  14#include <linux/kernel.h>
  15#include <linux/mutex.h>
  16#include <linux/gfp.h>
  17#include <linux/mmc/core.h>
  18#include <linux/mmc/card.h>
  19#include <linux/mmc/host.h>
  20#include <linux/mmc/sdio_func.h>
  21#include <linux/mmc/sdio_ids.h>
  22#include <linux/mmc/sdio.h>
  23#include <linux/suspend.h>
  24
  25#include "unifi_priv.h"
  26
  27#ifdef ANDROID_BUILD
  28struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
  29#endif
  30
  31static CsrSdioFunctionDriver *sdio_func_drv;
  32
  33#ifdef CONFIG_PM
  34static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr);
  35#endif
  36
  37/*
  38 * We need to keep track of the power on/off because we can not call
  39 * mmc_power_restore_host() when the card is already powered.
  40 * Even then, we need to patch the MMC driver to add a power_restore handler
  41 * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched,
  42 * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel,
  43 * returning immediately (at least on x86).
  44 */
  45static int card_is_powered = 1;
  46
  47/* MMC uses ENOMEDIUM to indicate card gone away */
  48
  49static CsrResult
  50ConvertSdioToCsrSdioResult(int r)
  51{
  52    CsrResult csrResult = CSR_RESULT_FAILURE;
  53
  54    switch (r) {
  55    case 0:
  56        csrResult = CSR_RESULT_SUCCESS;
  57    break;
  58    case -EIO:
  59    case -EILSEQ:
  60        csrResult = CSR_SDIO_RESULT_CRC_ERROR;
  61    break;
  62    /* Timeout errors */
  63    case -ETIMEDOUT:
  64    case -EBUSY:
  65        csrResult = CSR_SDIO_RESULT_TIMEOUT;
  66    break;
  67    case -ENODEV:
  68    case -ENOMEDIUM:
  69        csrResult = CSR_SDIO_RESULT_NO_DEVICE;
  70    break;
  71    case -EINVAL:
  72        csrResult = CSR_SDIO_RESULT_INVALID_VALUE;
  73    break;
  74    case -ENOMEM:
  75    case -ENOSYS:
  76    case -ERANGE:
  77    case -ENXIO:
  78        csrResult = CSR_RESULT_FAILURE;
  79    break;
  80    default:
  81        unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r);
  82    break;
  83    }
  84
  85    return csrResult;
  86}
  87
  88
  89static int
  90csr_io_rw_direct(struct mmc_card *card, int write, uint8_t fn,
  91                 uint32_t addr, uint8_t in, uint8_t* out)
  92{
  93    struct mmc_command cmd;
  94    int err;
  95
  96    BUG_ON(!card);
  97    BUG_ON(fn > 7);
  98
  99    memset(&cmd, 0, sizeof(struct mmc_command));
 100
 101    cmd.opcode = SD_IO_RW_DIRECT;
 102    cmd.arg = write ? 0x80000000 : 0x00000000;
 103    cmd.arg |= fn << 28;
 104    cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
 105    cmd.arg |= addr << 9;
 106    cmd.arg |= in;
 107    cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
 108
 109    err = mmc_wait_for_cmd(card->host, &cmd, 0);
 110    if (err)
 111        return err;
 112
 113    /* this function is not exported, so we will need to sort it out here
 114     * for now, lets hard code it to sdio */
 115    if (0) {
 116        /* old arg (mmc_host_is_spi(card->host)) { */
 117        /* host driver already reported errors */
 118    } else {
 119        if (cmd.resp[0] & R5_ERROR) {
 120            printk(KERN_ERR "%s: r5 error 0x%02x\n",
 121                   __FUNCTION__, cmd.resp[0]);
 122            return -EIO;
 123        }
 124        if (cmd.resp[0] & R5_FUNCTION_NUMBER)
 125            return -EINVAL;
 126        if (cmd.resp[0] & R5_OUT_OF_RANGE)
 127            return -ERANGE;
 128    }
 129
 130    if (out) {
 131        if (0) {    /* old argument (mmc_host_is_spi(card->host)) */
 132            *out = (cmd.resp[0] >> 8) & 0xFF;
 133        }
 134        else {
 135            *out = cmd.resp[0] & 0xFF;
 136        }
 137    }
 138
 139    return CSR_RESULT_SUCCESS;
 140}
 141
 142
 143CsrResult
 144CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data)
 145{
 146    struct sdio_func *func = (struct sdio_func *)function->priv;
 147    int err = 0;
 148
 149    _sdio_claim_host(func);
 150    *data = sdio_readb(func, address, &err);
 151    _sdio_release_host(func);
 152
 153    if (err) {
 154        return ConvertSdioToCsrSdioResult(err);
 155    }
 156
 157    return CSR_RESULT_SUCCESS;
 158} /* CsrSdioRead8() */
 159
 160CsrResult
 161CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data)
 162{
 163    struct sdio_func *func = (struct sdio_func *)function->priv;
 164    int err = 0;
 165
 166    _sdio_claim_host(func);
 167    sdio_writeb(func, data, address, &err);
 168    _sdio_release_host(func);
 169
 170    if (err) {
 171        return ConvertSdioToCsrSdioResult(err);
 172    }
 173
 174    return CSR_RESULT_SUCCESS;
 175} /* CsrSdioWrite8() */
 176
 177CsrResult
 178CsrSdioRead16(CsrSdioFunction *function, u32 address, u16 *data)
 179{
 180    struct sdio_func *func = (struct sdio_func *)function->priv;
 181    int err;
 182    uint8_t b0, b1;
 183
 184    _sdio_claim_host(func);
 185    b0 = sdio_readb(func, address, &err);
 186    if (err) {
 187        _sdio_release_host(func);
 188        return ConvertSdioToCsrSdioResult(err);
 189    }
 190
 191    b1 = sdio_readb(func, address+1, &err);
 192    if (err) {
 193        _sdio_release_host(func);
 194        return ConvertSdioToCsrSdioResult(err);
 195    }
 196    _sdio_release_host(func);
 197
 198    *data = ((uint16_t)b1 << 8) | b0;
 199
 200    return CSR_RESULT_SUCCESS;
 201} /* CsrSdioRead16() */
 202
 203
 204CsrResult
 205CsrSdioWrite16(CsrSdioFunction *function, u32 address, u16 data)
 206{
 207    struct sdio_func *func = (struct sdio_func *)function->priv;
 208    int err;
 209    uint8_t b0, b1;
 210
 211    _sdio_claim_host(func);
 212    b1 = (data >> 8) & 0xFF;
 213    sdio_writeb(func, b1, address+1, &err);
 214    if (err) {
 215        _sdio_release_host(func);
 216        return ConvertSdioToCsrSdioResult(err);
 217    }
 218
 219    b0 = data & 0xFF;
 220    sdio_writeb(func, b0, address, &err);
 221    if (err) {
 222        _sdio_release_host(func);
 223        return ConvertSdioToCsrSdioResult(err);
 224    }
 225
 226    _sdio_release_host(func);
 227    return CSR_RESULT_SUCCESS;
 228} /* CsrSdioWrite16() */
 229
 230
 231CsrResult
 232CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data)
 233{
 234    struct sdio_func *func = (struct sdio_func *)function->priv;
 235    int err = 0;
 236
 237    _sdio_claim_host(func);
 238#ifdef MMC_QUIRK_LENIENT_FN0
 239    *data = sdio_f0_readb(func, address, &err);
 240#else
 241    err = csr_io_rw_direct(func->card, 0, 0, address, 0, data);
 242#endif
 243    _sdio_release_host(func);
 244
 245    if (err) {
 246        return ConvertSdioToCsrSdioResult(err);
 247    }
 248
 249    return CSR_RESULT_SUCCESS;
 250} /* CsrSdioF0Read8() */
 251
 252CsrResult
 253CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data)
 254{
 255    struct sdio_func *func = (struct sdio_func *)function->priv;
 256    int err = 0;
 257
 258    _sdio_claim_host(func);
 259#ifdef MMC_QUIRK_LENIENT_FN0
 260    sdio_f0_writeb(func, data, address, &err);
 261#else
 262    err = csr_io_rw_direct(func->card, 1, 0, address, data, NULL);
 263#endif
 264    _sdio_release_host(func);
 265
 266    if (err) {
 267        return ConvertSdioToCsrSdioResult(err);
 268    }
 269
 270    return CSR_RESULT_SUCCESS;
 271} /* CsrSdioF0Write8() */
 272
 273
 274CsrResult
 275CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length)
 276{
 277    struct sdio_func *func = (struct sdio_func *)function->priv;
 278    int err;
 279
 280    _sdio_claim_host(func);
 281    err = sdio_readsb(func, data, address, length);
 282    _sdio_release_host(func);
 283
 284    if (err) {
 285        return ConvertSdioToCsrSdioResult(err);
 286    }
 287
 288    return CSR_RESULT_SUCCESS;
 289} /* CsrSdioRead() */
 290
 291CsrResult
 292CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 length)
 293{
 294    struct sdio_func *func = (struct sdio_func *)function->priv;
 295    int err;
 296
 297    _sdio_claim_host(func);
 298    err = sdio_writesb(func, address, (void*)data, length);
 299    _sdio_release_host(func);
 300
 301    if (err) {
 302        return ConvertSdioToCsrSdioResult(err);
 303    }
 304
 305    return CSR_RESULT_SUCCESS;
 306} /* CsrSdioWrite() */
 307
 308
 309static int
 310csr_sdio_enable_hs(struct mmc_card *card)
 311{
 312    int ret;
 313    u8 speed;
 314
 315    if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) {
 316        /* We've asked for HS clock rates, but controller doesn't
 317         * claim to support it. We should limit the clock
 318         * to 25MHz via module parameter.
 319         */
 320        printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
 321        return 0;
 322    }
 323
 324    if (!card->cccr.high_speed)
 325        return 0;
 326
 327#if 1
 328    ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
 329    if (ret)
 330        return ret;
 331
 332    speed |= SDIO_SPEED_EHS;
 333#else
 334    /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
 335    speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS;
 336#endif
 337
 338    ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
 339    if (ret)
 340        return ret;
 341
 342    mmc_card_set_highspeed(card);
 343    card->host->ios.timing = MMC_TIMING_SD_HS;
 344    card->host->ops->set_ios(card->host, &card->host->ios);
 345
 346    return 0;
 347}
 348
 349static int
 350csr_sdio_disable_hs(struct mmc_card *card)
 351{
 352    int ret;
 353    u8 speed;
 354
 355    if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
 356        return 0;
 357
 358    if (!card->cccr.high_speed)
 359        return 0;
 360#if 1
 361    ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
 362    if (ret)
 363        return ret;
 364
 365    speed &= ~SDIO_SPEED_EHS;
 366#else
 367    /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
 368    speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */
 369#endif
 370
 371    ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
 372    if (ret)
 373        return ret;
 374
 375    card->state &= ~MMC_STATE_HIGHSPEED;
 376    card->host->ios.timing = MMC_TIMING_LEGACY;
 377    card->host->ops->set_ios(card->host, &card->host->ios);
 378
 379    return 0;
 380}
 381
 382
 383/*
 384 * ---------------------------------------------------------------------------
 385 *  CsrSdioMaxBusClockFrequencySet
 386 *
 387 *      Set the maximum SDIO bus clock speed to use.
 388 *
 389 *  Arguments:
 390 *      sdio            SDIO context pointer
 391 *      maxFrequency         maximum clock speed in Hz
 392 *
 393 *  Returns:
 394 *      an error code.
 395 * ---------------------------------------------------------------------------
 396 */
 397CsrResult
 398CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, u32 maxFrequency)
 399{
 400    struct sdio_func *func = (struct sdio_func *)function->priv;
 401    struct mmc_host *host = func->card->host;
 402    struct mmc_ios *ios = &host->ios;
 403    unsigned int max_hz;
 404    int err;
 405        u32 max_khz = maxFrequency/1000;
 406
 407    if (!max_khz || max_khz > sdio_clock) {
 408        max_khz = sdio_clock;
 409    }
 410
 411    _sdio_claim_host(func);
 412    max_hz = 1000 * max_khz;
 413    if (max_hz > host->f_max) {
 414        max_hz = host->f_max;
 415    }
 416
 417    if (max_hz > 25000000) {
 418        err = csr_sdio_enable_hs(func->card);
 419    } else {
 420        err = csr_sdio_disable_hs(func->card);
 421    }
 422    if (err) {
 423        printk(KERN_ERR "SDIO warning: Failed to configure SDIO clock mode\n");
 424        _sdio_release_host(func);
 425                return CSR_RESULT_SUCCESS;
 426    }
 427
 428    ios->clock = max_hz;
 429    host->ops->set_ios(host, ios);
 430
 431    _sdio_release_host(func);
 432
 433        return CSR_RESULT_SUCCESS;
 434} /* CsrSdioMaxBusClockFrequencySet() */
 435
 436
 437/*
 438 * ---------------------------------------------------------------------------
 439 *  CsrSdioInterruptEnable
 440 *  CsrSdioInterruptDisable
 441 *
 442 *      Enable or disable the SDIO interrupt.
 443 *      The driver disables the SDIO interrupt until the i/o thread can
 444 *      process it.
 445 *      The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
 446 *      register in the Card Common Control Register block, but this requires
 447 *      two CMD52 operations. A better solution is to mask the interrupt at
 448 *      the host controller.
 449 *
 450 *  Arguments:
 451 *      sdio            SDIO context pointer
 452 *
 453 *  Returns:
 454 *      Zero on success or a UniFi driver error code.
 455 *
 456 * ---------------------------------------------------------------------------
 457 */
 458CsrResult
 459CsrSdioInterruptEnable(CsrSdioFunction *function)
 460{
 461    struct sdio_func *func = (struct sdio_func *)function->priv;
 462    int err = 0;
 463
 464#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
 465    sdio_unblock_card_irq(func);
 466#else
 467    _sdio_claim_host(func);
 468    /* Write the Int Enable in CCCR block */
 469#ifdef MMC_QUIRK_LENIENT_FN0
 470    sdio_f0_writeb(func, 0x3, SDIO_CCCR_IENx, &err);
 471#else
 472    err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x03, NULL);
 473#endif
 474    _sdio_release_host(func);
 475
 476    if (err) {
 477        printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
 478        return ConvertSdioToCsrSdioResult(err);
 479    }
 480#endif
 481    return CSR_RESULT_SUCCESS;
 482} /* CsrSdioInterruptEnable() */
 483
 484CsrResult
 485CsrSdioInterruptDisable(CsrSdioFunction *function)
 486{
 487    struct sdio_func *func = (struct sdio_func *)function->priv;
 488    int err = 0;
 489
 490#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
 491    sdio_block_card_irq(func);
 492#else
 493    _sdio_claim_host(func);
 494    /* Write the Int Enable in CCCR block */
 495#ifdef MMC_QUIRK_LENIENT_FN0
 496    sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &err);
 497#else
 498    err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
 499#endif
 500    _sdio_release_host(func);
 501
 502    if (err) {
 503        printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
 504        return ConvertSdioToCsrSdioResult(err);
 505    }
 506#endif
 507    return CSR_RESULT_SUCCESS;
 508} /* CsrSdioInterruptDisable() */
 509
 510
 511void CsrSdioInterruptAcknowledge(CsrSdioFunction *function)
 512{
 513}
 514
 515
 516/*
 517 * ---------------------------------------------------------------------------
 518 *  CsrSdioFunctionEnable
 519 *
 520 *      Enable i/o on function 1.
 521 *
 522 *  Arguments:
 523 *      sdio            SDIO context pointer
 524 *
 525 * Returns:
 526 *      UniFi driver error code.
 527 * ---------------------------------------------------------------------------
 528 */
 529CsrResult
 530CsrSdioFunctionEnable(CsrSdioFunction *function)
 531{
 532    struct sdio_func *func = (struct sdio_func *)function->priv;
 533    int err;
 534
 535    /* Enable UniFi function 1 (the 802.11 part). */
 536    _sdio_claim_host(func);
 537    err = sdio_enable_func(func);
 538    _sdio_release_host(func);
 539    if (err) {
 540        unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num);
 541    }
 542
 543    return ConvertSdioToCsrSdioResult(err);
 544} /* CsrSdioFunctionEnable() */
 545
 546
 547/*
 548 * ---------------------------------------------------------------------------
 549 *  CsrSdioFunctionDisable
 550 *
 551 *      Enable i/o on function 1.
 552 *
 553 *  Arguments:
 554 *      sdio            SDIO context pointer
 555 *
 556 * Returns:
 557 *      UniFi driver error code.
 558 * ---------------------------------------------------------------------------
 559 */
 560CsrResult
 561CsrSdioFunctionDisable(CsrSdioFunction *function)
 562{
 563    struct sdio_func *func = (struct sdio_func *)function->priv;
 564    int err;
 565
 566    /* Disable UniFi function 1 (the 802.11 part). */
 567    _sdio_claim_host(func);
 568    err = sdio_disable_func(func);
 569    _sdio_release_host(func);
 570    if (err) {
 571        unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num);
 572    }
 573
 574    return ConvertSdioToCsrSdioResult(err);
 575} /* CsrSdioFunctionDisable() */
 576
 577
 578/*
 579 * ---------------------------------------------------------------------------
 580 *  CsrSdioFunctionActive
 581 *
 582 *      No-op as the bus goes to an active state at the start of every
 583 *      command.
 584 *
 585 *  Arguments:
 586 *      sdio            SDIO context pointer
 587 * ---------------------------------------------------------------------------
 588 */
 589void
 590CsrSdioFunctionActive(CsrSdioFunction *function)
 591{
 592} /* CsrSdioFunctionActive() */
 593
 594/*
 595 * ---------------------------------------------------------------------------
 596 *  CsrSdioFunctionIdle
 597 *
 598 *      Set the function as idle.
 599 *
 600 *  Arguments:
 601 *      sdio            SDIO context pointer
 602 * ---------------------------------------------------------------------------
 603 */
 604void
 605CsrSdioFunctionIdle(CsrSdioFunction *function)
 606{
 607} /* CsrSdioFunctionIdle() */
 608
 609
 610/*
 611 * ---------------------------------------------------------------------------
 612 *  CsrSdioPowerOn
 613 *
 614 *      Power on UniFi.
 615 *
 616 *  Arguments:
 617 *      sdio            SDIO context pointer
 618 * ---------------------------------------------------------------------------
 619 */
 620CsrResult
 621CsrSdioPowerOn(CsrSdioFunction *function)
 622{
 623    struct sdio_func *func = (struct sdio_func *)function->priv;
 624    struct mmc_host *host = func->card->host;
 625
 626    _sdio_claim_host(func);
 627    if (!card_is_powered) {
 628        mmc_power_restore_host(host);
 629        card_is_powered = 1;
 630    } else {
 631        printk(KERN_INFO "SDIO: Skip power on; card is already powered.\n");
 632    }
 633    _sdio_release_host(func);
 634
 635    return CSR_RESULT_SUCCESS;
 636} /* CsrSdioPowerOn() */
 637
 638/*
 639 * ---------------------------------------------------------------------------
 640 *  CsrSdioPowerOff
 641 *
 642 *      Power off UniFi.
 643 *
 644 *  Arguments:
 645 *      sdio            SDIO context pointer
 646 * ---------------------------------------------------------------------------
 647 */
 648void
 649CsrSdioPowerOff(CsrSdioFunction *function)
 650{
 651    struct sdio_func *func = (struct sdio_func *)function->priv;
 652    struct mmc_host *host = func->card->host;
 653
 654    _sdio_claim_host(func);
 655    if (card_is_powered) {
 656        mmc_power_save_host(host);
 657        card_is_powered = 0;
 658    } else {
 659        printk(KERN_INFO "SDIO: Skip power off; card is already powered off.\n");
 660    }
 661    _sdio_release_host(func);
 662} /* CsrSdioPowerOff() */
 663
 664
 665static int
 666sdio_set_block_size_ignore_first_error(struct sdio_func *func, unsigned blksz)
 667{
 668    int ret;
 669
 670    if (blksz > func->card->host->max_blk_size)
 671        return -EINVAL;
 672
 673    if (blksz == 0) {
 674        blksz = min(func->max_blksize, func->card->host->max_blk_size);
 675        blksz = min(blksz, 512u);
 676    }
 677
 678    /*
 679     * Ignore -ERANGE (OUT_OF_RANGE in R5) on the first byte as
 680     * the block size may be invalid until both bytes are written.
 681     */
 682    ret = csr_io_rw_direct(func->card, 1, 0,
 683                           SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
 684                           blksz & 0xff, NULL);
 685    if (ret && ret != -ERANGE)
 686        return ret;
 687    ret = csr_io_rw_direct(func->card, 1, 0,
 688                           SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
 689                           (blksz >> 8) & 0xff, NULL);
 690    if (ret)
 691        return ret;
 692    func->cur_blksize = blksz;
 693
 694    return 0;
 695}
 696
 697CsrResult
 698CsrSdioBlockSizeSet(CsrSdioFunction *function, u16 blockSize)
 699{
 700    struct sdio_func *func = (struct sdio_func *)function->priv;
 701    int r = 0;
 702
 703    /* Module parameter overrides */
 704    if (sdio_block_size > -1) {
 705        blockSize = sdio_block_size;
 706    }
 707
 708    unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n",
 709                blockSize);
 710
 711    _sdio_claim_host(func);
 712    r = sdio_set_block_size(func, blockSize);
 713    _sdio_release_host(func);
 714
 715    /*
 716     * The MMC driver for kernels prior to 2.6.32 may fail this request
 717     * with -ERANGE. In this case use our workaround.
 718     */
 719    if (r == -ERANGE) {
 720        _sdio_claim_host(func);
 721        r = sdio_set_block_size_ignore_first_error(func, blockSize);
 722        _sdio_release_host(func);
 723    }
 724    if (r) {
 725        unifi_error(NULL, "Error %d setting block size\n", r);
 726    }
 727
 728    /* Determine the achieved block size to pass to the core */
 729    function->blockSize = func->cur_blksize;
 730
 731    return ConvertSdioToCsrSdioResult(r);
 732} /* CsrSdioBlockSizeSet() */
 733
 734
 735/*
 736 * ---------------------------------------------------------------------------
 737 *  CsrSdioHardReset
 738 *
 739 *      Hard Resets UniFi is possible.
 740 *
 741 *  Arguments:
 742 *      sdio            SDIO context pointer
 743 * ---------------------------------------------------------------------------
 744 */
 745CsrResult
 746CsrSdioHardReset(CsrSdioFunction *function)
 747{
 748    return CSR_RESULT_FAILURE;
 749} /* CsrSdioHardReset() */
 750
 751
 752
 753/*
 754 * ---------------------------------------------------------------------------
 755 *  uf_glue_sdio_int_handler
 756 *
 757 *      Interrupt callback function for SDIO interrupts.
 758 *      This is called in kernel context (i.e. not interrupt context).
 759 *
 760 *  Arguments:
 761 *      func      SDIO context pointer
 762 *
 763 *  Returns:
 764 *      None.
 765 *
 766 *  Note: Called with host already claimed.
 767 * ---------------------------------------------------------------------------
 768 */
 769static void
 770uf_glue_sdio_int_handler(struct sdio_func *func)
 771{
 772    CsrSdioFunction *sdio_ctx;
 773    CsrSdioInterruptDsrCallback func_dsr_callback;
 774    int r;
 775
 776    sdio_ctx = sdio_get_drvdata(func);
 777    if (!sdio_ctx) {
 778        return;
 779    }
 780
 781#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
 782    /*
 783     * Normally, we are not allowed to do any SDIO commands here.
 784     * However, this is called in a thread context and with the SDIO lock
 785     * so we disable the interrupts here instead of trying to do complicated
 786     * things with the SDIO lock.
 787     */
 788#ifdef MMC_QUIRK_LENIENT_FN0
 789    sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &r);
 790#else
 791    r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
 792#endif
 793    if (r) {
 794        printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
 795    }
 796#endif
 797
 798    /* If the function driver has registered a handler, call it */
 799    if (sdio_func_drv && sdio_func_drv->intr) {
 800
 801        func_dsr_callback = sdio_func_drv->intr(sdio_ctx);
 802
 803        /* If interrupt handle returns a DSR handle, call it */
 804        if (func_dsr_callback) {
 805            func_dsr_callback(sdio_ctx);
 806        }
 807    }
 808
 809} /* uf_glue_sdio_int_handler() */
 810
 811
 812
 813/*
 814 * ---------------------------------------------------------------------------
 815 *  csr_sdio_linux_remove_irq
 816 *
 817 *      Unregister the interrupt handler.
 818 *      This means that the linux layer can not process interrupts any more.
 819 *
 820 *  Arguments:
 821 *      sdio      SDIO context pointer
 822 *
 823 *  Returns:
 824 *      Status of the removal.
 825 * ---------------------------------------------------------------------------
 826 */
 827int csr_sdio_linux_remove_irq(CsrSdioFunction *function)
 828{
 829        struct sdio_func *func = (struct sdio_func *)function->priv;
 830        int r;
 831
 832        unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n");
 833
 834        sdio_claim_host(func);
 835        r = sdio_release_irq(func);
 836        sdio_release_host(func);
 837
 838        return r;
 839
 840} /* csr_sdio_linux_remove_irq() */
 841
 842
 843/*
 844 * ---------------------------------------------------------------------------
 845 *  csr_sdio_linux_install_irq
 846 *
 847 *      Register the interrupt handler.
 848 *      This means that the linux layer can process interrupts.
 849 *
 850 *  Arguments:
 851 *      sdio      SDIO context pointer
 852 *
 853 *  Returns:
 854 *      Status of the removal.
 855 * ---------------------------------------------------------------------------
 856 */
 857int csr_sdio_linux_install_irq(CsrSdioFunction *function)
 858{
 859        struct sdio_func *func = (struct sdio_func *)function->priv;
 860        int r;
 861
 862        unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n");
 863
 864        /* Register our interrupt handle */
 865        sdio_claim_host(func);
 866        r = sdio_claim_irq(func, uf_glue_sdio_int_handler);
 867        sdio_release_host(func);
 868
 869        /* If the interrupt was installed earlier, is fine */
 870        if (r == -EBUSY)
 871                r = 0;
 872
 873        return r;
 874} /* csr_sdio_linux_install_irq() */
 875
 876#ifdef CONFIG_PM
 877
 878/*
 879 * Power Management notifier
 880 */
 881struct uf_sdio_mmc_pm_notifier
 882{
 883    struct list_head list;
 884
 885    CsrSdioFunction *sdio_ctx;
 886    struct notifier_block pm_notifier;
 887};
 888
 889/* PM notifier list head */
 890static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
 891    .sdio_ctx = NULL,
 892};
 893
 894/*
 895 * ---------------------------------------------------------------------------
 896 * uf_sdio_mmc_register_pm_notifier
 897 * uf_sdio_mmc_unregister_pm_notifier
 898 *
 899 *      Register/unregister for power management events. A list is used to
 900 *      allow multiple card instances to be supported.
 901 *
 902 *  Arguments:
 903 *      sdio_ctx - CSR SDIO context to associate PM notifier to
 904 *
 905 *  Returns:
 906 *      Register function returns NULL on error
 907 * ---------------------------------------------------------------------------
 908 */
 909static struct uf_sdio_mmc_pm_notifier *
 910uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx)
 911{
 912    /* Allocate notifier context for this card instance */
 913    struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL);
 914
 915    if (notifier_ctx)
 916    {
 917        notifier_ctx->sdio_ctx = sdio_ctx;
 918        notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
 919
 920        list_add(&notifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
 921
 922        if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
 923            printk(KERN_ERR "unifi: register_pm_notifier failed\n");
 924        }
 925    }
 926
 927    return notifier_ctx;
 928}
 929
 930static void
 931uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
 932{
 933    struct uf_sdio_mmc_pm_notifier *notifier_ctx;
 934    struct list_head *node, *q;
 935
 936    list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) {
 937        notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list);
 938
 939        /* If it matches, unregister and free the notifier context */
 940        if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
 941        {
 942            if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
 943                printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
 944            }
 945
 946            /* Remove from list */
 947            notifier_ctx->sdio_ctx = NULL;
 948            list_del(node);
 949            kfree(notifier_ctx);
 950        }
 951    }
 952}
 953
 954/*
 955 * ---------------------------------------------------------------------------
 956 * uf_sdio_mmc_power_event
 957 *
 958 *      Handler for power management events.
 959 *
 960 *      We need to handle suspend/resume events while the userspace is unsuspended
 961 *      to allow the SME to run its suspend/resume state machines.
 962 *
 963 *  Arguments:
 964 *      event   event ID
 965 *
 966 *  Returns:
 967 *      Status of the event handling
 968 * ---------------------------------------------------------------------------
 969 */
 970static int
 971uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr)
 972{
 973    struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this,
 974                                                                struct uf_sdio_mmc_pm_notifier,
 975                                                                pm_notifier);
 976
 977    /* Call the CSR SDIO function driver's suspend/resume method
 978     * while the userspace is unsuspended.
 979     */
 980    switch (event) {
 981        case PM_POST_HIBERNATION:
 982        case PM_POST_SUSPEND:
 983            printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
 984            if (sdio_func_drv && sdio_func_drv->resume) {
 985                sdio_func_drv->resume(notifier_ctx->sdio_ctx);
 986            }
 987            break;
 988
 989        case PM_HIBERNATION_PREPARE:
 990        case PM_SUSPEND_PREPARE:
 991            printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
 992            if (sdio_func_drv && sdio_func_drv->suspend) {
 993                sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
 994            }
 995            break;
 996    }
 997    return NOTIFY_DONE;
 998}
 999
1000#endif /* CONFIG_PM */
1001
1002/*
1003 * ---------------------------------------------------------------------------
1004 *  uf_glue_sdio_probe
1005 *
1006 *      Card insert callback.
1007 *
1008 * Arguments:
1009 *      func            Our (glue layer) context pointer.
1010 *
1011 * Returns:
1012 *      UniFi driver error code.
1013 * ---------------------------------------------------------------------------
1014 */
1015static int
1016uf_glue_sdio_probe(struct sdio_func *func,
1017                   const struct sdio_device_id *id)
1018{
1019    int instance;
1020    CsrSdioFunction *sdio_ctx;
1021
1022    /* First of all claim the SDIO driver */
1023    sdio_claim_host(func);
1024
1025    /* Assume that the card is already powered */
1026    card_is_powered = 1;
1027
1028    /* Assumes one card per host, which is true for SDIO */
1029    instance = func->card->host->index;
1030    printk("sdio bus_id: %16s - UniFi card 0x%X inserted\n",
1031           sdio_func_id(func), instance);
1032
1033    /* Allocate context */
1034    sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction),
1035                                          GFP_KERNEL);
1036    if (sdio_ctx == NULL) {
1037        sdio_release_host(func);
1038        return -ENOMEM;
1039    }
1040
1041    /* Initialise the context */
1042    sdio_ctx->sdioId.manfId  = func->vendor;
1043    sdio_ctx->sdioId.cardId  = func->device;
1044    sdio_ctx->sdioId.sdioFunction  = func->num;
1045    sdio_ctx->sdioId.sdioInterface = func->class;
1046    sdio_ctx->blockSize = func->cur_blksize;
1047    sdio_ctx->priv = (void *)func;
1048    sdio_ctx->features = 0;
1049
1050    /* Module parameter enables byte mode */
1051    if (sdio_byte_mode) {
1052        sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
1053    }
1054
1055    if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) {
1056        unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n");
1057    }
1058
1059#ifdef MMC_QUIRK_LENIENT_FN0
1060    func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1061#endif
1062
1063    /* Pass context to the SDIO driver */
1064    sdio_set_drvdata(func, sdio_ctx);
1065
1066#ifdef CONFIG_PM
1067    /* Register to get PM events */
1068    if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) {
1069        unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
1070    }
1071#endif
1072
1073    /* Register this device with the SDIO function driver */
1074    /* Call the main UniFi driver inserted handler */
1075    if (sdio_func_drv && sdio_func_drv->inserted) {
1076        uf_add_os_device(instance, &func->dev);
1077        sdio_func_drv->inserted(sdio_ctx);
1078    }
1079
1080    /* We have finished, so release the SDIO driver */
1081    sdio_release_host(func);
1082
1083#ifdef ANDROID_BUILD
1084    /* Take the wakelock */
1085    unifi_trace(NULL, UDBG1, "probe: take wake lock\n");
1086    wake_lock(&unifi_sdio_wake_lock);
1087#endif
1088
1089    return 0;
1090} /* uf_glue_sdio_probe() */
1091
1092
1093/*
1094 * ---------------------------------------------------------------------------
1095 *  uf_glue_sdio_remove
1096 *
1097 *      Card removal callback.
1098 *
1099 * Arguments:
1100 *      func            Our (glue layer) context pointer.
1101 *
1102 * Returns:
1103 *      UniFi driver error code.
1104 * ---------------------------------------------------------------------------
1105 */
1106static void
1107uf_glue_sdio_remove(struct sdio_func *func)
1108{
1109    CsrSdioFunction *sdio_ctx;
1110
1111    sdio_ctx = sdio_get_drvdata(func);
1112    if (!sdio_ctx) {
1113        return;
1114    }
1115
1116    unifi_info(NULL, "UniFi card removed\n");
1117
1118    /* Clean up the SDIO function driver */
1119    if (sdio_func_drv && sdio_func_drv->removed) {
1120        uf_remove_os_device(func->card->host->index);
1121        sdio_func_drv->removed(sdio_ctx);
1122    }
1123
1124#ifdef CONFIG_PM
1125    /* Unregister for PM events */
1126    uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
1127#endif
1128
1129    kfree(sdio_ctx);
1130
1131} /* uf_glue_sdio_remove */
1132
1133
1134/*
1135 * SDIO ids *must* be statically declared, so we can't take
1136 * them from the list passed in csr_sdio_register_driver().
1137 */
1138static const struct sdio_device_id unifi_ids[] = {
1139    { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_3) },
1140    { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_4) },
1141    { /* end: all zeroes */                             },
1142};
1143
1144MODULE_DEVICE_TABLE(sdio, unifi_ids);
1145
1146#ifdef CONFIG_PM
1147
1148/*
1149 * ---------------------------------------------------------------------------
1150 *  uf_glue_sdio_suspend
1151 *
1152 *      Card suspend callback. The userspace will already be suspended.
1153 *
1154 * Arguments:
1155 *      dev            The struct device owned by the MMC driver
1156 *
1157 * Returns:
1158 *      None
1159 * ---------------------------------------------------------------------------
1160 */
1161static int
1162uf_glue_sdio_suspend(struct device *dev)
1163{
1164    unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
1165
1166    return 0;
1167} /* uf_glue_sdio_suspend */
1168
1169
1170/*
1171 * ---------------------------------------------------------------------------
1172 *  uf_glue_sdio_resume
1173 *
1174 *      Card resume callback. The userspace will still be suspended.
1175 *
1176 * Arguments:
1177 *      dev            The struct device owned by the MMC driver
1178 *
1179 * Returns:
1180 *      None
1181 * ---------------------------------------------------------------------------
1182 */
1183static int
1184uf_glue_sdio_resume(struct device *dev)
1185{
1186    unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
1187
1188#ifdef ANDROID_BUILD
1189    unifi_trace(NULL, UDBG1, "resume: take wakelock\n");
1190    wake_lock(&unifi_sdio_wake_lock);
1191#endif
1192
1193    return 0;
1194
1195} /* uf_glue_sdio_resume */
1196
1197static struct dev_pm_ops unifi_pm_ops = {
1198    .suspend = uf_glue_sdio_suspend,
1199    .resume  = uf_glue_sdio_resume,
1200};
1201
1202#define UNIFI_PM_OPS  (&unifi_pm_ops)
1203
1204#else
1205
1206#define UNIFI_PM_OPS  NULL
1207
1208#endif /* CONFIG_PM */
1209
1210static struct sdio_driver unifi_driver = {
1211    .probe      = uf_glue_sdio_probe,
1212    .remove     = uf_glue_sdio_remove,
1213    .name       = "unifi",
1214    .id_table   = unifi_ids,
1215    .drv.pm     = UNIFI_PM_OPS,
1216};
1217
1218
1219/*
1220 * ---------------------------------------------------------------------------
1221 *  CsrSdioFunctionDriverRegister
1222 *  CsrSdioFunctionDriverUnregister
1223 *
1224 *      These functions are called from the main module load and unload
1225 *      functions. They perform the appropriate operations for the
1226 *      linux MMC/SDIO driver.
1227 *
1228 *  Arguments:
1229 *      sdio_drv    Pointer to the function driver's SDIO structure.
1230 *
1231 *  Returns:
1232 *      None.
1233 * ---------------------------------------------------------------------------
1234 */
1235CsrResult
1236CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
1237{
1238    int r;
1239
1240    printk("UniFi: Using native Linux MMC driver for SDIO.\n");
1241
1242    if (sdio_func_drv) {
1243        unifi_error(NULL, "sdio_mmc: UniFi driver already registered\n");
1244        return CSR_SDIO_RESULT_INVALID_VALUE;
1245    }
1246
1247#ifdef ANDROID_BUILD
1248    wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
1249#endif
1250
1251    /* Save the registered driver description */
1252    /*
1253     * FIXME:
1254     * Need a table here to handle a call to register for just one function.
1255     * mmc only allows us to register for the whole device
1256     */
1257    sdio_func_drv = sdio_drv;
1258
1259#ifdef CONFIG_PM
1260    /* Initialise PM notifier list */
1261    INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
1262#endif
1263
1264    /* Register ourself with mmc_core */
1265    r = sdio_register_driver(&unifi_driver);
1266    if (r) {
1267        printk(KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r);
1268        return ConvertSdioToCsrSdioResult(r);
1269    }
1270
1271    return CSR_RESULT_SUCCESS;
1272} /* CsrSdioFunctionDriverRegister() */
1273
1274
1275
1276void
1277CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
1278{
1279    printk(KERN_INFO "UniFi: unregister from MMC sdio\n");
1280
1281#ifdef ANDROID_BUILD
1282    wake_lock_destroy(&unifi_sdio_wake_lock);
1283#endif
1284    sdio_unregister_driver(&unifi_driver);
1285
1286    sdio_func_drv = NULL;
1287
1288} /* CsrSdioFunctionDriverUnregister() */
1289
1290
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.