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
rtw_sdio_claim_host_needed(struct sdio_func * func)11 static 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
rtw_sdio_set_irq_thd(struct dvobj_priv * dvobj,void * thd_hdl)21 inline 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 */
_sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)33 s32 _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 */
sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)64 s32 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 */
_sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)97 s32 _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 */
sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)128 s32 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
sd_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)156 u8 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
sd_read32(struct intf_hdl * pintfhdl,u32 addr,s32 * err)184 u32 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
sd_write8(struct intf_hdl * pintfhdl,u32 addr,u8 v,s32 * err)237 void 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
sd_write32(struct intf_hdl * pintfhdl,u32 addr,u32 v,s32 * err)262 void 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 */
_sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)328 s32 _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 */
sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)377 s32 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 */
_sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)420 s32 _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 */
sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)472 s32 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