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