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