GNU Linux-libre 6.7.9-gnu
[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
8 #include <drv_types.h>
9 #include <rtw_debug.h>
10
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
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  */
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  */
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  */
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  */
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
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
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
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
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  */
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  */
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  */
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  */
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 }