* [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules
@ 2024-09-19 16:57 Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read() Lorenzo Bianconi
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Lorenzo Bianconi @ 2024-09-19 16:57 UTC (permalink / raw)
To: Lorenzo Bianconi, Ray Liu, Mark Brown, AngeloGioacchino Del Regno,
Andy Shevchenko
Cc: Christian Marangi, linux-arm-kernel, linux-spi, upstream
Fix errors detected running mtd_test kernel test modules.
---
Changes in v2:
- repost patch 3/4 and 4/4 improving commit log
- Link to v1: https://lore.kernel.org/r/20240913-airoha-spi-fixes-v1-0-de2e74ed4664@kernel.org
---
Lorenzo Bianconi (2):
spi: airoha: remove read cache in airoha_snand_dirmap_read()
spi: airoha: do not keep {tx,rx} dma buffer always mapped
drivers/spi/spi-airoha-snfi.c | 173 +++++++++++++++++-------------------------
1 file changed, 69 insertions(+), 104 deletions(-)
---
base-commit: 220bc4acfbc26376962b155db5160de942a5e4cf
change-id: 20240913-airoha-spi-fixes-56bb430fb99f
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read()
2024-09-19 16:57 [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Lorenzo Bianconi
@ 2024-09-19 16:57 ` Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped Lorenzo Bianconi
2024-09-20 9:40 ` (subset) [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Mark Brown
2 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Bianconi @ 2024-09-19 16:57 UTC (permalink / raw)
To: Lorenzo Bianconi, Ray Liu, Mark Brown, AngeloGioacchino Del Regno,
Andy Shevchenko
Cc: Christian Marangi, linux-arm-kernel, linux-spi, upstream
Current upstream driver reports errors running mtd_oobtest kernel module
test:
root@OpenWrt:/# insmod mtd_test.ko
root@OpenWrt:/# insmod mtd_oobtest.ko dev=5
[ 7023.730584] =================================================
[ 7023.736399] mtd_oobtest: MTD device: 5
[ 7023.740160] mtd_oobtest: MTD device size 3670016, eraseblock size 131072, page size 2048, count of eraseblocks 28, pages per eraseblock 64, OOB size 128
[ 7023.753837] mtd_test: scanning for bad eraseblocks
[ 7023.758636] mtd_test: scanned 28 eraseblocks, 0 are bad
[ 7023.763861] mtd_oobtest: test 1 of 5
[ 7024.042076] mtd_oobtest: writing OOBs of whole device
[ 7024.682069] mtd_oobtest: written up to eraseblock 0
[ 7041.962077] mtd_oobtest: written 28 eraseblocks
[ 7041.966626] mtd_oobtest: verifying all eraseblocks
[ 7041.972276] mtd_oobtest: error @addr[0x0:0x0] 0xff -> 0xe diff 0xf1
[ 7041.978550] mtd_oobtest: error @addr[0x0:0x1] 0xff -> 0x10 diff 0xef
[ 7041.984932] mtd_oobtest: error @addr[0x0:0x2] 0xff -> 0x82 diff 0x7d
[ 7041.991293] mtd_oobtest: error @addr[0x0:0x3] 0xff -> 0x10 diff 0xef
[ 7041.997659] mtd_oobtest: error @addr[0x0:0x4] 0xff -> 0x0 diff 0xff
[ 7042.003942] mtd_oobtest: error @addr[0x0:0x5] 0xff -> 0x8a diff 0x75
[ 7042.010294] mtd_oobtest: error @addr[0x0:0x6] 0xff -> 0x20 diff 0xdf
[ 7042.016659] mtd_oobtest: error @addr[0x0:0x7] 0xff -> 0x1 diff 0xfe
[ 7042.022935] mtd_oobtest: error @addr[0x0:0x8] 0xff -> 0x2e diff 0xd1
[ 7042.029295] mtd_oobtest: error @addr[0x0:0x9] 0xff -> 0x40 diff 0xbf
[ 7042.035661] mtd_oobtest: error @addr[0x0:0xa] 0xff -> 0x0 diff 0xff
[ 7042.041935] mtd_oobtest: error @addr[0x0:0xb] 0xff -> 0x89 diff 0x76
[ 7042.048300] mtd_oobtest: error @addr[0x0:0xc] 0xff -> 0x82 diff 0x7d
[ 7042.054662] mtd_oobtest: error @addr[0x0:0xd] 0xff -> 0x15 diff 0xea
[ 7042.061014] mtd_oobtest: error @addr[0x0:0xe] 0xff -> 0x90 diff 0x6f
[ 7042.067380] mtd_oobtest: error @addr[0x0:0xf] 0xff -> 0x0 diff 0xff
....
[ 7432.421369] mtd_oobtest: error @addr[0x237800:0x36] 0xff -> 0x5f diff 0xa0
[ 7432.428242] mtd_oobtest: error @addr[0x237800:0x37] 0xff -> 0x21 diff 0xde
[ 7432.435118] mtd_oobtest: error: verify failed at 0x237800
[ 7432.440510] mtd_oobtest: error: too many errors
[ 7432.445053] mtd_oobtest: error -1 occurred
The above errors are due to the buggy logic in the 'read cache' available
in airoha_snand_dirmap_read() routine since there are some corner cases
where we are missing data updates. Since we do not get any read/write speed
improvement using the cache (according to the mtd_speedtest kernel
module test), in order to fix the mtd_oobtest test, remove the 'read cache'
in airoha_snand_dirmap_read routine. Now the driver is passing all the
tests available in mtd_test suite.
Fixes: a403997c1201 ("spi: airoha: add SPI-NAND Flash controller driver")
Tested-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/spi/spi-airoha-snfi.c | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
index c71be702cf6f..94458df53eae 100644
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -211,9 +211,6 @@ struct airoha_snand_dev {
u8 *txrx_buf;
dma_addr_t dma_addr;
-
- u64 cur_page_num;
- bool data_need_update;
};
struct airoha_snand_ctrl {
@@ -644,11 +641,6 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
u32 val, rd_mode;
int err;
- if (!as_dev->data_need_update)
- return len;
-
- as_dev->data_need_update = false;
-
switch (op->cmd.opcode) {
case SPI_NAND_OP_READ_FROM_CACHE_DUAL:
rd_mode = 1;
@@ -895,23 +887,11 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
static int airoha_snand_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
- struct airoha_snand_dev *as_dev = spi_get_ctldata(mem->spi);
u8 data[8], cmd, opcode = op->cmd.opcode;
struct airoha_snand_ctrl *as_ctrl;
int i, err;
as_ctrl = spi_controller_get_devdata(mem->spi->controller);
- if (opcode == SPI_NAND_OP_PROGRAM_EXECUTE &&
- op->addr.val == as_dev->cur_page_num) {
- as_dev->data_need_update = true;
- } else if (opcode == SPI_NAND_OP_PAGE_READ) {
- if (!as_dev->data_need_update &&
- op->addr.val == as_dev->cur_page_num)
- return 0;
-
- as_dev->data_need_update = true;
- as_dev->cur_page_num = op->addr.val;
- }
/* switch to manual mode */
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
@@ -996,7 +976,6 @@ static int airoha_snand_setup(struct spi_device *spi)
if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))
return -ENOMEM;
- as_dev->data_need_update = true;
spi_set_ctldata(spi, as_dev);
return 0;
--
2.46.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped
2024-09-19 16:57 [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read() Lorenzo Bianconi
@ 2024-09-19 16:57 ` Lorenzo Bianconi
2024-09-20 14:17 ` Andy Shevchenko
2024-09-20 9:40 ` (subset) [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Mark Brown
2 siblings, 1 reply; 6+ messages in thread
From: Lorenzo Bianconi @ 2024-09-19 16:57 UTC (permalink / raw)
To: Lorenzo Bianconi, Ray Liu, Mark Brown, AngeloGioacchino Del Regno,
Andy Shevchenko
Cc: Christian Marangi, linux-arm-kernel, linux-spi, upstream
DMA map txrx_buf on demand in airoha_snand_dirmap_read and
airoha_snand_dirmap_write routines and do not keep it always mapped.
This patch is not fixing any bug or introducing any functional change
to the driver, it just simplifies the code and improve code readability
without introducing any performance degradation according to the results
obtained from the mtd_speedtest kernel module test.
root@OpenWrt:# insmod mtd_test.ko
root@OpenWrt:# insmod mtd_speedtest.ko dev=5
[ 49.849869] =================================================
[ 49.855659] mtd_speedtest: MTD device: 5
[ 49.859583] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 128
[ 49.874622] mtd_test: scanning for bad eraseblocks
[ 49.879433] mtd_test: scanned 64 eraseblocks, 0 are bad
[ 50.106372] mtd_speedtest: testing eraseblock write speed
[ 53.083380] mtd_speedtest: eraseblock write speed is 2756 KiB/s
[ 53.089322] mtd_speedtest: testing eraseblock read speed
[ 54.143360] mtd_speedtest: eraseblock read speed is 7811 KiB/s
[ 54.370365] mtd_speedtest: testing page write speed
[ 57.349480] mtd_speedtest: page write speed is 2754 KiB/s
[ 57.354895] mtd_speedtest: testing page read speed
[ 58.410431] mtd_speedtest: page read speed is 7796 KiB/s
[ 58.636805] mtd_speedtest: testing 2 page write speed
[ 61.612427] mtd_speedtest: 2 page write speed is 2757 KiB/s
[ 61.618021] mtd_speedtest: testing 2 page read speed
[ 62.672653] mtd_speedtest: 2 page read speed is 7804 KiB/s
[ 62.678159] mtd_speedtest: Testing erase speed
[ 62.903617] mtd_speedtest: erase speed is 37063 KiB/s
[ 62.908678] mtd_speedtest: Testing 2x multi-block erase speed
[ 63.134083] mtd_speedtest: 2x multi-block erase speed is 37292 KiB/s
[ 63.140442] mtd_speedtest: Testing 4x multi-block erase speed
[ 63.364262] mtd_speedtest: 4x multi-block erase speed is 37566 KiB/s
[ 63.370632] mtd_speedtest: Testing 8x multi-block erase speed
[ 63.595740] mtd_speedtest: 8x multi-block erase speed is 37344 KiB/s
[ 63.602089] mtd_speedtest: Testing 16x multi-block erase speed
[ 63.827426] mtd_speedtest: 16x multi-block erase speed is 37320 KiB/s
[ 63.833860] mtd_speedtest: Testing 32x multi-block erase speed
[ 64.059389] mtd_speedtest: 32x multi-block erase speed is 37288 KiB/s
[ 64.065833] mtd_speedtest: Testing 64x multi-block erase speed
[ 64.290609] mtd_speedtest: 64x multi-block erase speed is 37415 KiB/s
[ 64.297063] mtd_speedtest: finished
[ 64.300555] =================================================
Tested-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/spi/spi-airoha-snfi.c | 152 +++++++++++++++++++-----------------------
1 file changed, 69 insertions(+), 83 deletions(-)
diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
index 94458df53eae..16c528883cca 100644
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -206,13 +206,6 @@ enum airoha_snand_cs {
SPI_CHIP_SEL_LOW,
};
-struct airoha_snand_dev {
- size_t buf_len;
-
- u8 *txrx_buf;
- dma_addr_t dma_addr;
-};
-
struct airoha_snand_ctrl {
struct device *dev;
struct regmap *regmap_ctrl;
@@ -617,9 +610,9 @@ static bool airoha_snand_supports_op(struct spi_mem *mem,
static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
- struct airoha_snand_dev *as_dev = spi_get_ctldata(desc->mem->spi);
+ u8 *txrx_buf = spi_get_ctldata(desc->mem->spi);
- if (!as_dev->txrx_buf)
+ if (!txrx_buf)
return -EINVAL;
if (desc->info.offset + desc->info.length > U32_MAX)
@@ -634,10 +627,11 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, void *buf)
{
- struct spi_device *spi = desc->mem->spi;
- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
struct spi_mem_op *op = &desc->info.op_tmpl;
+ struct spi_device *spi = desc->mem->spi;
struct airoha_snand_ctrl *as_ctrl;
+ u8 *txrx_buf = spi_get_ctldata(spi);
+ dma_addr_t dma_addr;
u32 val, rd_mode;
int err;
@@ -662,14 +656,16 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (err)
return err;
- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(as_ctrl->dev, dma_addr))
+ return -ENOMEM;
/* set dma addr */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
- as_dev->dma_addr);
+ dma_addr);
if (err)
- return err;
+ goto error_dma_unmap;
/* set cust sec size */
val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
@@ -678,58 +674,58 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
REG_SPI_NFI_SNF_MISC_CTL2,
SPI_NFI_READ_DATA_BYTE_NUM, val);
if (err)
- return err;
+ goto error_dma_unmap;
/* set read command */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,
op->cmd.opcode);
if (err)
- return err;
+ goto error_dma_unmap;
/* set read mode */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode));
if (err)
- return err;
+ goto error_dma_unmap;
/* set read addr */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);
if (err)
- return err;
+ goto error_dma_unmap;
/* set nfi read */
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
SPI_NFI_OPMODE,
FIELD_PREP(SPI_NFI_OPMODE, 6));
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0);
if (err)
- return err;
+ goto error_dma_unmap;
/* trigger dma start read */
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_RD_TRIG);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_RD_TRIG);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
REG_SPI_NFI_SNF_STA_CTL1, val,
(val & SPI_NFI_READ_FROM_CACHE_DONE),
0, 1 * USEC_PER_SEC);
if (err)
- return err;
+ goto error_dma_unmap;
/*
* SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end
@@ -739,35 +735,41 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
SPI_NFI_READ_FROM_CACHE_DONE,
SPI_NFI_READ_FROM_CACHE_DONE);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
val, (val & SPI_NFI_AHB_DONE), 0,
1 * USEC_PER_SEC);
if (err)
- return err;
+ goto error_dma_unmap;
/* DMA read need delay for data ready from controller to DRAM */
udelay(1);
- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
if (err < 0)
return err;
- memcpy(buf, as_dev->txrx_buf + offs, len);
+ memcpy(buf, txrx_buf + offs, len);
return len;
+
+error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
+ return err;
}
static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, const void *buf)
{
- struct spi_device *spi = desc->mem->spi;
- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
struct spi_mem_op *op = &desc->info.op_tmpl;
+ struct spi_device *spi = desc->mem->spi;
+ u8 *txrx_buf = spi_get_ctldata(spi);
struct airoha_snand_ctrl *as_ctrl;
+ dma_addr_t dma_addr;
u32 wr_mode, val;
int err;
@@ -776,19 +778,19 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
if (err < 0)
return err;
- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
- memcpy(as_dev->txrx_buf + offs, buf, len);
- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
+ memcpy(txrx_buf + offs, buf, len);
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(as_ctrl->dev, dma_addr))
+ return -ENOMEM;
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
if (err < 0)
- return err;
+ goto error_dma_unmap;
err = airoha_snand_nfi_config(as_ctrl);
if (err)
- return err;
+ goto error_dma_unmap;
if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||
op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)
@@ -797,9 +799,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
wr_mode = 0;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
- as_dev->dma_addr);
+ dma_addr);
if (err)
- return err;
+ goto error_dma_unmap;
val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM,
as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
@@ -807,65 +809,65 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
REG_SPI_NFI_SNF_MISC_CTL2,
SPI_NFI_PROG_LOAD_BYTE_NUM, val);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,
FIELD_PREP(SPI_NFI_PG_LOAD_CMD,
op->cmd.opcode));
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
SPI_NFI_READ_MODE);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
SPI_NFI_OPMODE,
FIELD_PREP(SPI_NFI_OPMODE, 3));
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
SPI_NFI_DMA_MODE);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_WR_TRIG);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_WR_TRIG);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
val, (val & SPI_NFI_AHB_DONE), 0,
1 * USEC_PER_SEC);
if (err)
- return err;
+ goto error_dma_unmap;
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
REG_SPI_NFI_SNF_STA_CTL1, val,
(val & SPI_NFI_LOAD_TO_CACHE_DONE),
0, 1 * USEC_PER_SEC);
if (err)
- return err;
+ goto error_dma_unmap;
/*
* SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end
@@ -875,13 +877,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
SPI_NFI_LOAD_TO_CACHE_DONE,
SPI_NFI_LOAD_TO_CACHE_DONE);
if (err)
- return err;
+ goto error_dma_unmap;
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
if (err < 0)
return err;
return len;
+
+error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
+ return err;
}
static int airoha_snand_exec_op(struct spi_mem *mem,
@@ -956,42 +965,20 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = {
static int airoha_snand_setup(struct spi_device *spi)
{
struct airoha_snand_ctrl *as_ctrl;
- struct airoha_snand_dev *as_dev;
-
- as_ctrl = spi_controller_get_devdata(spi->controller);
-
- as_dev = devm_kzalloc(as_ctrl->dev, sizeof(*as_dev), GFP_KERNEL);
- if (!as_dev)
- return -ENOMEM;
+ u8 *txrx_buf;
/* prepare device buffer */
- as_dev->buf_len = SPI_NAND_CACHE_SIZE;
- as_dev->txrx_buf = devm_kzalloc(as_ctrl->dev, as_dev->buf_len,
- GFP_KERNEL);
- if (!as_dev->txrx_buf)
- return -ENOMEM;
-
- as_dev->dma_addr = dma_map_single(as_ctrl->dev, as_dev->txrx_buf,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))
+ as_ctrl = spi_controller_get_devdata(spi->controller);
+ txrx_buf = devm_kzalloc(as_ctrl->dev, SPI_NAND_CACHE_SIZE,
+ GFP_KERNEL);
+ if (!txrx_buf)
return -ENOMEM;
- spi_set_ctldata(spi, as_dev);
+ spi_set_ctldata(spi, txrx_buf);
return 0;
}
-static void airoha_snand_cleanup(struct spi_device *spi)
-{
- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
- struct airoha_snand_ctrl *as_ctrl;
-
- as_ctrl = spi_controller_get_devdata(spi->controller);
- dma_unmap_single(as_ctrl->dev, as_dev->dma_addr,
- as_dev->buf_len, DMA_BIDIRECTIONAL);
- spi_set_ctldata(spi, NULL);
-}
-
static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl)
{
u32 val, sec_size, sec_num;
@@ -1093,7 +1080,6 @@ static int airoha_snand_probe(struct platform_device *pdev)
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
ctrl->mode_bits = SPI_RX_DUAL;
ctrl->setup = airoha_snand_setup;
- ctrl->cleanup = airoha_snand_cleanup;
device_set_node(&ctrl->dev, dev_fwnode(dev));
err = airoha_snand_nfi_setup(as_ctrl);
--
2.46.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: (subset) [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules
2024-09-19 16:57 [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read() Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped Lorenzo Bianconi
@ 2024-09-20 9:40 ` Mark Brown
2 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2024-09-20 9:40 UTC (permalink / raw)
To: Ray Liu, AngeloGioacchino Del Regno, Andy Shevchenko,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-spi, upstream
On Thu, 19 Sep 2024 18:57:15 +0200, Lorenzo Bianconi wrote:
> Fix errors detected running mtd_test kernel test modules.
>
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
Thanks!
[1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read()
commit: fffca269e4f31c3633c6d810833ba1b184407915
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped
2024-09-19 16:57 ` [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped Lorenzo Bianconi
@ 2024-09-20 14:17 ` Andy Shevchenko
2024-09-20 14:42 ` Lorenzo Bianconi
0 siblings, 1 reply; 6+ messages in thread
From: Andy Shevchenko @ 2024-09-20 14:17 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Ray Liu, Mark Brown, AngeloGioacchino Del Regno,
Christian Marangi, linux-arm-kernel, linux-spi, upstream
On Thu, Sep 19, 2024 at 06:57:17PM +0200, Lorenzo Bianconi wrote:
> DMA map txrx_buf on demand in airoha_snand_dirmap_read and
> airoha_snand_dirmap_write routines and do not keep it always mapped.
> This patch is not fixing any bug or introducing any functional change
> to the driver, it just simplifies the code and improve code readability
> without introducing any performance degradation according to the results
> obtained from the mtd_speedtest kernel module test.
...
> + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
> + DMA_FROM_DEVICE);
> + if (dma_mapping_error(as_ctrl->dev, dma_addr))
> + return -ENOMEM;
Shouldn't this be
err = dma_mapping_error(as_ctrl->dev, dma_addr);
if (err)
return err;
?
...
> + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
> + DMA_TO_DEVICE);
> + if (dma_mapping_error(as_ctrl->dev, dma_addr))
> + return -ENOMEM;
Ditto.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped
2024-09-20 14:17 ` Andy Shevchenko
@ 2024-09-20 14:42 ` Lorenzo Bianconi
0 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Bianconi @ 2024-09-20 14:42 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Ray Liu, Mark Brown, AngeloGioacchino Del Regno,
Christian Marangi, linux-arm-kernel, linux-spi, upstream
[-- Attachment #1: Type: text/plain, Size: 1175 bytes --]
On Sep 20, Andy Shevchenko wrote:
> On Thu, Sep 19, 2024 at 06:57:17PM +0200, Lorenzo Bianconi wrote:
> > DMA map txrx_buf on demand in airoha_snand_dirmap_read and
> > airoha_snand_dirmap_write routines and do not keep it always mapped.
> > This patch is not fixing any bug or introducing any functional change
> > to the driver, it just simplifies the code and improve code readability
> > without introducing any performance degradation according to the results
> > obtained from the mtd_speedtest kernel module test.
>
> ...
>
> > + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
> > + DMA_FROM_DEVICE);
> > + if (dma_mapping_error(as_ctrl->dev, dma_addr))
> > + return -ENOMEM;
>
> Shouldn't this be
>
> err = dma_mapping_error(as_ctrl->dev, dma_addr);
> if (err)
> return err;
>
> ?
>
> ...
>
> > + dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
> > + DMA_TO_DEVICE);
> > + if (dma_mapping_error(as_ctrl->dev, dma_addr))
> > + return -ENOMEM;
>
> Ditto.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
ack, I will fix it in v3.
Rergards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-09-20 14:42 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-19 16:57 [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 1/2] spi: airoha: remove read cache in airoha_snand_dirmap_read() Lorenzo Bianconi
2024-09-19 16:57 ` [PATCH v2 2/2] spi: airoha: do not keep {tx,rx} dma buffer always mapped Lorenzo Bianconi
2024-09-20 14:17 ` Andy Shevchenko
2024-09-20 14:42 ` Lorenzo Bianconi
2024-09-20 9:40 ` (subset) [PATCH v2 0/2] spi: airoha: Fix errors reported by mtd_test kernel modules Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).