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