xref: /linux/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c (revision d2912cb15bdda8ba4a5dd73396ad62641af2f520)
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__, err, addr+i, pdata[i]);
160 			break;
161 		}
162 	}
163 	return err;
164 }
165 
166 /*
167  * Return:
168  *0		Success
169  *others	Fail
170  */
171 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
172 {
173 	struct adapter *padapter;
174 	struct dvobj_priv *psdiodev;
175 	struct sdio_data *psdio;
176 
177 	int err = 0;
178 	struct sdio_func *func;
179 	bool claim_needed;
180 
181 	padapter = pintfhdl->padapter;
182 	psdiodev = pintfhdl->pintf_dev;
183 	psdio = &psdiodev->intf_data;
184 
185 	if (padapter->bSurpriseRemoved) {
186 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
187 		return err;
188 	}
189 
190 	func = psdio->func;
191 	claim_needed = rtw_sdio_claim_host_needed(func);
192 
193 	if (claim_needed)
194 		sdio_claim_host(func);
195 	err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
196 	if (claim_needed)
197 		sdio_release_host(func);
198 	return err;
199 }
200 
201 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
202 {
203 	struct adapter *padapter;
204 	struct dvobj_priv *psdiodev;
205 	struct sdio_data *psdio;
206 
207 	u8 v = 0;
208 	struct sdio_func *func;
209 	bool claim_needed;
210 
211 	padapter = pintfhdl->padapter;
212 	psdiodev = pintfhdl->pintf_dev;
213 	psdio = &psdiodev->intf_data;
214 
215 	if (padapter->bSurpriseRemoved) {
216 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
217 		return v;
218 	}
219 
220 	func = psdio->func;
221 	claim_needed = rtw_sdio_claim_host_needed(func);
222 
223 	if (claim_needed)
224 		sdio_claim_host(func);
225 	v = sdio_readb(func, addr, err);
226 	if (claim_needed)
227 		sdio_release_host(func);
228 	if (err && *err)
229 		DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
230 	return v;
231 }
232 
233 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
234 {
235 	struct adapter *padapter;
236 	struct dvobj_priv *psdiodev;
237 	struct sdio_data *psdio;
238 	u32 v = 0;
239 	struct sdio_func *func;
240 	bool claim_needed;
241 
242 	padapter = pintfhdl->padapter;
243 	psdiodev = pintfhdl->pintf_dev;
244 	psdio = &psdiodev->intf_data;
245 
246 	if (padapter->bSurpriseRemoved) {
247 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
248 		return v;
249 	}
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 	v = sdio_readl(func, addr, err);
257 	if (claim_needed)
258 		sdio_release_host(func);
259 
260 	if (err && *err)
261 	{
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 		{
269 			if (claim_needed) sdio_claim_host(func);
270 			v = sdio_readl(func, addr, err);
271 			if (claim_needed) sdio_release_host(func);
272 
273 			if (*err == 0) {
274 				rtw_reset_continual_io_error(psdiodev);
275 				break;
276 			} else {
277 				DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
278 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) {
279 					padapter->bSurpriseRemoved = true;
280 				}
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 	{
355 		int i;
356 
357 		DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v);
358 
359 		*err = 0;
360 		for (i = 0; i < SD_IO_TRY_CNT; i++)
361 		{
362 			if (claim_needed) sdio_claim_host(func);
363 			sdio_writel(func, v, addr, err);
364 			if (claim_needed) 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 
374 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
375 					padapter->bSurpriseRemoved = true;
376 					break;
377 				}
378 			}
379 		}
380 
381 		if (i == SD_IO_TRY_CNT)
382 			DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
383 		else
384 			DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
385 	}
386 }
387 
388 /*
389  * Use CMD53 to read data from SDIO device.
390  * This function MUST be called after sdio_claim_host() or
391  * in SDIO ISR(host had been claimed).
392  *
393  * Parameters:
394  *psdio	pointer of SDIO_DATA
395  *addr	address to read
396  *cnt		amount to read
397  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
398  *
399  * Return:
400  *0		Success
401  *others	Fail
402  */
403 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
404 {
405 	struct adapter *padapter;
406 	struct dvobj_priv *psdiodev;
407 	struct sdio_data *psdio;
408 
409 	int err = -EPERM;
410 	struct sdio_func *func;
411 
412 	padapter = pintfhdl->padapter;
413 	psdiodev = pintfhdl->pintf_dev;
414 	psdio = &psdiodev->intf_data;
415 
416 	if (padapter->bSurpriseRemoved) {
417 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
418 		return err;
419 	}
420 
421 	func = psdio->func;
422 
423 	if (unlikely((cnt == 1) || (cnt == 2)))
424 	{
425 		int i;
426 		u8 *pbuf = pdata;
427 
428 		for (i = 0; i < cnt; i++)
429 		{
430 			*(pbuf+i) = sdio_readb(func, addr+i, &err);
431 
432 			if (err) {
433 				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr);
434 				break;
435 			}
436 		}
437 		return err;
438 	}
439 
440 	err = sdio_memcpy_fromio(func, pdata, addr, cnt);
441 	if (err) {
442 		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt);
443 	}
444 	return err;
445 }
446 
447 /*
448  * Use CMD53 to read data from SDIO device.
449  *
450  * Parameters:
451  *psdio	pointer of SDIO_DATA
452  *addr	address to read
453  *cnt		amount to read
454  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
455  *
456  * Return:
457  *0		Success
458  *others	Fail
459  */
460 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
461 {
462 	struct adapter *padapter;
463 	struct dvobj_priv *psdiodev;
464 	struct sdio_data *psdio;
465 
466 	struct sdio_func *func;
467 	bool claim_needed;
468 	s32 err = -EPERM;
469 
470 	padapter = pintfhdl->padapter;
471 	psdiodev = pintfhdl->pintf_dev;
472 	psdio = &psdiodev->intf_data;
473 
474 	if (padapter->bSurpriseRemoved) {
475 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
476 		return err;
477 	}
478 	func = psdio->func;
479 	claim_needed = rtw_sdio_claim_host_needed(func);
480 
481 	if (claim_needed)
482 		sdio_claim_host(func);
483 	err = _sd_read(pintfhdl, addr, cnt, pdata);
484 	if (claim_needed)
485 		sdio_release_host(func);
486 	return err;
487 }
488 
489 /*
490  * Use CMD53 to write data to SDIO device.
491  * This function MUST be called after sdio_claim_host() or
492  * in SDIO ISR(host had been claimed).
493  *
494  * Parameters:
495  *psdio	pointer of SDIO_DATA
496  *addr	address to write
497  *cnt		amount to write
498  *pdata	data pointer, this should be a "DMA:able scratch buffer"!
499  *
500  * Return:
501  *0		Success
502  *others	Fail
503  */
504 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
505 {
506 	struct adapter *padapter;
507 	struct dvobj_priv *psdiodev;
508 	struct sdio_data *psdio;
509 
510 	struct sdio_func *func;
511 	u32 size;
512 	s32 err =  -EPERM;
513 
514 	padapter = pintfhdl->padapter;
515 	psdiodev = pintfhdl->pintf_dev;
516 	psdio = &psdiodev->intf_data;
517 
518 	if (padapter->bSurpriseRemoved) {
519 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
520 		return err;
521 	}
522 
523 	func = psdio->func;
524 /*	size = sdio_align_size(func, cnt); */
525 
526 	if (unlikely((cnt == 1) || (cnt == 2)))
527 	{
528 		int i;
529 		u8 *pbuf = pdata;
530 
531 		for (i = 0; i < cnt; i++)
532 		{
533 			sdio_writeb(func, *(pbuf+i), addr+i, &err);
534 			if (err) {
535 				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr, *(pbuf+i));
536 				break;
537 			}
538 		}
539 
540 		return err;
541 	}
542 
543 	size = cnt;
544 	err = sdio_memcpy_toio(func, addr, pdata, size);
545 	if (err) {
546 		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size);
547 	}
548 	return err;
549 }
550 
551 /*
552  * Use CMD53 to write data to SDIO device.
553  *
554  * Parameters:
555  *  psdio	pointer of SDIO_DATA
556  *  addr	address to write
557  *  cnt		amount to write
558  *  pdata	data pointer, this should be a "DMA:able scratch buffer"!
559  *
560  * Return:
561  *  0		Success
562  *  others	Fail
563  */
564 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
565 {
566 	struct adapter *padapter;
567 	struct dvobj_priv *psdiodev;
568 	struct sdio_data *psdio;
569 	struct sdio_func *func;
570 	bool claim_needed;
571 	s32 err =  -EPERM;
572 
573 	padapter = pintfhdl->padapter;
574 	psdiodev = pintfhdl->pintf_dev;
575 	psdio = &psdiodev->intf_data;
576 
577 	if (padapter->bSurpriseRemoved) {
578 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
579 		return err;
580 	}
581 
582 	func = psdio->func;
583 	claim_needed = rtw_sdio_claim_host_needed(func);
584 
585 	if (claim_needed)
586 		sdio_claim_host(func);
587 	err = _sd_write(pintfhdl, addr, cnt, pdata);
588 	if (claim_needed)
589 		sdio_release_host(func);
590 	return err;
591 }
592