kernel/patches/0358-spi-hisi-sfc-v3xx-add-address-mode-check.patch

105 lines
3.5 KiB
Diff

From a009f74ef5b6cf1953abd034da40e4ba27e7e1a1 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 8 Dec 2022 21:45:25 +0800
Subject: [PATCH 36/39] spi: hisi-sfc-v3xx: add address mode check
mainline inclusion
from mainline-v5.12-rc1
commit 6d2386e36440165da782dbc5c0de40f31665e108
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d2386e36440165da782dbc5c0de40f31665e108
--------------------------------------------------------------------------
The address mode is either 3 or 4 for the controller, which is configured
by the firmware and cannot be modified in the OS driver. Get the
firmware configuration and add address mode check in the .supports_op()
to block invalid operations.
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Acked-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1611740450-47975-3-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index e679321c7e23..3cb6735aaf34 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -19,6 +19,8 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
+#define HISI_SFC_V3XX_GLB_CFG (0x100)
+#define HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE BIT(2)
#define HISI_SFC_V3XX_RAW_INT_STAT (0x120)
#define HISI_SFC_V3XX_INT_STAT (0x124)
#define HISI_SFC_V3XX_INT_MASK (0x128)
@@ -75,6 +77,7 @@ struct hisi_sfc_v3xx_host {
void __iomem *regbase;
int max_cmd_dword;
struct completion *completion;
+ u8 address_mode;
int irq;
};
@@ -172,10 +175,18 @@ static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
static bool hisi_sfc_v3xx_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
+ struct spi_device *spi = mem->spi;
+ struct hisi_sfc_v3xx_host *host;
+
+ host = spi_controller_get_devdata(spi->master);
+
if (op->data.buswidth > 4 || op->dummy.buswidth > 4 ||
op->addr.buswidth > 4 || op->cmd.buswidth > 4)
return false;
+ if (op->addr.nbytes != host->address_mode && op->addr.nbytes)
+ return false;
+
return spi_mem_default_supports_op(mem, op);
}
@@ -425,7 +436,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct hisi_sfc_v3xx_host *host;
struct spi_controller *ctlr;
- u32 version;
+ u32 version, glb_config;
int ret;
ctlr = spi_alloc_master(&pdev->dev, sizeof(*host));
@@ -474,6 +485,18 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
ctlr->num_chipselect = 1;
ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops;
+ /*
+ * The address mode of the controller is either 3 or 4,
+ * which is indicated by the address mode bit in
+ * the global config register. The register is read only
+ * for the OS driver.
+ */
+ glb_config = readl(host->regbase + HISI_SFC_V3XX_GLB_CFG);
+ if (glb_config & HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE)
+ host->address_mode = 4;
+ else
+ host->address_mode = 3;
+
version = readl(host->regbase + HISI_SFC_V3XX_VERSION);
if (version >= 0x351)
--
2.27.0