diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c | |
parent | Initial commit. (diff) | |
download | linux-upstream.tar.xz linux-upstream.zip |
Adding upstream version 6.1.76.upstream/6.1.76upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c')
-rw-r--r-- | drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c new file mode 100644 index 000000000..0a0b04088 --- /dev/null +++ b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0 +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + *******************************************************************************/ + +#include <drv_types.h> +#include <rtw_debug.h> + +static bool rtw_sdio_claim_host_needed(struct sdio_func *func) +{ + struct dvobj_priv *dvobj = sdio_get_drvdata(func); + struct sdio_data *sdio_data = &dvobj->intf_data; + + if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current) + return false; + return true; +} + +inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl) +{ + struct sdio_data *sdio_data = &dvobj->intf_data; + + sdio_data->sys_sdio_irq_thd = thd_hdl; +} + +/* + * Return: + *0 Success + *others Fail + */ +s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + int err = 0, i; + struct sdio_func *func; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + + for (i = 0; i < cnt; i++) { + pdata[i] = sdio_readb(func, addr + i, &err); + if (err) + break; + } + return err; +} + +/* + * Return: + *0 Success + *others Fail + */ +s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + int err = 0; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + return err; +} + +/* + * Return: + *0 Success + *others Fail + */ +s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + int err = 0, i; + struct sdio_func *func; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + + for (i = 0; i < cnt; i++) { + sdio_writeb(func, pdata[i], addr + i, &err); + if (err) + break; + } + return err; +} + +/* + * Return: + *0 Success + *others Fail + */ +s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + int err = 0; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + return err; +} + +u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + u8 v = 0; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return v; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_readb(func, addr, err); + if (claim_needed) + sdio_release_host(func); + return v; +} + +u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + u32 v = 0; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return v; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_readl(func, addr, err); + if (claim_needed) + sdio_release_host(func); + + if (err && *err) { + int i; + + *err = 0; + for (i = 0; i < SD_IO_TRY_CNT; i++) { + if (claim_needed) + sdio_claim_host(func); + v = sdio_readl(func, addr, err); + if (claim_needed) + sdio_release_host(func); + + if (*err == 0) { + rtw_reset_continual_io_error(psdiodev); + break; + } else { + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) + padapter->bSurpriseRemoved = true; + + if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { + padapter->bSurpriseRemoved = true; + break; + } + } + } + } + return v; +} + +void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_writeb(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); +} + +void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + struct sdio_func *func; + bool claim_needed; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_writel(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + + if (err && *err) { + int i; + + *err = 0; + for (i = 0; i < SD_IO_TRY_CNT; i++) { + if (claim_needed) + sdio_claim_host(func); + sdio_writel(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + if (*err == 0) { + rtw_reset_continual_io_error(psdiodev); + break; + } else { + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) + padapter->bSurpriseRemoved = true; + + if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { + padapter->bSurpriseRemoved = true; + break; + } + } + } + + } +} + +/* + * Use CMD53 to read data from SDIO device. + * This function MUST be called after sdio_claim_host() or + * in SDIO ISR(host had been claimed). + * + * Parameters: + *psdio pointer of SDIO_DATA + *addr address to read + *cnt amount to read + *pdata pointer to put data, this should be a "DMA:able scratch buffer"! + * + * Return: + *0 Success + *others Fail + */ +s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + int err = -EPERM; + struct sdio_func *func; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + + if (unlikely((cnt == 1) || (cnt == 2))) { + int i; + u8 *pbuf = pdata; + + for (i = 0; i < cnt; i++) { + *(pbuf + i) = sdio_readb(func, addr + i, &err); + + if (err) + break; + } + return err; + } + + err = sdio_memcpy_fromio(func, pdata, addr, cnt); + + return err; +} + +/* + * Use CMD53 to read data from SDIO device. + * + * Parameters: + *psdio pointer of SDIO_DATA + *addr address to read + *cnt amount to read + *pdata pointer to put data, this should be a "DMA:able scratch buffer"! + * + * Return: + *0 Success + *others Fail + */ +s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + struct sdio_func *func; + bool claim_needed; + s32 err = -EPERM; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_read(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + return err; +} + +/* + * Use CMD53 to write data to SDIO device. + * This function MUST be called after sdio_claim_host() or + * in SDIO ISR(host had been claimed). + * + * Parameters: + *psdio pointer of SDIO_DATA + *addr address to write + *cnt amount to write + *pdata data pointer, this should be a "DMA:able scratch buffer"! + * + * Return: + *0 Success + *others Fail + */ +s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + + struct sdio_func *func; + u32 size; + s32 err = -EPERM; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; +/* size = sdio_align_size(func, cnt); */ + + if (unlikely((cnt == 1) || (cnt == 2))) { + int i; + u8 *pbuf = pdata; + + for (i = 0; i < cnt; i++) { + sdio_writeb(func, *(pbuf + i), addr + i, &err); + if (err) + break; + } + + return err; + } + + size = cnt; + err = sdio_memcpy_toio(func, addr, pdata, size); + + return err; +} + +/* + * Use CMD53 to write data to SDIO device. + * + * Parameters: + * psdio pointer of SDIO_DATA + * addr address to write + * cnt amount to write + * pdata data pointer, this should be a "DMA:able scratch buffer"! + * + * Return: + * 0 Success + * others Fail + */ +s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + struct adapter *padapter; + struct dvobj_priv *psdiodev; + struct sdio_data *psdio; + struct sdio_func *func; + bool claim_needed; + s32 err = -EPERM; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (padapter->bSurpriseRemoved) + return err; + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_write(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + return err; +} |