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 /*
313 * Use CMD53 to read data from SDIO device.
314 * This function MUST be called after sdio_claim_host() or
315 * in SDIO ISR(host had been claimed).
316 *
317 * Parameters:
318 *psdio pointer of SDIO_DATA
319 *addr address to read
320 *cnt amount to read
321 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
322 *
323 * Return:
324 *0 Success
325 *others Fail
326 */
_sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)327 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
328 {
329 struct adapter *padapter;
330 struct dvobj_priv *psdiodev;
331 struct sdio_data *psdio;
332
333 int err = -EPERM;
334 struct sdio_func *func;
335
336 padapter = pintfhdl->padapter;
337 psdiodev = pintfhdl->pintf_dev;
338 psdio = &psdiodev->intf_data;
339
340 if (padapter->bSurpriseRemoved)
341 return err;
342
343 func = psdio->func;
344
345 if (unlikely((cnt == 1) || (cnt == 2))) {
346 int i;
347 u8 *pbuf = pdata;
348
349 for (i = 0; i < cnt; i++) {
350 *(pbuf + i) = sdio_readb(func, addr + i, &err);
351
352 if (err)
353 break;
354 }
355 return err;
356 }
357
358 err = sdio_memcpy_fromio(func, pdata, addr, cnt);
359
360 return err;
361 }
362
363 /*
364 * Use CMD53 to read data from SDIO device.
365 *
366 * Parameters:
367 *psdio pointer of SDIO_DATA
368 *addr address to read
369 *cnt amount to read
370 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
371 *
372 * Return:
373 *0 Success
374 *others Fail
375 */
sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)376 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
377 {
378 struct adapter *padapter;
379 struct dvobj_priv *psdiodev;
380 struct sdio_data *psdio;
381
382 struct sdio_func *func;
383 bool claim_needed;
384 s32 err = -EPERM;
385
386 padapter = pintfhdl->padapter;
387 psdiodev = pintfhdl->pintf_dev;
388 psdio = &psdiodev->intf_data;
389
390 if (padapter->bSurpriseRemoved)
391 return err;
392
393 func = psdio->func;
394 claim_needed = rtw_sdio_claim_host_needed(func);
395
396 if (claim_needed)
397 sdio_claim_host(func);
398 err = _sd_read(pintfhdl, addr, cnt, pdata);
399 if (claim_needed)
400 sdio_release_host(func);
401 return err;
402 }
403
404 /*
405 * Use CMD53 to write data to SDIO device.
406 * This function MUST be called after sdio_claim_host() or
407 * in SDIO ISR(host had been claimed).
408 *
409 * Parameters:
410 *psdio pointer of SDIO_DATA
411 *addr address to write
412 *cnt amount to write
413 *pdata data pointer, this should be a "DMA:able scratch buffer"!
414 *
415 * Return:
416 *0 Success
417 *others Fail
418 */
_sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)419 s32 _sd_write(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 u32 size;
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 /* size = sdio_align_size(func, cnt); */
438
439 if (unlikely((cnt == 1) || (cnt == 2))) {
440 int i;
441 u8 *pbuf = pdata;
442
443 for (i = 0; i < cnt; i++) {
444 sdio_writeb(func, *(pbuf + i), addr + i, &err);
445 if (err)
446 break;
447 }
448
449 return err;
450 }
451
452 size = cnt;
453 err = sdio_memcpy_toio(func, addr, pdata, size);
454
455 return err;
456 }
457
458 /*
459 * Use CMD53 to write data to SDIO device.
460 *
461 * Parameters:
462 * psdio pointer of SDIO_DATA
463 * addr address to write
464 * cnt amount to write
465 * pdata data pointer, this should be a "DMA:able scratch buffer"!
466 *
467 * Return:
468 * 0 Success
469 * others Fail
470 */
sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)471 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
472 {
473 struct adapter *padapter;
474 struct dvobj_priv *psdiodev;
475 struct sdio_data *psdio;
476 struct sdio_func *func;
477 bool claim_needed;
478 s32 err = -EPERM;
479
480 padapter = pintfhdl->padapter;
481 psdiodev = pintfhdl->pintf_dev;
482 psdio = &psdiodev->intf_data;
483
484 if (padapter->bSurpriseRemoved)
485 return err;
486
487 func = psdio->func;
488 claim_needed = rtw_sdio_claim_host_needed(func);
489
490 if (claim_needed)
491 sdio_claim_host(func);
492 err = _sd_write(pintfhdl, addr, cnt, pdata);
493 if (claim_needed)
494 sdio_release_host(func);
495 return err;
496 }
497