linux/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5 *
   6 *******************************************************************************/
   7
   8#include <drv_types.h>
   9#include <rtw_debug.h>
  10
  11static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
  12{
  13        struct dvobj_priv *dvobj = sdio_get_drvdata(func);
  14        struct sdio_data *sdio_data = &dvobj->intf_data;
  15
  16        if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
  17                return false;
  18        return true;
  19}
  20
  21inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl)
  22{
  23        struct sdio_data *sdio_data = &dvobj->intf_data;
  24
  25        sdio_data->sys_sdio_irq_thd = thd_hdl;
  26}
  27
  28/*
  29 * Return:
  30 *0             Success
  31 *others        Fail
  32 */
  33s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
  34{
  35        struct adapter *padapter;
  36        struct dvobj_priv *psdiodev;
  37        struct sdio_data *psdio;
  38
  39        int err = 0, i;
  40        struct sdio_func *func;
  41
  42        padapter = pintfhdl->padapter;
  43        psdiodev = pintfhdl->pintf_dev;
  44        psdio = &psdiodev->intf_data;
  45
  46        if (padapter->bSurpriseRemoved)
  47                return err;
  48
  49        func = psdio->func;
  50
  51        for (i = 0; i < cnt; i++) {
  52                pdata[i] = sdio_readb(func, addr + i, &err);
  53                if (err)
  54                        break;
  55        }
  56        return err;
  57}
  58
  59/*
  60 * Return:
  61 *0             Success
  62 *others        Fail
  63 */
  64s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
  65{
  66        struct adapter *padapter;
  67        struct dvobj_priv *psdiodev;
  68        struct sdio_data *psdio;
  69
  70        int err = 0;
  71        struct sdio_func *func;
  72        bool claim_needed;
  73
  74        padapter = pintfhdl->padapter;
  75        psdiodev = pintfhdl->pintf_dev;
  76        psdio = &psdiodev->intf_data;
  77
  78        if (padapter->bSurpriseRemoved)
  79                return err;
  80
  81        func = psdio->func;
  82        claim_needed = rtw_sdio_claim_host_needed(func);
  83
  84        if (claim_needed)
  85                sdio_claim_host(func);
  86        err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
  87        if (claim_needed)
  88                sdio_release_host(func);
  89        return err;
  90}
  91
  92/*
  93 * Return:
  94 *0             Success
  95 *others        Fail
  96 */
  97s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
  98{
  99        struct adapter *padapter;
 100        struct dvobj_priv *psdiodev;
 101        struct sdio_data *psdio;
 102
 103        int err = 0, i;
 104        struct sdio_func *func;
 105
 106        padapter = pintfhdl->padapter;
 107        psdiodev = pintfhdl->pintf_dev;
 108        psdio = &psdiodev->intf_data;
 109
 110        if (padapter->bSurpriseRemoved)
 111                return err;
 112
 113        func = psdio->func;
 114
 115        for (i = 0; i < cnt; i++) {
 116                sdio_writeb(func, pdata[i], addr + i, &err);
 117                if (err)
 118                        break;
 119        }
 120        return err;
 121}
 122
 123/*
 124 * Return:
 125 *0             Success
 126 *others        Fail
 127 */
 128s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
 129{
 130        struct adapter *padapter;
 131        struct dvobj_priv *psdiodev;
 132        struct sdio_data *psdio;
 133
 134        int err = 0;
 135        struct sdio_func *func;
 136        bool claim_needed;
 137
 138        padapter = pintfhdl->padapter;
 139        psdiodev = pintfhdl->pintf_dev;
 140        psdio = &psdiodev->intf_data;
 141
 142        if (padapter->bSurpriseRemoved)
 143                return err;
 144
 145        func = psdio->func;
 146        claim_needed = rtw_sdio_claim_host_needed(func);
 147
 148        if (claim_needed)
 149                sdio_claim_host(func);
 150        err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
 151        if (claim_needed)
 152                sdio_release_host(func);
 153        return err;
 154}
 155
 156u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
 157{
 158        struct adapter *padapter;
 159        struct dvobj_priv *psdiodev;
 160        struct sdio_data *psdio;
 161
 162        u8 v = 0;
 163        struct sdio_func *func;
 164        bool claim_needed;
 165
 166        padapter = pintfhdl->padapter;
 167        psdiodev = pintfhdl->pintf_dev;
 168        psdio = &psdiodev->intf_data;
 169
 170        if (padapter->bSurpriseRemoved)
 171                return v;
 172
 173        func = psdio->func;
 174        claim_needed = rtw_sdio_claim_host_needed(func);
 175
 176        if (claim_needed)
 177                sdio_claim_host(func);
 178        v = sdio_readb(func, addr, err);
 179        if (claim_needed)
 180                sdio_release_host(func);
 181        return v;
 182}
 183
 184u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
 185{
 186        struct adapter *padapter;
 187        struct dvobj_priv *psdiodev;
 188        struct sdio_data *psdio;
 189        u32 v = 0;
 190        struct sdio_func *func;
 191        bool claim_needed;
 192
 193        padapter = pintfhdl->padapter;
 194        psdiodev = pintfhdl->pintf_dev;
 195        psdio = &psdiodev->intf_data;
 196
 197        if (padapter->bSurpriseRemoved)
 198                return v;
 199
 200        func = psdio->func;
 201        claim_needed = rtw_sdio_claim_host_needed(func);
 202
 203        if (claim_needed)
 204                sdio_claim_host(func);
 205        v = sdio_readl(func, addr, err);
 206        if (claim_needed)
 207                sdio_release_host(func);
 208
 209        if (err && *err) {
 210                int i;
 211
 212                *err = 0;
 213                for (i = 0; i < SD_IO_TRY_CNT; i++) {
 214                        if (claim_needed)
 215                                sdio_claim_host(func);
 216                        v = sdio_readl(func, addr, err);
 217                        if (claim_needed)
 218                                sdio_release_host(func);
 219
 220                        if (*err == 0) {
 221                                rtw_reset_continual_io_error(psdiodev);
 222                                break;
 223                        } else {
 224                                if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
 225                                        padapter->bSurpriseRemoved = true;
 226
 227                                if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
 228                                        padapter->bSurpriseRemoved = true;
 229                                        break;
 230                                }
 231                        }
 232                }
 233        }
 234        return  v;
 235}
 236
 237void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
 238{
 239        struct adapter *padapter;
 240        struct dvobj_priv *psdiodev;
 241        struct sdio_data *psdio;
 242        struct sdio_func *func;
 243        bool claim_needed;
 244
 245        padapter = pintfhdl->padapter;
 246        psdiodev = pintfhdl->pintf_dev;
 247        psdio = &psdiodev->intf_data;
 248
 249        if (padapter->bSurpriseRemoved)
 250                return;
 251
 252        func = psdio->func;
 253        claim_needed = rtw_sdio_claim_host_needed(func);
 254
 255        if (claim_needed)
 256                sdio_claim_host(func);
 257        sdio_writeb(func, v, addr, err);
 258        if (claim_needed)
 259                sdio_release_host(func);
 260}
 261
 262void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
 263{
 264        struct adapter *padapter;
 265        struct dvobj_priv *psdiodev;
 266        struct sdio_data *psdio;
 267        struct sdio_func *func;
 268        bool claim_needed;
 269
 270        padapter = pintfhdl->padapter;
 271        psdiodev = pintfhdl->pintf_dev;
 272        psdio = &psdiodev->intf_data;
 273
 274        if (padapter->bSurpriseRemoved)
 275                return;
 276
 277        func = psdio->func;
 278        claim_needed = rtw_sdio_claim_host_needed(func);
 279
 280        if (claim_needed)
 281                sdio_claim_host(func);
 282        sdio_writel(func, v, addr, err);
 283        if (claim_needed)
 284                sdio_release_host(func);
 285
 286        if (err && *err) {
 287                int i;
 288
 289                *err = 0;
 290                for (i = 0; i < SD_IO_TRY_CNT; i++) {
 291                        if (claim_needed)
 292                                sdio_claim_host(func);
 293                        sdio_writel(func, v, addr, err);
 294                        if (claim_needed)
 295                                sdio_release_host(func);
 296                        if (*err == 0) {
 297                                rtw_reset_continual_io_error(psdiodev);
 298                                break;
 299                        } else {
 300                                if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
 301                                        padapter->bSurpriseRemoved = true;
 302
 303                                if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
 304                                        padapter->bSurpriseRemoved = true;
 305                                        break;
 306                                }
 307                        }
 308                }
 309
 310        }
 311}
 312
 313/*
 314 * Use CMD53 to read data from SDIO device.
 315 * This function MUST be called after sdio_claim_host() or
 316 * in SDIO ISR(host had been claimed).
 317 *
 318 * Parameters:
 319 *psdio pointer of SDIO_DATA
 320 *addr  address to read
 321 *cnt           amount to read
 322 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
 323 *
 324 * Return:
 325 *0             Success
 326 *others        Fail
 327 */
 328s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
 329{
 330        struct adapter *padapter;
 331        struct dvobj_priv *psdiodev;
 332        struct sdio_data *psdio;
 333
 334        int err = -EPERM;
 335        struct sdio_func *func;
 336
 337        padapter = pintfhdl->padapter;
 338        psdiodev = pintfhdl->pintf_dev;
 339        psdio = &psdiodev->intf_data;
 340
 341        if (padapter->bSurpriseRemoved)
 342                return err;
 343
 344        func = psdio->func;
 345
 346        if (unlikely((cnt == 1) || (cnt == 2))) {
 347                int i;
 348                u8 *pbuf = pdata;
 349
 350                for (i = 0; i < cnt; i++) {
 351                        *(pbuf + i) = sdio_readb(func, addr + i, &err);
 352
 353                        if (err)
 354                                break;
 355                }
 356                return err;
 357        }
 358
 359        err = sdio_memcpy_fromio(func, pdata, addr, cnt);
 360
 361        return err;
 362}
 363
 364/*
 365 * Use CMD53 to read data from SDIO device.
 366 *
 367 * Parameters:
 368 *psdio pointer of SDIO_DATA
 369 *addr  address to read
 370 *cnt           amount to read
 371 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
 372 *
 373 * Return:
 374 *0             Success
 375 *others        Fail
 376 */
 377s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
 378{
 379        struct adapter *padapter;
 380        struct dvobj_priv *psdiodev;
 381        struct sdio_data *psdio;
 382
 383        struct sdio_func *func;
 384        bool claim_needed;
 385        s32 err = -EPERM;
 386
 387        padapter = pintfhdl->padapter;
 388        psdiodev = pintfhdl->pintf_dev;
 389        psdio = &psdiodev->intf_data;
 390
 391        if (padapter->bSurpriseRemoved)
 392                return err;
 393
 394        func = psdio->func;
 395        claim_needed = rtw_sdio_claim_host_needed(func);
 396
 397        if (claim_needed)
 398                sdio_claim_host(func);
 399        err = _sd_read(pintfhdl, addr, cnt, pdata);
 400        if (claim_needed)
 401                sdio_release_host(func);
 402        return err;
 403}
 404
 405/*
 406 * Use CMD53 to write data to SDIO device.
 407 * This function MUST be called after sdio_claim_host() or
 408 * in SDIO ISR(host had been claimed).
 409 *
 410 * Parameters:
 411 *psdio pointer of SDIO_DATA
 412 *addr  address to write
 413 *cnt           amount to write
 414 *pdata data pointer, this should be a "DMA:able scratch buffer"!
 415 *
 416 * Return:
 417 *0             Success
 418 *others        Fail
 419 */
 420s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
 421{
 422        struct adapter *padapter;
 423        struct dvobj_priv *psdiodev;
 424        struct sdio_data *psdio;
 425
 426        struct sdio_func *func;
 427        u32 size;
 428        s32 err =  -EPERM;
 429
 430        padapter = pintfhdl->padapter;
 431        psdiodev = pintfhdl->pintf_dev;
 432        psdio = &psdiodev->intf_data;
 433
 434        if (padapter->bSurpriseRemoved)
 435                return err;
 436
 437        func = psdio->func;
 438/*      size = sdio_align_size(func, cnt); */
 439
 440        if (unlikely((cnt == 1) || (cnt == 2))) {
 441                int i;
 442                u8 *pbuf = pdata;
 443
 444                for (i = 0; i < cnt; i++) {
 445                        sdio_writeb(func, *(pbuf + i), addr + i, &err);
 446                        if (err)
 447                                break;
 448                }
 449
 450                return err;
 451        }
 452
 453        size = cnt;
 454        err = sdio_memcpy_toio(func, addr, pdata, size);
 455
 456        return err;
 457}
 458
 459/*
 460 * Use CMD53 to write data to SDIO device.
 461 *
 462 * Parameters:
 463 *  psdio       pointer of SDIO_DATA
 464 *  addr        address to write
 465 *  cnt         amount to write
 466 *  pdata       data pointer, this should be a "DMA:able scratch buffer"!
 467 *
 468 * Return:
 469 *  0           Success
 470 *  others      Fail
 471 */
 472s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
 473{
 474        struct adapter *padapter;
 475        struct dvobj_priv *psdiodev;
 476        struct sdio_data *psdio;
 477        struct sdio_func *func;
 478        bool claim_needed;
 479        s32 err =  -EPERM;
 480
 481        padapter = pintfhdl->padapter;
 482        psdiodev = pintfhdl->pintf_dev;
 483        psdio = &psdiodev->intf_data;
 484
 485        if (padapter->bSurpriseRemoved)
 486                return err;
 487
 488        func = psdio->func;
 489        claim_needed = rtw_sdio_claim_host_needed(func);
 490
 491        if (claim_needed)
 492                sdio_claim_host(func);
 493        err = _sd_write(pintfhdl, addr, cnt, pdata);
 494        if (claim_needed)
 495                sdio_release_host(func);
 496        return err;
 497}
 498