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