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