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