linux/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Broadcom Corporation
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16/* ****************** SDIO CARD Interface Functions **************************/
  17
  18#include <linux/types.h>
  19#include <linux/netdevice.h>
  20#include <linux/pci.h>
  21#include <linux/pci_ids.h>
  22#include <linux/sched.h>
  23#include <linux/completion.h>
  24#include <linux/scatterlist.h>
  25#include <linux/mmc/sdio.h>
  26#include <linux/mmc/core.h>
  27#include <linux/mmc/sdio_func.h>
  28#include <linux/mmc/card.h>
  29#include <linux/mmc/host.h>
  30#include <linux/platform_device.h>
  31#include <linux/platform_data/brcmfmac-sdio.h>
  32#include <linux/suspend.h>
  33#include <linux/errno.h>
  34#include <linux/module.h>
  35#include <net/cfg80211.h>
  36
  37#include <defs.h>
  38#include <brcm_hw_ids.h>
  39#include <brcmu_utils.h>
  40#include <brcmu_wifi.h>
  41#include <chipcommon.h>
  42#include <soc.h>
  43#include "chip.h"
  44#include "bus.h"
  45#include "debug.h"
  46#include "sdio.h"
  47#include "of.h"
  48
  49#define SDIOH_API_ACCESS_RETRY_LIMIT    2
  50
  51#define DMA_ALIGN_MASK  0x03
  52
  53#define SDIO_FUNC1_BLOCKSIZE            64
  54#define SDIO_FUNC2_BLOCKSIZE            512
  55/* Maximum milliseconds to wait for F2 to come up */
  56#define SDIO_WAIT_F2RDY 3000
  57
  58#define BRCMF_DEFAULT_TXGLOM_SIZE       32  /* max tx frames in glom chain */
  59#define BRCMF_DEFAULT_RXGLOM_SIZE       32  /* max rx frames in glom chain */
  60
  61static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  62module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
  63MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  64
  65static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
  66{
  67        struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
  68        struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  69
  70        brcmf_dbg(INTR, "OOB intr triggered\n");
  71
  72        /* out-of-band interrupt is level-triggered which won't
  73         * be cleared until dpc
  74         */
  75        if (sdiodev->irq_en) {
  76                disable_irq_nosync(irq);
  77                sdiodev->irq_en = false;
  78        }
  79
  80        brcmf_sdio_isr(sdiodev->bus);
  81
  82        return IRQ_HANDLED;
  83}
  84
  85static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func)
  86{
  87        struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
  88        struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  89
  90        brcmf_dbg(INTR, "IB intr triggered\n");
  91
  92        brcmf_sdio_isr(sdiodev->bus);
  93}
  94
  95/* dummy handler for SDIO function 2 interrupt */
  96static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)
  97{
  98}
  99
 100static bool brcmf_sdiod_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
 101{
 102        bool is_err = false;
 103#ifdef CONFIG_PM_SLEEP
 104        is_err = atomic_read(&sdiodev->suspend);
 105#endif
 106        return is_err;
 107}
 108
 109static void brcmf_sdiod_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
 110                                       wait_queue_head_t *wq)
 111{
 112#ifdef CONFIG_PM_SLEEP
 113        int retry = 0;
 114        while (atomic_read(&sdiodev->suspend) && retry++ != 30)
 115                wait_event_timeout(*wq, false, HZ/100);
 116#endif
 117}
 118
 119int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 120{
 121        int ret = 0;
 122        u8 data;
 123        u32 addr, gpiocontrol;
 124        unsigned long flags;
 125
 126        if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
 127                brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
 128                          sdiodev->pdata->oob_irq_nr);
 129                ret = request_irq(sdiodev->pdata->oob_irq_nr,
 130                                  brcmf_sdiod_oob_irqhandler,
 131                                  sdiodev->pdata->oob_irq_flags,
 132                                  "brcmf_oob_intr",
 133                                  &sdiodev->func[1]->dev);
 134                if (ret != 0) {
 135                        brcmf_err("request_irq failed %d\n", ret);
 136                        return ret;
 137                }
 138                sdiodev->oob_irq_requested = true;
 139                spin_lock_init(&sdiodev->irq_en_lock);
 140                spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
 141                sdiodev->irq_en = true;
 142                spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
 143
 144                ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr);
 145                if (ret != 0) {
 146                        brcmf_err("enable_irq_wake failed %d\n", ret);
 147                        return ret;
 148                }
 149                sdiodev->irq_wake = true;
 150
 151                sdio_claim_host(sdiodev->func[1]);
 152
 153                if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
 154                        /* assign GPIO to SDIO core */
 155                        addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
 156                        gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
 157                        gpiocontrol |= 0x2;
 158                        brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
 159
 160                        brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
 161                                          &ret);
 162                        brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
 163                        brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
 164                }
 165
 166                /* must configure SDIO_CCCR_IENx to enable irq */
 167                data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
 168                data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
 169                brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
 170
 171                /* redirect, configure and enable io for interrupt signal */
 172                data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
 173                if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
 174                        data |= SDIO_SEPINT_ACT_HI;
 175                brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
 176
 177                sdio_release_host(sdiodev->func[1]);
 178        } else {
 179                brcmf_dbg(SDIO, "Entering\n");
 180                sdio_claim_host(sdiodev->func[1]);
 181                sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
 182                sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
 183                sdio_release_host(sdiodev->func[1]);
 184        }
 185
 186        return 0;
 187}
 188
 189int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 190{
 191        brcmf_dbg(SDIO, "Entering\n");
 192
 193        if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
 194                sdio_claim_host(sdiodev->func[1]);
 195                brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
 196                brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
 197                sdio_release_host(sdiodev->func[1]);
 198
 199                if (sdiodev->oob_irq_requested) {
 200                        sdiodev->oob_irq_requested = false;
 201                        if (sdiodev->irq_wake) {
 202                                disable_irq_wake(sdiodev->pdata->oob_irq_nr);
 203                                sdiodev->irq_wake = false;
 204                        }
 205                        free_irq(sdiodev->pdata->oob_irq_nr,
 206                                 &sdiodev->func[1]->dev);
 207                        sdiodev->irq_en = false;
 208                }
 209        } else {
 210                sdio_claim_host(sdiodev->func[1]);
 211                sdio_release_irq(sdiodev->func[2]);
 212                sdio_release_irq(sdiodev->func[1]);
 213                sdio_release_host(sdiodev->func[1]);
 214        }
 215
 216        return 0;
 217}
 218
 219static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
 220                                        uint regaddr, u8 byte)
 221{
 222        int err_ret;
 223
 224        /*
 225         * Can only directly write to some F0 registers.
 226         * Handle CCCR_IENx and CCCR_ABORT command
 227         * as a special case.
 228         */
 229        if ((regaddr == SDIO_CCCR_ABORT) ||
 230            (regaddr == SDIO_CCCR_IENx))
 231                sdio_writeb(func, byte, regaddr, &err_ret);
 232        else
 233                sdio_f0_writeb(func, byte, regaddr, &err_ret);
 234
 235        return err_ret;
 236}
 237
 238static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
 239                                    u32 addr, u8 regsz, void *data, bool write)
 240{
 241        struct sdio_func *func;
 242        int ret;
 243
 244        brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
 245                  write, fn, addr, regsz);
 246
 247        brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
 248        if (brcmf_sdiod_pm_resume_error(sdiodev))
 249                return -EIO;
 250
 251        /* only allow byte access on F0 */
 252        if (WARN_ON(regsz > 1 && !fn))
 253                return -EINVAL;
 254        func = sdiodev->func[fn];
 255
 256        switch (regsz) {
 257        case sizeof(u8):
 258                if (write) {
 259                        if (fn)
 260                                sdio_writeb(func, *(u8 *)data, addr, &ret);
 261                        else
 262                                ret = brcmf_sdiod_f0_writeb(func, addr,
 263                                                            *(u8 *)data);
 264                } else {
 265                        if (fn)
 266                                *(u8 *)data = sdio_readb(func, addr, &ret);
 267                        else
 268                                *(u8 *)data = sdio_f0_readb(func, addr, &ret);
 269                }
 270                break;
 271        case sizeof(u16):
 272                if (write)
 273                        sdio_writew(func, *(u16 *)data, addr, &ret);
 274                else
 275                        *(u16 *)data = sdio_readw(func, addr, &ret);
 276                break;
 277        case sizeof(u32):
 278                if (write)
 279                        sdio_writel(func, *(u32 *)data, addr, &ret);
 280                else
 281                        *(u32 *)data = sdio_readl(func, addr, &ret);
 282                break;
 283        default:
 284                brcmf_err("invalid size: %d\n", regsz);
 285                break;
 286        }
 287
 288        if (ret)
 289                brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
 290                          write ? "write" : "read", fn, addr, ret);
 291
 292        return ret;
 293}
 294
 295static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
 296                                   u8 regsz, void *data, bool write)
 297{
 298        u8 func;
 299        s32 retry = 0;
 300        int ret;
 301
 302        if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
 303                return -ENOMEDIUM;
 304
 305        /*
 306         * figure out how to read the register based on address range
 307         * 0x00 ~ 0x7FF: function 0 CCCR and FBR
 308         * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
 309         * The rest: function 1 silicon backplane core registers
 310         */
 311        if ((addr & ~REG_F0_REG_MASK) == 0)
 312                func = SDIO_FUNC_0;
 313        else
 314                func = SDIO_FUNC_1;
 315
 316        do {
 317                if (!write)
 318                        memset(data, 0, regsz);
 319                /* for retry wait for 1 ms till bus get settled down */
 320                if (retry)
 321                        usleep_range(1000, 2000);
 322                ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
 323                                               data, write);
 324        } while (ret != 0 && ret != -ENOMEDIUM &&
 325                 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 326
 327        if (ret == -ENOMEDIUM)
 328                brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
 329        else if (ret != 0) {
 330                /*
 331                 * SleepCSR register access can fail when
 332                 * waking up the device so reduce this noise
 333                 * in the logs.
 334                 */
 335                if (addr != SBSDIO_FUNC1_SLEEPCSR)
 336                        brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
 337                                  write ? "write" : "read", func, addr, ret);
 338                else
 339                        brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
 340                                  write ? "write" : "read", func, addr, ret);
 341        }
 342        return ret;
 343}
 344
 345static int
 346brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 347{
 348        int err = 0, i;
 349        u8 addr[3];
 350
 351        if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
 352                return -ENOMEDIUM;
 353
 354        addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
 355        addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
 356        addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
 357
 358        for (i = 0; i < 3; i++) {
 359                err = brcmf_sdiod_regrw_helper(sdiodev,
 360                                               SBSDIO_FUNC1_SBADDRLOW + i,
 361                                               sizeof(u8), &addr[i], true);
 362                if (err) {
 363                        brcmf_err("failed at addr: 0x%0x\n",
 364                                  SBSDIO_FUNC1_SBADDRLOW + i);
 365                        break;
 366                }
 367        }
 368
 369        return err;
 370}
 371
 372static int
 373brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
 374{
 375        uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 376        int err = 0;
 377
 378        if (bar0 != sdiodev->sbwad) {
 379                err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
 380                if (err)
 381                        return err;
 382
 383                sdiodev->sbwad = bar0;
 384        }
 385
 386        *addr &= SBSDIO_SB_OFT_ADDR_MASK;
 387
 388        if (width == 4)
 389                *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 390
 391        return 0;
 392}
 393
 394u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 395{
 396        u8 data;
 397        int retval;
 398
 399        brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
 400        retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
 401                                          false);
 402        brcmf_dbg(SDIO, "data:0x%02x\n", data);
 403
 404        if (ret)
 405                *ret = retval;
 406
 407        return data;
 408}
 409
 410u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 411{
 412        u32 data;
 413        int retval;
 414
 415        brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
 416        retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
 417        if (retval)
 418                goto done;
 419        retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
 420                                          false);
 421        brcmf_dbg(SDIO, "data:0x%08x\n", data);
 422
 423done:
 424        if (ret)
 425                *ret = retval;
 426
 427        return data;
 428}
 429
 430void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
 431                      u8 data, int *ret)
 432{
 433        int retval;
 434
 435        brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
 436        retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
 437                                          true);
 438        if (ret)
 439                *ret = retval;
 440}
 441
 442void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 443                      u32 data, int *ret)
 444{
 445        int retval;
 446
 447        brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
 448        retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
 449        if (retval)
 450                goto done;
 451        retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
 452                                          true);
 453
 454done:
 455        if (ret)
 456                *ret = retval;
 457}
 458
 459static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 460                             bool write, u32 addr, struct sk_buff *pkt)
 461{
 462        unsigned int req_sz;
 463        int err;
 464
 465        brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
 466        if (brcmf_sdiod_pm_resume_error(sdiodev))
 467                return -EIO;
 468
 469        /* Single skb use the standard mmc interface */
 470        req_sz = pkt->len + 3;
 471        req_sz &= (uint)~3;
 472
 473        if (write)
 474                err = sdio_memcpy_toio(sdiodev->func[fn], addr,
 475                                       ((u8 *)(pkt->data)), req_sz);
 476        else if (fn == 1)
 477                err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
 478                                         addr, req_sz);
 479        else
 480                /* function 2 read is FIFO operation */
 481                err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
 482                                  req_sz);
 483        if (err == -ENOMEDIUM)
 484                brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
 485        return err;
 486}
 487
 488/**
 489 * brcmf_sdiod_sglist_rw - SDIO interface function for block data access
 490 * @sdiodev: brcmfmac sdio device
 491 * @fn: SDIO function number
 492 * @write: direction flag
 493 * @addr: dongle memory address as source/destination
 494 * @pkt: skb pointer
 495 *
 496 * This function takes the respbonsibility as the interface function to MMC
 497 * stack for block data access. It assumes that the skb passed down by the
 498 * caller has already been padded and aligned.
 499 */
 500static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
 501                                 bool write, u32 addr,
 502                                 struct sk_buff_head *pktlist)
 503{
 504        unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
 505        unsigned int max_req_sz, orig_offset, dst_offset;
 506        unsigned short max_seg_cnt, seg_sz;
 507        unsigned char *pkt_data, *orig_data, *dst_data;
 508        struct sk_buff *pkt_next = NULL, *local_pkt_next;
 509        struct sk_buff_head local_list, *target_list;
 510        struct mmc_request mmc_req;
 511        struct mmc_command mmc_cmd;
 512        struct mmc_data mmc_dat;
 513        struct scatterlist *sgl;
 514        int ret = 0;
 515
 516        if (!pktlist->qlen)
 517                return -EINVAL;
 518
 519        brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
 520        if (brcmf_sdiod_pm_resume_error(sdiodev))
 521                return -EIO;
 522
 523        target_list = pktlist;
 524        /* for host with broken sg support, prepare a page aligned list */
 525        __skb_queue_head_init(&local_list);
 526        if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
 527                req_sz = 0;
 528                skb_queue_walk(pktlist, pkt_next)
 529                        req_sz += pkt_next->len;
 530                req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
 531                while (req_sz > PAGE_SIZE) {
 532                        pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
 533                        if (pkt_next == NULL) {
 534                                ret = -ENOMEM;
 535                                goto exit;
 536                        }
 537                        __skb_queue_tail(&local_list, pkt_next);
 538                        req_sz -= PAGE_SIZE;
 539                }
 540                pkt_next = brcmu_pkt_buf_get_skb(req_sz);
 541                if (pkt_next == NULL) {
 542                        ret = -ENOMEM;
 543                        goto exit;
 544                }
 545                __skb_queue_tail(&local_list, pkt_next);
 546                target_list = &local_list;
 547        }
 548
 549        func_blk_sz = sdiodev->func[fn]->cur_blksize;
 550        max_req_sz = sdiodev->max_request_size;
 551        max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
 552                            target_list->qlen);
 553        seg_sz = target_list->qlen;
 554        pkt_offset = 0;
 555        pkt_next = target_list->next;
 556
 557        memset(&mmc_req, 0, sizeof(struct mmc_request));
 558        memset(&mmc_cmd, 0, sizeof(struct mmc_command));
 559        memset(&mmc_dat, 0, sizeof(struct mmc_data));
 560
 561        mmc_dat.sg = sdiodev->sgtable.sgl;
 562        mmc_dat.blksz = func_blk_sz;
 563        mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
 564        mmc_cmd.opcode = SD_IO_RW_EXTENDED;
 565        mmc_cmd.arg = write ? 1<<31 : 0;        /* write flag  */
 566        mmc_cmd.arg |= (fn & 0x7) << 28;        /* SDIO func num */
 567        mmc_cmd.arg |= 1<<27;                   /* block mode */
 568        /* for function 1 the addr will be incremented */
 569        mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
 570        mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
 571        mmc_req.cmd = &mmc_cmd;
 572        mmc_req.data = &mmc_dat;
 573
 574        while (seg_sz) {
 575                req_sz = 0;
 576                sg_cnt = 0;
 577                sgl = sdiodev->sgtable.sgl;
 578                /* prep sg table */
 579                while (pkt_next != (struct sk_buff *)target_list) {
 580                        pkt_data = pkt_next->data + pkt_offset;
 581                        sg_data_sz = pkt_next->len - pkt_offset;
 582                        if (sg_data_sz > sdiodev->max_segment_size)
 583                                sg_data_sz = sdiodev->max_segment_size;
 584                        if (sg_data_sz > max_req_sz - req_sz)
 585                                sg_data_sz = max_req_sz - req_sz;
 586
 587                        sg_set_buf(sgl, pkt_data, sg_data_sz);
 588
 589                        sg_cnt++;
 590                        sgl = sg_next(sgl);
 591                        req_sz += sg_data_sz;
 592                        pkt_offset += sg_data_sz;
 593                        if (pkt_offset == pkt_next->len) {
 594                                pkt_offset = 0;
 595                                pkt_next = pkt_next->next;
 596                        }
 597
 598                        if (req_sz >= max_req_sz || sg_cnt >= max_seg_cnt)
 599                                break;
 600                }
 601                seg_sz -= sg_cnt;
 602
 603                if (req_sz % func_blk_sz != 0) {
 604                        brcmf_err("sg request length %u is not %u aligned\n",
 605                                  req_sz, func_blk_sz);
 606                        ret = -ENOTBLK;
 607                        goto exit;
 608                }
 609
 610                mmc_dat.sg_len = sg_cnt;
 611                mmc_dat.blocks = req_sz / func_blk_sz;
 612                mmc_cmd.arg |= (addr & 0x1FFFF) << 9;   /* address */
 613                mmc_cmd.arg |= mmc_dat.blocks & 0x1FF;  /* block count */
 614                /* incrementing addr for function 1 */
 615                if (fn == 1)
 616                        addr += req_sz;
 617
 618                mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
 619                mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
 620
 621                ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
 622                if (ret == -ENOMEDIUM) {
 623                        brcmf_bus_change_state(sdiodev->bus_if,
 624                                               BRCMF_BUS_NOMEDIUM);
 625                        break;
 626                } else if (ret != 0) {
 627                        brcmf_err("CMD53 sg block %s failed %d\n",
 628                                  write ? "write" : "read", ret);
 629                        ret = -EIO;
 630                        break;
 631                }
 632        }
 633
 634        if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
 635                local_pkt_next = local_list.next;
 636                orig_offset = 0;
 637                skb_queue_walk(pktlist, pkt_next) {
 638                        dst_offset = 0;
 639                        do {
 640                                req_sz = local_pkt_next->len - orig_offset;
 641                                req_sz = min_t(uint, pkt_next->len - dst_offset,
 642                                               req_sz);
 643                                orig_data = local_pkt_next->data + orig_offset;
 644                                dst_data = pkt_next->data + dst_offset;
 645                                memcpy(dst_data, orig_data, req_sz);
 646                                orig_offset += req_sz;
 647                                dst_offset += req_sz;
 648                                if (orig_offset == local_pkt_next->len) {
 649                                        orig_offset = 0;
 650                                        local_pkt_next = local_pkt_next->next;
 651                                }
 652                                if (dst_offset == pkt_next->len)
 653                                        break;
 654                        } while (!skb_queue_empty(&local_list));
 655                }
 656        }
 657
 658exit:
 659        sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
 660        while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
 661                brcmu_pkt_buf_free_skb(pkt_next);
 662
 663        return ret;
 664}
 665
 666int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
 667{
 668        struct sk_buff *mypkt;
 669        int err;
 670
 671        mypkt = brcmu_pkt_buf_get_skb(nbytes);
 672        if (!mypkt) {
 673                brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
 674                          nbytes);
 675                return -EIO;
 676        }
 677
 678        err = brcmf_sdiod_recv_pkt(sdiodev, mypkt);
 679        if (!err)
 680                memcpy(buf, mypkt->data, nbytes);
 681
 682        brcmu_pkt_buf_free_skb(mypkt);
 683        return err;
 684}
 685
 686int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
 687{
 688        u32 addr = sdiodev->sbwad;
 689        int err = 0;
 690
 691        brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
 692
 693        err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
 694        if (err)
 695                goto done;
 696
 697        err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt);
 698
 699done:
 700        return err;
 701}
 702
 703int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
 704                           struct sk_buff_head *pktq, uint totlen)
 705{
 706        struct sk_buff *glom_skb;
 707        struct sk_buff *skb;
 708        u32 addr = sdiodev->sbwad;
 709        int err = 0;
 710
 711        brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
 712                  addr, pktq->qlen);
 713
 714        err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
 715        if (err)
 716                goto done;
 717
 718        if (pktq->qlen == 1)
 719                err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
 720                                         pktq->next);
 721        else if (!sdiodev->sg_support) {
 722                glom_skb = brcmu_pkt_buf_get_skb(totlen);
 723                if (!glom_skb)
 724                        return -ENOMEM;
 725                err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
 726                                         glom_skb);
 727                if (err)
 728                        goto done;
 729
 730                skb_queue_walk(pktq, skb) {
 731                        memcpy(skb->data, glom_skb->data, skb->len);
 732                        skb_pull(glom_skb, skb->len);
 733                }
 734        } else
 735                err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,
 736                                            pktq);
 737
 738done:
 739        return err;
 740}
 741
 742int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
 743{
 744        struct sk_buff *mypkt;
 745        u32 addr = sdiodev->sbwad;
 746        int err;
 747
 748        mypkt = brcmu_pkt_buf_get_skb(nbytes);
 749        if (!mypkt) {
 750                brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
 751                          nbytes);
 752                return -EIO;
 753        }
 754
 755        memcpy(mypkt->data, buf, nbytes);
 756
 757        err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
 758
 759        if (!err)
 760                err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
 761                                         mypkt);
 762
 763        brcmu_pkt_buf_free_skb(mypkt);
 764        return err;
 765
 766}
 767
 768int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 769                         struct sk_buff_head *pktq)
 770{
 771        struct sk_buff *skb;
 772        u32 addr = sdiodev->sbwad;
 773        int err;
 774
 775        brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
 776
 777        err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
 778        if (err)
 779                return err;
 780
 781        if (pktq->qlen == 1 || !sdiodev->sg_support)
 782                skb_queue_walk(pktq, skb) {
 783                        err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true,
 784                                                 addr, skb);
 785                        if (err)
 786                                break;
 787                }
 788        else
 789                err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
 790                                            pktq);
 791
 792        return err;
 793}
 794
 795int
 796brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 797                  u8 *data, uint size)
 798{
 799        int bcmerror = 0;
 800        struct sk_buff *pkt;
 801        u32 sdaddr;
 802        uint dsize;
 803
 804        dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
 805        pkt = dev_alloc_skb(dsize);
 806        if (!pkt) {
 807                brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
 808                return -EIO;
 809        }
 810        pkt->priority = 0;
 811
 812        /* Determine initial transfer parameters */
 813        sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
 814        if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
 815                dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
 816        else
 817                dsize = size;
 818
 819        sdio_claim_host(sdiodev->func[1]);
 820
 821        /* Do the transfer(s) */
 822        while (size) {
 823                /* Set the backplane window to include the start address */
 824                bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
 825                if (bcmerror)
 826                        break;
 827
 828                brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
 829                          write ? "write" : "read", dsize,
 830                          sdaddr, address & SBSDIO_SBWINDOW_MASK);
 831
 832                sdaddr &= SBSDIO_SB_OFT_ADDR_MASK;
 833                sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 834
 835                skb_put(pkt, dsize);
 836                if (write)
 837                        memcpy(pkt->data, data, dsize);
 838                bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
 839                                              sdaddr, pkt);
 840                if (bcmerror) {
 841                        brcmf_err("membytes transfer failed\n");
 842                        break;
 843                }
 844                if (!write)
 845                        memcpy(data, pkt->data, dsize);
 846                skb_trim(pkt, 0);
 847
 848                /* Adjust for next transfer (if any) */
 849                size -= dsize;
 850                if (size) {
 851                        data += dsize;
 852                        address += dsize;
 853                        sdaddr = 0;
 854                        dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
 855                }
 856        }
 857
 858        dev_kfree_skb(pkt);
 859
 860        /* Return the window to backplane enumeration space for core access */
 861        if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad))
 862                brcmf_err("FAILED to set window back to 0x%x\n",
 863                          sdiodev->sbwad);
 864
 865        sdio_release_host(sdiodev->func[1]);
 866
 867        return bcmerror;
 868}
 869
 870int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
 871{
 872        char t_func = (char)fn;
 873        brcmf_dbg(SDIO, "Enter\n");
 874
 875        /* issue abort cmd52 command through F0 */
 876        brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
 877                                 sizeof(t_func), &t_func, true);
 878
 879        brcmf_dbg(SDIO, "Exit\n");
 880        return 0;
 881}
 882
 883static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
 884{
 885        uint nents;
 886        int err;
 887
 888        if (!sdiodev->sg_support)
 889                return;
 890
 891        nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
 892        nents += (nents >> 4) + 1;
 893
 894        WARN_ON(nents > sdiodev->max_segment_count);
 895
 896        brcmf_dbg(TRACE, "nents=%d\n", nents);
 897        err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
 898        if (err < 0) {
 899                brcmf_err("allocation failed: disable scatter-gather");
 900                sdiodev->sg_support = false;
 901        }
 902
 903        sdiodev->txglomsz = brcmf_sdiod_txglomsz;
 904}
 905
 906static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
 907{
 908        if (sdiodev->bus) {
 909                brcmf_sdio_remove(sdiodev->bus);
 910                sdiodev->bus = NULL;
 911        }
 912
 913        /* Disable Function 2 */
 914        sdio_claim_host(sdiodev->func[2]);
 915        sdio_disable_func(sdiodev->func[2]);
 916        sdio_release_host(sdiodev->func[2]);
 917
 918        /* Disable Function 1 */
 919        sdio_claim_host(sdiodev->func[1]);
 920        sdio_disable_func(sdiodev->func[1]);
 921        sdio_release_host(sdiodev->func[1]);
 922
 923        sg_free_table(&sdiodev->sgtable);
 924        sdiodev->sbwad = 0;
 925
 926        return 0;
 927}
 928
 929static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
 930{
 931        struct sdio_func *func;
 932        struct mmc_host *host;
 933        uint max_blocks;
 934        int ret = 0;
 935
 936        sdiodev->num_funcs = 2;
 937
 938        sdio_claim_host(sdiodev->func[1]);
 939
 940        ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
 941        if (ret) {
 942                brcmf_err("Failed to set F1 blocksize\n");
 943                sdio_release_host(sdiodev->func[1]);
 944                goto out;
 945        }
 946        ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
 947        if (ret) {
 948                brcmf_err("Failed to set F2 blocksize\n");
 949                sdio_release_host(sdiodev->func[1]);
 950                goto out;
 951        }
 952
 953        /* increase F2 timeout */
 954        sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY;
 955
 956        /* Enable Function 1 */
 957        ret = sdio_enable_func(sdiodev->func[1]);
 958        sdio_release_host(sdiodev->func[1]);
 959        if (ret) {
 960                brcmf_err("Failed to enable F1: err=%d\n", ret);
 961                goto out;
 962        }
 963
 964        /*
 965         * determine host related variables after brcmf_sdiod_probe()
 966         * as func->cur_blksize is properly set and F2 init has been
 967         * completed successfully.
 968         */
 969        func = sdiodev->func[2];
 970        host = func->card->host;
 971        sdiodev->sg_support = host->max_segs > 1;
 972        max_blocks = min_t(uint, host->max_blk_count, 511u);
 973        sdiodev->max_request_size = min_t(uint, host->max_req_size,
 974                                          max_blocks * func->cur_blksize);
 975        sdiodev->max_segment_count = min_t(uint, host->max_segs,
 976                                           SG_MAX_SINGLE_ALLOC);
 977        sdiodev->max_segment_size = host->max_seg_size;
 978
 979        /* allocate scatter-gather table. sg support
 980         * will be disabled upon allocation failure.
 981         */
 982        brcmf_sdiod_sgtable_alloc(sdiodev);
 983
 984        /* try to attach to the target device */
 985        sdiodev->bus = brcmf_sdio_probe(sdiodev);
 986        if (!sdiodev->bus) {
 987                ret = -ENODEV;
 988                goto out;
 989        }
 990
 991out:
 992        if (ret)
 993                brcmf_sdiod_remove(sdiodev);
 994
 995        return ret;
 996}
 997
 998#define BRCMF_SDIO_DEVICE(dev_id)       \
 999        {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)}
1000
1001/* devices we support, null terminated */
1002static const struct sdio_device_id brcmf_sdmmc_ids[] = {
1003        BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID),
1004        BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID),
1005        BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID),
1006        BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID),
1007        BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID),
1008        BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID),
1009        BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID),
1010        BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID),
1011        { /* end: all zeroes */ }
1012};
1013MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
1014
1015static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
1016
1017
1018static int brcmf_ops_sdio_probe(struct sdio_func *func,
1019                                const struct sdio_device_id *id)
1020{
1021        int err;
1022        struct brcmf_sdio_dev *sdiodev;
1023        struct brcmf_bus *bus_if;
1024
1025        brcmf_dbg(SDIO, "Enter\n");
1026        brcmf_dbg(SDIO, "Class=%x\n", func->class);
1027        brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
1028        brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1029        brcmf_dbg(SDIO, "Function#: %d\n", func->num);
1030
1031        /* Consume func num 1 but dont do anything with it. */
1032        if (func->num == 1)
1033                return 0;
1034
1035        /* Ignore anything but func 2 */
1036        if (func->num != 2)
1037                return -ENODEV;
1038
1039        bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
1040        if (!bus_if)
1041                return -ENOMEM;
1042        sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
1043        if (!sdiodev) {
1044                kfree(bus_if);
1045                return -ENOMEM;
1046        }
1047
1048        /* store refs to functions used. mmc_card does
1049         * not hold the F0 function pointer.
1050         */
1051        sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
1052        sdiodev->func[0]->num = 0;
1053        sdiodev->func[1] = func->card->sdio_func[0];
1054        sdiodev->func[2] = func;
1055
1056        sdiodev->bus_if = bus_if;
1057        bus_if->bus_priv.sdio = sdiodev;
1058        bus_if->proto_type = BRCMF_PROTO_BCDC;
1059        dev_set_drvdata(&func->dev, bus_if);
1060        dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
1061        sdiodev->dev = &sdiodev->func[1]->dev;
1062        sdiodev->pdata = brcmfmac_sdio_pdata;
1063
1064        if (!sdiodev->pdata)
1065                brcmf_of_probe(sdiodev);
1066
1067#ifdef CONFIG_PM_SLEEP
1068        /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
1069         * is true or when platform data OOB irq is true).
1070         */
1071        if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
1072            ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
1073             (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
1074                bus_if->wowl_supported = true;
1075#endif
1076
1077        atomic_set(&sdiodev->suspend, false);
1078        init_waitqueue_head(&sdiodev->request_word_wait);
1079        init_waitqueue_head(&sdiodev->request_buffer_wait);
1080
1081        brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1082        err = brcmf_sdiod_probe(sdiodev);
1083        if (err) {
1084                brcmf_err("F2 error, probe failed %d...\n", err);
1085                goto fail;
1086        }
1087
1088        brcmf_dbg(SDIO, "F2 init completed...\n");
1089        return 0;
1090
1091fail:
1092        dev_set_drvdata(&func->dev, NULL);
1093        dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
1094        kfree(sdiodev->func[0]);
1095        kfree(sdiodev);
1096        kfree(bus_if);
1097        return err;
1098}
1099
1100static void brcmf_ops_sdio_remove(struct sdio_func *func)
1101{
1102        struct brcmf_bus *bus_if;
1103        struct brcmf_sdio_dev *sdiodev;
1104
1105        brcmf_dbg(SDIO, "Enter\n");
1106        brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
1107        brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1108        brcmf_dbg(SDIO, "Function: %d\n", func->num);
1109
1110        if (func->num != 1 && func->num != 2)
1111                return;
1112
1113        bus_if = dev_get_drvdata(&func->dev);
1114        if (bus_if) {
1115                sdiodev = bus_if->bus_priv.sdio;
1116                brcmf_sdiod_remove(sdiodev);
1117
1118                dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
1119                dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
1120
1121                kfree(bus_if);
1122                kfree(sdiodev->func[0]);
1123                kfree(sdiodev);
1124        }
1125
1126        brcmf_dbg(SDIO, "Exit\n");
1127}
1128
1129void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1130{
1131        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1132        struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1133
1134        brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
1135        sdiodev->wowl_enabled = enabled;
1136}
1137
1138#ifdef CONFIG_PM_SLEEP
1139static int brcmf_ops_sdio_suspend(struct device *dev)
1140{
1141        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1142        struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1143        mmc_pm_flag_t sdio_flags;
1144
1145        brcmf_dbg(SDIO, "Enter\n");
1146
1147        atomic_set(&sdiodev->suspend, true);
1148
1149        if (sdiodev->wowl_enabled) {
1150                sdio_flags = MMC_PM_KEEP_POWER;
1151                if (sdiodev->pdata->oob_irq_supported)
1152                        enable_irq_wake(sdiodev->pdata->oob_irq_nr);
1153                else
1154                        sdio_flags = MMC_PM_WAKE_SDIO_IRQ;
1155                if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
1156                        brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
1157        }
1158
1159        brcmf_sdio_wd_timer(sdiodev->bus, 0);
1160
1161        return 0;
1162}
1163
1164static int brcmf_ops_sdio_resume(struct device *dev)
1165{
1166        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1167        struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1168
1169        brcmf_dbg(SDIO, "Enter\n");
1170        if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)
1171                disable_irq_wake(sdiodev->pdata->oob_irq_nr);
1172        brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
1173        atomic_set(&sdiodev->suspend, false);
1174        return 0;
1175}
1176
1177static const struct dev_pm_ops brcmf_sdio_pm_ops = {
1178        .suspend        = brcmf_ops_sdio_suspend,
1179        .resume         = brcmf_ops_sdio_resume,
1180};
1181#endif  /* CONFIG_PM_SLEEP */
1182
1183static struct sdio_driver brcmf_sdmmc_driver = {
1184        .probe = brcmf_ops_sdio_probe,
1185        .remove = brcmf_ops_sdio_remove,
1186        .name = BRCMFMAC_SDIO_PDATA_NAME,
1187        .id_table = brcmf_sdmmc_ids,
1188        .drv = {
1189                .owner = THIS_MODULE,
1190#ifdef CONFIG_PM_SLEEP
1191                .pm = &brcmf_sdio_pm_ops,
1192#endif  /* CONFIG_PM_SLEEP */
1193        },
1194};
1195
1196static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
1197{
1198        brcmf_dbg(SDIO, "Enter\n");
1199
1200        brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
1201
1202        if (brcmfmac_sdio_pdata->power_on)
1203                brcmfmac_sdio_pdata->power_on();
1204
1205        return 0;
1206}
1207
1208static int brcmf_sdio_pd_remove(struct platform_device *pdev)
1209{
1210        brcmf_dbg(SDIO, "Enter\n");
1211
1212        if (brcmfmac_sdio_pdata->power_off)
1213                brcmfmac_sdio_pdata->power_off();
1214
1215        sdio_unregister_driver(&brcmf_sdmmc_driver);
1216
1217        return 0;
1218}
1219
1220static struct platform_driver brcmf_sdio_pd = {
1221        .remove         = brcmf_sdio_pd_remove,
1222        .driver         = {
1223                .name   = BRCMFMAC_SDIO_PDATA_NAME,
1224        }
1225};
1226
1227void brcmf_sdio_register(void)
1228{
1229        int ret;
1230
1231        ret = sdio_register_driver(&brcmf_sdmmc_driver);
1232        if (ret)
1233                brcmf_err("sdio_register_driver failed: %d\n", ret);
1234}
1235
1236void brcmf_sdio_exit(void)
1237{
1238        brcmf_dbg(SDIO, "Enter\n");
1239
1240        if (brcmfmac_sdio_pdata)
1241                platform_driver_unregister(&brcmf_sdio_pd);
1242        else
1243                sdio_unregister_driver(&brcmf_sdmmc_driver);
1244}
1245
1246void __init brcmf_sdio_init(void)
1247{
1248        int ret;
1249
1250        brcmf_dbg(SDIO, "Enter\n");
1251
1252        ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
1253        if (ret == -ENODEV)
1254                brcmf_dbg(SDIO, "No platform data available.\n");
1255}
1256
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.