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