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 }
527