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