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