diff options
author | Jérôme Pouiller <jerome.pouiller@silabs.com> | 2022-02-26 12:21:42 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@kernel.org> | 2022-04-06 09:52:14 +0300 |
commit | 4a5fb1bbcdf1cccae1f6b9c0277b3796b2a468ef (patch) | |
tree | 73f7dc8e436a7cc61f8a7d270067f9cb46cc1daf /drivers/staging/wfx/hwio.c | |
parent | 3123109284176b1532874591f7c81f3837bbdc17 (diff) | |
download | linux-4a5fb1bbcdf1cccae1f6b9c0277b3796b2a468ef.tar.xz |
wfx: get out from the staging area
The wfx driver is now mature enough to leave the staging area.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Diffstat (limited to 'drivers/staging/wfx/hwio.c')
-rw-r--r-- | drivers/staging/wfx/hwio.c | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/drivers/staging/wfx/hwio.c b/drivers/staging/wfx/hwio.c deleted file mode 100644 index 3f9750b470be..000000000000 --- a/drivers/staging/wfx/hwio.c +++ /dev/null @@ -1,332 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Low-level I/O functions. - * - * Copyright (c) 2017-2020, Silicon Laboratories, Inc. - * Copyright (c) 2010, ST-Ericsson - */ -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/align.h> - -#include "hwio.h" -#include "wfx.h" -#include "bus.h" -#include "traces.h" - -#define WFX_HIF_BUFFER_SIZE 0x2000 - -static int wfx_read32(struct wfx_dev *wdev, int reg, u32 *val) -{ - int ret; - __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); - - *val = ~0; /* Never return undefined value */ - if (!tmp) - return -ENOMEM; - ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, tmp, sizeof(u32)); - if (ret >= 0) - *val = le32_to_cpu(*tmp); - kfree(tmp); - if (ret) - dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret); - return ret; -} - -static int wfx_write32(struct wfx_dev *wdev, int reg, u32 val) -{ - int ret; - __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); - - if (!tmp) - return -ENOMEM; - *tmp = cpu_to_le32(val); - ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, tmp, sizeof(u32)); - kfree(tmp); - if (ret) - dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret); - return ret; -} - -static int wfx_read32_locked(struct wfx_dev *wdev, int reg, u32 *val) -{ - int ret; - - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_read32(wdev, reg, val); - _trace_io_read32(reg, *val); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - return ret; -} - -static int wfx_write32_locked(struct wfx_dev *wdev, int reg, u32 val) -{ - int ret; - - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_write32(wdev, reg, val); - _trace_io_write32(reg, val); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - return ret; -} - -static int wfx_write32_bits_locked(struct wfx_dev *wdev, int reg, u32 mask, u32 val) -{ - int ret; - u32 val_r, val_w; - - WARN_ON(~mask & val); - val &= mask; - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_read32(wdev, reg, &val_r); - _trace_io_read32(reg, val_r); - if (ret < 0) - goto err; - val_w = (val_r & ~mask) | val; - if (val_w != val_r) { - ret = wfx_write32(wdev, reg, val_w); - _trace_io_write32(reg, val_w); - } -err: - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - return ret; -} - -static int wfx_indirect_read(struct wfx_dev *wdev, int reg, u32 addr, void *buf, size_t len) -{ - int ret; - int i; - u32 cfg; - u32 prefetch; - - WARN_ON(len >= WFX_HIF_BUFFER_SIZE); - WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT); - - if (reg == WFX_REG_AHB_DPORT) - prefetch = CFG_PREFETCH_AHB; - else if (reg == WFX_REG_SRAM_DPORT) - prefetch = CFG_PREFETCH_SRAM; - else - return -ENODEV; - - ret = wfx_write32(wdev, WFX_REG_BASE_ADDR, addr); - if (ret < 0) - goto err; - - ret = wfx_read32(wdev, WFX_REG_CONFIG, &cfg); - if (ret < 0) - goto err; - - ret = wfx_write32(wdev, WFX_REG_CONFIG, cfg | prefetch); - if (ret < 0) - goto err; - - for (i = 0; i < 20; i++) { - ret = wfx_read32(wdev, WFX_REG_CONFIG, &cfg); - if (ret < 0) - goto err; - if (!(cfg & prefetch)) - break; - usleep_range(200, 250); - } - if (i == 20) { - ret = -ETIMEDOUT; - goto err; - } - - ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, buf, len); - -err: - if (ret < 0) - memset(buf, 0xFF, len); /* Never return undefined value */ - return ret; -} - -static int wfx_indirect_write(struct wfx_dev *wdev, int reg, u32 addr, - const void *buf, size_t len) -{ - int ret; - - WARN_ON(len >= WFX_HIF_BUFFER_SIZE); - WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT); - ret = wfx_write32(wdev, WFX_REG_BASE_ADDR, addr); - if (ret < 0) - return ret; - - return wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, buf, len); -} - -static int wfx_indirect_read_locked(struct wfx_dev *wdev, int reg, u32 addr, - void *buf, size_t len) -{ - int ret; - - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_indirect_read(wdev, reg, addr, buf, len); - _trace_io_ind_read(reg, addr, buf, len); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - return ret; -} - -static int wfx_indirect_write_locked(struct wfx_dev *wdev, int reg, u32 addr, - const void *buf, size_t len) -{ - int ret; - - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_indirect_write(wdev, reg, addr, buf, len); - _trace_io_ind_write(reg, addr, buf, len); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - return ret; -} - -static int wfx_indirect_read32_locked(struct wfx_dev *wdev, int reg, u32 addr, u32 *val) -{ - int ret; - __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); - - if (!tmp) - return -ENOMEM; - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_indirect_read(wdev, reg, addr, tmp, sizeof(u32)); - *val = le32_to_cpu(*tmp); - _trace_io_ind_read32(reg, addr, *val); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - kfree(tmp); - return ret; -} - -static int wfx_indirect_write32_locked(struct wfx_dev *wdev, int reg, u32 addr, u32 val) -{ - int ret; - __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); - - if (!tmp) - return -ENOMEM; - *tmp = cpu_to_le32(val); - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wfx_indirect_write(wdev, reg, addr, tmp, sizeof(u32)); - _trace_io_ind_write32(reg, addr, val); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - kfree(tmp); - return ret; -} - -int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t len) -{ - int ret; - - WARN(!IS_ALIGNED((uintptr_t)buf, 4), "unaligned buffer"); - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, WFX_REG_IN_OUT_QUEUE, buf, len); - _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - if (ret) - dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret); - return ret; -} - -int wfx_data_write(struct wfx_dev *wdev, const void *buf, size_t len) -{ - int ret; - - WARN(!IS_ALIGNED((uintptr_t)buf, 4), "unaligned buffer"); - wdev->hwbus_ops->lock(wdev->hwbus_priv); - ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, WFX_REG_IN_OUT_QUEUE, buf, len); - _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len); - wdev->hwbus_ops->unlock(wdev->hwbus_priv); - if (ret) - dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret); - return ret; -} - -int wfx_sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) -{ - return wfx_indirect_read_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); -} - -int wfx_ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) -{ - return wfx_indirect_read_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); -} - -int wfx_sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) -{ - return wfx_indirect_write_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); -} - -int wfx_ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) -{ - return wfx_indirect_write_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); -} - -int wfx_sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) -{ - return wfx_indirect_read32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); -} - -int wfx_ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) -{ - return wfx_indirect_read32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); -} - -int wfx_sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) -{ - return wfx_indirect_write32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); -} - -int wfx_ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) -{ - return wfx_indirect_write32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); -} - -int wfx_config_reg_read(struct wfx_dev *wdev, u32 *val) -{ - return wfx_read32_locked(wdev, WFX_REG_CONFIG, val); -} - -int wfx_config_reg_write(struct wfx_dev *wdev, u32 val) -{ - return wfx_write32_locked(wdev, WFX_REG_CONFIG, val); -} - -int wfx_config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) -{ - return wfx_write32_bits_locked(wdev, WFX_REG_CONFIG, mask, val); -} - -int wfx_control_reg_read(struct wfx_dev *wdev, u32 *val) -{ - return wfx_read32_locked(wdev, WFX_REG_CONTROL, val); -} - -int wfx_control_reg_write(struct wfx_dev *wdev, u32 val) -{ - return wfx_write32_locked(wdev, WFX_REG_CONTROL, val); -} - -int wfx_control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) -{ - return wfx_write32_bits_locked(wdev, WFX_REG_CONTROL, mask, val); -} - -int wfx_igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val) -{ - int ret; - - *val = ~0; /* Never return undefined value */ - ret = wfx_write32_locked(wdev, WFX_REG_SET_GEN_R_W, IGPR_RW | index << 24); - if (ret) - return ret; - ret = wfx_read32_locked(wdev, WFX_REG_SET_GEN_R_W, val); - if (ret) - return ret; - *val &= IGPR_VALUE; - return ret; -} - -int wfx_igpr_reg_write(struct wfx_dev *wdev, int index, u32 val) -{ - return wfx_write32_locked(wdev, WFX_REG_SET_GEN_R_W, index << 24 | val); -} |