158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0
2554c0a3aSHans de Goede /******************************************************************************
3554c0a3aSHans de Goede  *
4554c0a3aSHans de Goede  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5554c0a3aSHans de Goede  *
6554c0a3aSHans de Goede  *******************************************************************************/
7554c0a3aSHans de Goede 
8554c0a3aSHans de Goede #include <drv_types.h>
9554c0a3aSHans de Goede #include <rtw_debug.h>
10554c0a3aSHans de Goede 
rtw_sdio_claim_host_needed(struct sdio_func * func)11554c0a3aSHans de Goede static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
12554c0a3aSHans de Goede {
13554c0a3aSHans de Goede 	struct dvobj_priv *dvobj = sdio_get_drvdata(func);
14affbeba3SMadhumitha Prabakaran 	struct sdio_data *sdio_data = &dvobj->intf_data;
15554c0a3aSHans de Goede 
16554c0a3aSHans de Goede 	if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
17554c0a3aSHans de Goede 		return false;
18554c0a3aSHans de Goede 	return true;
19554c0a3aSHans de Goede }
20554c0a3aSHans de Goede 
rtw_sdio_set_irq_thd(struct dvobj_priv * dvobj,void * thd_hdl)21554c0a3aSHans de Goede inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl)
22554c0a3aSHans de Goede {
23affbeba3SMadhumitha Prabakaran 	struct sdio_data *sdio_data = &dvobj->intf_data;
24554c0a3aSHans de Goede 
25554c0a3aSHans de Goede 	sdio_data->sys_sdio_irq_thd = thd_hdl;
26554c0a3aSHans de Goede }
27554c0a3aSHans de Goede 
28554c0a3aSHans de Goede /*
29554c0a3aSHans de Goede  * Return:
30554c0a3aSHans de Goede  *0		Success
31554c0a3aSHans de Goede  *others	Fail
32554c0a3aSHans de Goede  */
_sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)33554c0a3aSHans de Goede s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
34554c0a3aSHans de Goede {
35554c0a3aSHans de Goede 	struct adapter *padapter;
36554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
37affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
38554c0a3aSHans de Goede 
39554c0a3aSHans de Goede 	int err = 0, i;
40554c0a3aSHans de Goede 	struct sdio_func *func;
41554c0a3aSHans de Goede 
42554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
43554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
44554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
45554c0a3aSHans de Goede 
46*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
47554c0a3aSHans de Goede 		return err;
48554c0a3aSHans de Goede 
49554c0a3aSHans de Goede 	func = psdio->func;
50554c0a3aSHans de Goede 
51554c0a3aSHans de Goede 	for (i = 0; i < cnt; i++) {
52554c0a3aSHans de Goede 		pdata[i] = sdio_readb(func, addr + i, &err);
53*709c8e49SFabio Aiuto 		if (err)
54554c0a3aSHans de Goede 			break;
55554c0a3aSHans de Goede 	}
56554c0a3aSHans de Goede 	return err;
57554c0a3aSHans de Goede }
58554c0a3aSHans de Goede 
59554c0a3aSHans de Goede /*
60554c0a3aSHans de Goede  * Return:
61554c0a3aSHans de Goede  *0		Success
62554c0a3aSHans de Goede  *others	Fail
63554c0a3aSHans de Goede  */
sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)64554c0a3aSHans de Goede s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
65554c0a3aSHans de Goede {
66554c0a3aSHans de Goede 	struct adapter *padapter;
67554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
68affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
69554c0a3aSHans de Goede 
70554c0a3aSHans de Goede 	int err = 0;
71554c0a3aSHans de Goede 	struct sdio_func *func;
72554c0a3aSHans de Goede 	bool claim_needed;
73554c0a3aSHans de Goede 
74554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
75554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
76554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
77554c0a3aSHans de Goede 
78*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
79554c0a3aSHans de Goede 		return err;
80554c0a3aSHans de Goede 
81554c0a3aSHans de Goede 	func = psdio->func;
82554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
83554c0a3aSHans de Goede 
84554c0a3aSHans de Goede 	if (claim_needed)
85554c0a3aSHans de Goede 		sdio_claim_host(func);
86554c0a3aSHans de Goede 	err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
87554c0a3aSHans de Goede 	if (claim_needed)
88554c0a3aSHans de Goede 		sdio_release_host(func);
89554c0a3aSHans de Goede 	return err;
90554c0a3aSHans de Goede }
91554c0a3aSHans de Goede 
92554c0a3aSHans de Goede /*
93554c0a3aSHans de Goede  * Return:
94554c0a3aSHans de Goede  *0		Success
95554c0a3aSHans de Goede  *others	Fail
96554c0a3aSHans de Goede  */
_sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)97554c0a3aSHans de Goede s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
98554c0a3aSHans de Goede {
99554c0a3aSHans de Goede 	struct adapter *padapter;
100554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
101affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
102554c0a3aSHans de Goede 
103554c0a3aSHans de Goede 	int err = 0, i;
104554c0a3aSHans de Goede 	struct sdio_func *func;
105554c0a3aSHans de Goede 
106554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
107554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
108554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
109554c0a3aSHans de Goede 
110*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
111554c0a3aSHans de Goede 		return err;
112554c0a3aSHans de Goede 
113554c0a3aSHans de Goede 	func = psdio->func;
114554c0a3aSHans de Goede 
115554c0a3aSHans de Goede 	for (i = 0; i < cnt; i++) {
116554c0a3aSHans de Goede 		sdio_writeb(func, pdata[i], addr + i, &err);
117*709c8e49SFabio Aiuto 		if (err)
118554c0a3aSHans de Goede 			break;
119554c0a3aSHans de Goede 	}
120554c0a3aSHans de Goede 	return err;
121554c0a3aSHans de Goede }
122554c0a3aSHans de Goede 
123554c0a3aSHans de Goede /*
124554c0a3aSHans de Goede  * Return:
125554c0a3aSHans de Goede  *0		Success
126554c0a3aSHans de Goede  *others	Fail
127554c0a3aSHans de Goede  */
sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)128554c0a3aSHans de Goede s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
129554c0a3aSHans de Goede {
130554c0a3aSHans de Goede 	struct adapter *padapter;
131554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
132affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
133554c0a3aSHans de Goede 
134554c0a3aSHans de Goede 	int err = 0;
135554c0a3aSHans de Goede 	struct sdio_func *func;
136554c0a3aSHans de Goede 	bool claim_needed;
137554c0a3aSHans de Goede 
138554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
139554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
140554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
141554c0a3aSHans de Goede 
142*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
143554c0a3aSHans de Goede 		return err;
144554c0a3aSHans de Goede 
145554c0a3aSHans de Goede 	func = psdio->func;
146554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
147554c0a3aSHans de Goede 
148554c0a3aSHans de Goede 	if (claim_needed)
149554c0a3aSHans de Goede 		sdio_claim_host(func);
150554c0a3aSHans de Goede 	err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
151554c0a3aSHans de Goede 	if (claim_needed)
152554c0a3aSHans de Goede 		sdio_release_host(func);
153554c0a3aSHans de Goede 	return err;
154554c0a3aSHans de Goede }
155554c0a3aSHans de Goede 
sd_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)156554c0a3aSHans de Goede u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
157554c0a3aSHans de Goede {
158554c0a3aSHans de Goede 	struct adapter *padapter;
159554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
160affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
161554c0a3aSHans de Goede 
162554c0a3aSHans de Goede 	u8 v = 0;
163554c0a3aSHans de Goede 	struct sdio_func *func;
164554c0a3aSHans de Goede 	bool claim_needed;
165554c0a3aSHans de Goede 
166554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
167554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
168554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
169554c0a3aSHans de Goede 
170*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
171554c0a3aSHans de Goede 		return v;
172554c0a3aSHans de Goede 
173554c0a3aSHans de Goede 	func = psdio->func;
174554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
175554c0a3aSHans de Goede 
176554c0a3aSHans de Goede 	if (claim_needed)
177554c0a3aSHans de Goede 		sdio_claim_host(func);
178554c0a3aSHans de Goede 	v = sdio_readb(func, addr, err);
179554c0a3aSHans de Goede 	if (claim_needed)
180554c0a3aSHans de Goede 		sdio_release_host(func);
181554c0a3aSHans de Goede 	return v;
182554c0a3aSHans de Goede }
183554c0a3aSHans de Goede 
sd_read32(struct intf_hdl * pintfhdl,u32 addr,s32 * err)184554c0a3aSHans de Goede u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
185554c0a3aSHans de Goede {
186554c0a3aSHans de Goede 	struct adapter *padapter;
187554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
188affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
189554c0a3aSHans de Goede 	u32 v = 0;
190554c0a3aSHans de Goede 	struct sdio_func *func;
191554c0a3aSHans de Goede 	bool claim_needed;
192554c0a3aSHans de Goede 
193554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
194554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
195554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
196554c0a3aSHans de Goede 
197*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
198554c0a3aSHans de Goede 		return v;
199554c0a3aSHans de Goede 
200554c0a3aSHans de Goede 	func = psdio->func;
201554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
202554c0a3aSHans de Goede 
203554c0a3aSHans de Goede 	if (claim_needed)
204554c0a3aSHans de Goede 		sdio_claim_host(func);
205554c0a3aSHans de Goede 	v = sdio_readl(func, addr, err);
206554c0a3aSHans de Goede 	if (claim_needed)
207554c0a3aSHans de Goede 		sdio_release_host(func);
208554c0a3aSHans de Goede 
2096a9b5dd1SShobhit Kukreti 	if (err && *err) {
210554c0a3aSHans de Goede 		int i;
211554c0a3aSHans de Goede 
212554c0a3aSHans de Goede 		*err = 0;
2136a9b5dd1SShobhit Kukreti 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
21490493f60SRoss Schmidt 			if (claim_needed)
21590493f60SRoss Schmidt 				sdio_claim_host(func);
216554c0a3aSHans de Goede 			v = sdio_readl(func, addr, err);
21790493f60SRoss Schmidt 			if (claim_needed)
21890493f60SRoss Schmidt 				sdio_release_host(func);
219554c0a3aSHans de Goede 
220554c0a3aSHans de Goede 			if (*err == 0) {
221554c0a3aSHans de Goede 				rtw_reset_continual_io_error(psdiodev);
222554c0a3aSHans de Goede 				break;
223554c0a3aSHans de Goede 			} else {
22447af9702SRoss Schmidt 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
225554c0a3aSHans de Goede 					padapter->bSurpriseRemoved = true;
226554c0a3aSHans de Goede 
227554c0a3aSHans de Goede 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
228554c0a3aSHans de Goede 					padapter->bSurpriseRemoved = true;
229554c0a3aSHans de Goede 					break;
230554c0a3aSHans de Goede 				}
231554c0a3aSHans de Goede 			}
232554c0a3aSHans de Goede 		}
233554c0a3aSHans de Goede 	}
234554c0a3aSHans de Goede 	return  v;
235554c0a3aSHans de Goede }
236554c0a3aSHans de Goede 
sd_write8(struct intf_hdl * pintfhdl,u32 addr,u8 v,s32 * err)237554c0a3aSHans de Goede void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
238554c0a3aSHans de Goede {
239554c0a3aSHans de Goede 	struct adapter *padapter;
240554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
241affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
242554c0a3aSHans de Goede 	struct sdio_func *func;
243554c0a3aSHans de Goede 	bool claim_needed;
244554c0a3aSHans de Goede 
245554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
246554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
247554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
248554c0a3aSHans de Goede 
249*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
250554c0a3aSHans de Goede 		return;
251554c0a3aSHans de Goede 
252554c0a3aSHans de Goede 	func = psdio->func;
253554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
254554c0a3aSHans de Goede 
255554c0a3aSHans de Goede 	if (claim_needed)
256554c0a3aSHans de Goede 		sdio_claim_host(func);
257554c0a3aSHans de Goede 	sdio_writeb(func, v, addr, err);
258554c0a3aSHans de Goede 	if (claim_needed)
259554c0a3aSHans de Goede 		sdio_release_host(func);
260554c0a3aSHans de Goede }
261554c0a3aSHans de Goede 
sd_write32(struct intf_hdl * pintfhdl,u32 addr,u32 v,s32 * err)262554c0a3aSHans de Goede void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
263554c0a3aSHans de Goede {
264554c0a3aSHans de Goede 	struct adapter *padapter;
265554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
266affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
267554c0a3aSHans de Goede 	struct sdio_func *func;
268554c0a3aSHans de Goede 	bool claim_needed;
269554c0a3aSHans de Goede 
270554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
271554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
272554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
273554c0a3aSHans de Goede 
274*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
275554c0a3aSHans de Goede 		return;
276554c0a3aSHans de Goede 
277554c0a3aSHans de Goede 	func = psdio->func;
278554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
279554c0a3aSHans de Goede 
280554c0a3aSHans de Goede 	if (claim_needed)
281554c0a3aSHans de Goede 		sdio_claim_host(func);
282554c0a3aSHans de Goede 	sdio_writel(func, v, addr, err);
283554c0a3aSHans de Goede 	if (claim_needed)
284554c0a3aSHans de Goede 		sdio_release_host(func);
285554c0a3aSHans de Goede 
2866a9b5dd1SShobhit Kukreti 	if (err && *err) {
287554c0a3aSHans de Goede 		int i;
288554c0a3aSHans de Goede 
289554c0a3aSHans de Goede 		*err = 0;
2906a9b5dd1SShobhit Kukreti 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
29190493f60SRoss Schmidt 			if (claim_needed)
29290493f60SRoss Schmidt 				sdio_claim_host(func);
293554c0a3aSHans de Goede 			sdio_writel(func, v, addr, err);
29490493f60SRoss Schmidt 			if (claim_needed)
29590493f60SRoss Schmidt 				sdio_release_host(func);
296554c0a3aSHans de Goede 			if (*err == 0) {
297554c0a3aSHans de Goede 				rtw_reset_continual_io_error(psdiodev);
298554c0a3aSHans de Goede 				break;
299554c0a3aSHans de Goede 			} else {
30047af9702SRoss Schmidt 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
301554c0a3aSHans de Goede 					padapter->bSurpriseRemoved = true;
302554c0a3aSHans de Goede 
303554c0a3aSHans de Goede 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
304554c0a3aSHans de Goede 					padapter->bSurpriseRemoved = true;
305554c0a3aSHans de Goede 					break;
306554c0a3aSHans de Goede 				}
307554c0a3aSHans de Goede 			}
308554c0a3aSHans de Goede 		}
309554c0a3aSHans de Goede 
310554c0a3aSHans de Goede 	}
311554c0a3aSHans de Goede }
312554c0a3aSHans de Goede 
313554c0a3aSHans de Goede /*
314554c0a3aSHans de Goede  * Use CMD53 to read data from SDIO device.
315554c0a3aSHans de Goede  * This function MUST be called after sdio_claim_host() or
316554c0a3aSHans de Goede  * in SDIO ISR(host had been claimed).
317554c0a3aSHans de Goede  *
318554c0a3aSHans de Goede  * Parameters:
319554c0a3aSHans de Goede  *psdio	pointer of SDIO_DATA
320554c0a3aSHans de Goede  *addr	address to read
321554c0a3aSHans de Goede  *cnt		amount to read
322554c0a3aSHans de Goede  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
323554c0a3aSHans de Goede  *
324554c0a3aSHans de Goede  * Return:
325554c0a3aSHans de Goede  *0		Success
326554c0a3aSHans de Goede  *others	Fail
327554c0a3aSHans de Goede  */
_sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)328554c0a3aSHans de Goede s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
329554c0a3aSHans de Goede {
330554c0a3aSHans de Goede 	struct adapter *padapter;
331554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
332affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
333554c0a3aSHans de Goede 
334554c0a3aSHans de Goede 	int err = -EPERM;
335554c0a3aSHans de Goede 	struct sdio_func *func;
336554c0a3aSHans de Goede 
337554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
338554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
339554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
340554c0a3aSHans de Goede 
341*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
342554c0a3aSHans de Goede 		return err;
343554c0a3aSHans de Goede 
344554c0a3aSHans de Goede 	func = psdio->func;
345554c0a3aSHans de Goede 
3466a9b5dd1SShobhit Kukreti 	if (unlikely((cnt == 1) || (cnt == 2))) {
347554c0a3aSHans de Goede 		int i;
34867e3e07eSHimanshu Jha 		u8 *pbuf = pdata;
349554c0a3aSHans de Goede 
3506a9b5dd1SShobhit Kukreti 		for (i = 0; i < cnt; i++) {
351554c0a3aSHans de Goede 			*(pbuf + i) = sdio_readb(func, addr + i, &err);
352554c0a3aSHans de Goede 
353*709c8e49SFabio Aiuto 			if (err)
354554c0a3aSHans de Goede 				break;
355554c0a3aSHans de Goede 		}
356554c0a3aSHans de Goede 		return err;
357554c0a3aSHans de Goede 	}
358554c0a3aSHans de Goede 
359554c0a3aSHans de Goede 	err = sdio_memcpy_fromio(func, pdata, addr, cnt);
36047af9702SRoss Schmidt 
361554c0a3aSHans de Goede 	return err;
362554c0a3aSHans de Goede }
363554c0a3aSHans de Goede 
364554c0a3aSHans de Goede /*
365554c0a3aSHans de Goede  * Use CMD53 to read data from SDIO device.
366554c0a3aSHans de Goede  *
367554c0a3aSHans de Goede  * Parameters:
368554c0a3aSHans de Goede  *psdio	pointer of SDIO_DATA
369554c0a3aSHans de Goede  *addr	address to read
370554c0a3aSHans de Goede  *cnt		amount to read
371554c0a3aSHans de Goede  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
372554c0a3aSHans de Goede  *
373554c0a3aSHans de Goede  * Return:
374554c0a3aSHans de Goede  *0		Success
375554c0a3aSHans de Goede  *others	Fail
376554c0a3aSHans de Goede  */
sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)377554c0a3aSHans de Goede s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
378554c0a3aSHans de Goede {
379554c0a3aSHans de Goede 	struct adapter *padapter;
380554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
381affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
382554c0a3aSHans de Goede 
383554c0a3aSHans de Goede 	struct sdio_func *func;
384554c0a3aSHans de Goede 	bool claim_needed;
385554c0a3aSHans de Goede 	s32 err = -EPERM;
386554c0a3aSHans de Goede 
387554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
388554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
389554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
390554c0a3aSHans de Goede 
391*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
392554c0a3aSHans de Goede 		return err;
393*709c8e49SFabio Aiuto 
394554c0a3aSHans de Goede 	func = psdio->func;
395554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
396554c0a3aSHans de Goede 
397554c0a3aSHans de Goede 	if (claim_needed)
398554c0a3aSHans de Goede 		sdio_claim_host(func);
399554c0a3aSHans de Goede 	err = _sd_read(pintfhdl, addr, cnt, pdata);
400554c0a3aSHans de Goede 	if (claim_needed)
401554c0a3aSHans de Goede 		sdio_release_host(func);
402554c0a3aSHans de Goede 	return err;
403554c0a3aSHans de Goede }
404554c0a3aSHans de Goede 
405554c0a3aSHans de Goede /*
406554c0a3aSHans de Goede  * Use CMD53 to write data to SDIO device.
407554c0a3aSHans de Goede  * This function MUST be called after sdio_claim_host() or
408554c0a3aSHans de Goede  * in SDIO ISR(host had been claimed).
409554c0a3aSHans de Goede  *
410554c0a3aSHans de Goede  * Parameters:
411554c0a3aSHans de Goede  *psdio	pointer of SDIO_DATA
412554c0a3aSHans de Goede  *addr	address to write
413554c0a3aSHans de Goede  *cnt		amount to write
414554c0a3aSHans de Goede  *pdata	data pointer, this should be a "DMA:able scratch buffer"!
415554c0a3aSHans de Goede  *
416554c0a3aSHans de Goede  * Return:
417554c0a3aSHans de Goede  *0		Success
418554c0a3aSHans de Goede  *others	Fail
419554c0a3aSHans de Goede  */
_sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)420554c0a3aSHans de Goede s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
421554c0a3aSHans de Goede {
422554c0a3aSHans de Goede 	struct adapter *padapter;
423554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
424affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
425554c0a3aSHans de Goede 
426554c0a3aSHans de Goede 	struct sdio_func *func;
427554c0a3aSHans de Goede 	u32 size;
428554c0a3aSHans de Goede 	s32 err =  -EPERM;
429554c0a3aSHans de Goede 
430554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
431554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
432554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
433554c0a3aSHans de Goede 
434*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
435554c0a3aSHans de Goede 		return err;
436554c0a3aSHans de Goede 
437554c0a3aSHans de Goede 	func = psdio->func;
438554c0a3aSHans de Goede /*	size = sdio_align_size(func, cnt); */
439554c0a3aSHans de Goede 
4406a9b5dd1SShobhit Kukreti 	if (unlikely((cnt == 1) || (cnt == 2))) {
441554c0a3aSHans de Goede 		int i;
44267e3e07eSHimanshu Jha 		u8 *pbuf = pdata;
443554c0a3aSHans de Goede 
4446a9b5dd1SShobhit Kukreti 		for (i = 0; i < cnt; i++) {
445554c0a3aSHans de Goede 			sdio_writeb(func, *(pbuf + i), addr + i, &err);
446*709c8e49SFabio Aiuto 			if (err)
447554c0a3aSHans de Goede 				break;
448554c0a3aSHans de Goede 		}
449554c0a3aSHans de Goede 
450554c0a3aSHans de Goede 		return err;
451554c0a3aSHans de Goede 	}
452554c0a3aSHans de Goede 
453554c0a3aSHans de Goede 	size = cnt;
454554c0a3aSHans de Goede 	err = sdio_memcpy_toio(func, addr, pdata, size);
45547af9702SRoss Schmidt 
456554c0a3aSHans de Goede 	return err;
457554c0a3aSHans de Goede }
458554c0a3aSHans de Goede 
459554c0a3aSHans de Goede /*
460554c0a3aSHans de Goede  * Use CMD53 to write data to SDIO device.
461554c0a3aSHans de Goede  *
462554c0a3aSHans de Goede  * Parameters:
463554c0a3aSHans de Goede  *  psdio	pointer of SDIO_DATA
464554c0a3aSHans de Goede  *  addr	address to write
465554c0a3aSHans de Goede  *  cnt		amount to write
466554c0a3aSHans de Goede  *  pdata	data pointer, this should be a "DMA:able scratch buffer"!
467554c0a3aSHans de Goede  *
468554c0a3aSHans de Goede  * Return:
469554c0a3aSHans de Goede  *  0		Success
470554c0a3aSHans de Goede  *  others	Fail
471554c0a3aSHans de Goede  */
sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)472554c0a3aSHans de Goede s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
473554c0a3aSHans de Goede {
474554c0a3aSHans de Goede 	struct adapter *padapter;
475554c0a3aSHans de Goede 	struct dvobj_priv *psdiodev;
476affbeba3SMadhumitha Prabakaran 	struct sdio_data *psdio;
477554c0a3aSHans de Goede 	struct sdio_func *func;
478554c0a3aSHans de Goede 	bool claim_needed;
479554c0a3aSHans de Goede 	s32 err =  -EPERM;
480554c0a3aSHans de Goede 
481554c0a3aSHans de Goede 	padapter = pintfhdl->padapter;
482554c0a3aSHans de Goede 	psdiodev = pintfhdl->pintf_dev;
483554c0a3aSHans de Goede 	psdio = &psdiodev->intf_data;
484554c0a3aSHans de Goede 
485*709c8e49SFabio Aiuto 	if (padapter->bSurpriseRemoved)
486554c0a3aSHans de Goede 		return err;
487554c0a3aSHans de Goede 
488554c0a3aSHans de Goede 	func = psdio->func;
489554c0a3aSHans de Goede 	claim_needed = rtw_sdio_claim_host_needed(func);
490554c0a3aSHans de Goede 
491554c0a3aSHans de Goede 	if (claim_needed)
492554c0a3aSHans de Goede 		sdio_claim_host(func);
493554c0a3aSHans de Goede 	err = _sd_write(pintfhdl, addr, cnt, pdata);
494554c0a3aSHans de Goede 	if (claim_needed)
495554c0a3aSHans de Goede 		sdio_release_host(func);
496554c0a3aSHans de Goede 	return err;
497554c0a3aSHans de Goede }
498