Skip to content

Commit ad00df9

Browse files
LorenzoBianconigregkh
authored andcommitted
spi: airoha: do not keep {tx,rx} dma buffer always mapped
[ Upstream commit 7a4b3eb ] 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> Link: https://patch.msgid.link/20240922-airoha-spi-fixes-v3-1-f958802b3d68@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: 20d7b23 ("spi: airoha: switch back to non-dma mode in the case of error") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 182221d commit ad00df9

File tree

1 file changed

+71
-83
lines changed

1 file changed

+71
-83
lines changed

drivers/spi/spi-airoha-snfi.c

Lines changed: 71 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,6 @@ enum airoha_snand_cs {
214214
SPI_CHIP_SEL_LOW,
215215
};
216216

217-
struct airoha_snand_dev {
218-
size_t buf_len;
219-
220-
u8 *txrx_buf;
221-
dma_addr_t dma_addr;
222-
};
223-
224217
struct airoha_snand_ctrl {
225218
struct device *dev;
226219
struct regmap *regmap_ctrl;
@@ -657,9 +650,9 @@ static bool airoha_snand_supports_op(struct spi_mem *mem,
657650

658651
static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
659652
{
660-
struct airoha_snand_dev *as_dev = spi_get_ctldata(desc->mem->spi);
653+
u8 *txrx_buf = spi_get_ctldata(desc->mem->spi);
661654

662-
if (!as_dev->txrx_buf)
655+
if (!txrx_buf)
663656
return -EINVAL;
664657

665658
if (desc->info.offset + desc->info.length > U32_MAX)
@@ -678,10 +671,11 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
678671
static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
679672
u64 offs, size_t len, void *buf)
680673
{
681-
struct spi_device *spi = desc->mem->spi;
682-
struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
683674
struct spi_mem_op *op = &desc->info.op_tmpl;
675+
struct spi_device *spi = desc->mem->spi;
684676
struct airoha_snand_ctrl *as_ctrl;
677+
u8 *txrx_buf = spi_get_ctldata(spi);
678+
dma_addr_t dma_addr;
685679
u32 val, rd_mode;
686680
int err;
687681

@@ -706,14 +700,17 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
706700
if (err)
707701
return err;
708702

709-
dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
710-
as_dev->buf_len, DMA_BIDIRECTIONAL);
703+
dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
704+
DMA_FROM_DEVICE);
705+
err = dma_mapping_error(as_ctrl->dev, dma_addr);
706+
if (err)
707+
return err;
711708

712709
/* set dma addr */
713710
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
714-
as_dev->dma_addr);
711+
dma_addr);
715712
if (err)
716-
return err;
713+
goto error_dma_unmap;
717714

718715
/* set cust sec size */
719716
val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
@@ -722,58 +719,58 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
722719
REG_SPI_NFI_SNF_MISC_CTL2,
723720
SPI_NFI_READ_DATA_BYTE_NUM, val);
724721
if (err)
725-
return err;
722+
goto error_dma_unmap;
726723

727724
/* set read command */
728725
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,
729726
op->cmd.opcode);
730727
if (err)
731-
return err;
728+
goto error_dma_unmap;
732729

733730
/* set read mode */
734731
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
735732
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode));
736733
if (err)
737-
return err;
734+
goto error_dma_unmap;
738735

739736
/* set read addr */
740737
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);
741738
if (err)
742-
return err;
739+
goto error_dma_unmap;
743740

744741
/* set nfi read */
745742
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
746743
SPI_NFI_OPMODE,
747744
FIELD_PREP(SPI_NFI_OPMODE, 6));
748745
if (err)
749-
return err;
746+
goto error_dma_unmap;
750747

751748
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
752749
SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE);
753750
if (err)
754-
return err;
751+
goto error_dma_unmap;
755752

756753
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0);
757754
if (err)
758-
return err;
755+
goto error_dma_unmap;
759756

760757
/* trigger dma start read */
761758
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
762759
SPI_NFI_RD_TRIG);
763760
if (err)
764-
return err;
761+
goto error_dma_unmap;
765762

766763
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
767764
SPI_NFI_RD_TRIG);
768765
if (err)
769-
return err;
766+
goto error_dma_unmap;
770767

771768
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
772769
REG_SPI_NFI_SNF_STA_CTL1, val,
773770
(val & SPI_NFI_READ_FROM_CACHE_DONE),
774771
0, 1 * USEC_PER_SEC);
775772
if (err)
776-
return err;
773+
goto error_dma_unmap;
777774

778775
/*
779776
* SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end
@@ -783,35 +780,41 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
783780
SPI_NFI_READ_FROM_CACHE_DONE,
784781
SPI_NFI_READ_FROM_CACHE_DONE);
785782
if (err)
786-
return err;
783+
goto error_dma_unmap;
787784

788785
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
789786
val, (val & SPI_NFI_AHB_DONE), 0,
790787
1 * USEC_PER_SEC);
791788
if (err)
792-
return err;
789+
goto error_dma_unmap;
793790

794791
/* DMA read need delay for data ready from controller to DRAM */
795792
udelay(1);
796793

797-
dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
798-
as_dev->buf_len, DMA_BIDIRECTIONAL);
794+
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
795+
DMA_FROM_DEVICE);
799796
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
800797
if (err < 0)
801798
return err;
802799

803-
memcpy(buf, as_dev->txrx_buf + offs, len);
800+
memcpy(buf, txrx_buf + offs, len);
804801

805802
return len;
803+
804+
error_dma_unmap:
805+
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
806+
DMA_FROM_DEVICE);
807+
return err;
806808
}
807809

808810
static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
809811
u64 offs, size_t len, const void *buf)
810812
{
811-
struct spi_device *spi = desc->mem->spi;
812-
struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
813813
struct spi_mem_op *op = &desc->info.op_tmpl;
814+
struct spi_device *spi = desc->mem->spi;
815+
u8 *txrx_buf = spi_get_ctldata(spi);
814816
struct airoha_snand_ctrl *as_ctrl;
817+
dma_addr_t dma_addr;
815818
u32 wr_mode, val;
816819
int err;
817820

@@ -820,19 +823,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
820823
if (err < 0)
821824
return err;
822825

823-
dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
824-
as_dev->buf_len, DMA_BIDIRECTIONAL);
825-
memcpy(as_dev->txrx_buf + offs, buf, len);
826-
dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
827-
as_dev->buf_len, DMA_BIDIRECTIONAL);
826+
memcpy(txrx_buf + offs, buf, len);
827+
dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
828+
DMA_TO_DEVICE);
829+
err = dma_mapping_error(as_ctrl->dev, dma_addr);
830+
if (err)
831+
return err;
828832

829833
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
830834
if (err < 0)
831-
return err;
835+
goto error_dma_unmap;
832836

833837
err = airoha_snand_nfi_config(as_ctrl);
834838
if (err)
835-
return err;
839+
goto error_dma_unmap;
836840

837841
if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||
838842
op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)
@@ -841,75 +845,75 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
841845
wr_mode = 0;
842846

843847
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
844-
as_dev->dma_addr);
848+
dma_addr);
845849
if (err)
846-
return err;
850+
goto error_dma_unmap;
847851

848852
val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM,
849853
as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
850854
err = regmap_update_bits(as_ctrl->regmap_nfi,
851855
REG_SPI_NFI_SNF_MISC_CTL2,
852856
SPI_NFI_PROG_LOAD_BYTE_NUM, val);
853857
if (err)
854-
return err;
858+
goto error_dma_unmap;
855859

856860
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,
857861
FIELD_PREP(SPI_NFI_PG_LOAD_CMD,
858862
op->cmd.opcode));
859863
if (err)
860-
return err;
864+
goto error_dma_unmap;
861865

862866
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
863867
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));
864868
if (err)
865-
return err;
869+
goto error_dma_unmap;
866870

867871
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);
868872
if (err)
869-
return err;
873+
goto error_dma_unmap;
870874

871875
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
872876
SPI_NFI_READ_MODE);
873877
if (err)
874-
return err;
878+
goto error_dma_unmap;
875879

876880
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
877881
SPI_NFI_OPMODE,
878882
FIELD_PREP(SPI_NFI_OPMODE, 3));
879883
if (err)
880-
return err;
884+
goto error_dma_unmap;
881885

882886
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
883887
SPI_NFI_DMA_MODE);
884888
if (err)
885-
return err;
889+
goto error_dma_unmap;
886890

887891
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80);
888892
if (err)
889-
return err;
893+
goto error_dma_unmap;
890894

891895
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
892896
SPI_NFI_WR_TRIG);
893897
if (err)
894-
return err;
898+
goto error_dma_unmap;
895899

896900
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
897901
SPI_NFI_WR_TRIG);
898902
if (err)
899-
return err;
903+
goto error_dma_unmap;
900904

901905
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
902906
val, (val & SPI_NFI_AHB_DONE), 0,
903907
1 * USEC_PER_SEC);
904908
if (err)
905-
return err;
909+
goto error_dma_unmap;
906910

907911
err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
908912
REG_SPI_NFI_SNF_STA_CTL1, val,
909913
(val & SPI_NFI_LOAD_TO_CACHE_DONE),
910914
0, 1 * USEC_PER_SEC);
911915
if (err)
912-
return err;
916+
goto error_dma_unmap;
913917

914918
/*
915919
* SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end
@@ -919,13 +923,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
919923
SPI_NFI_LOAD_TO_CACHE_DONE,
920924
SPI_NFI_LOAD_TO_CACHE_DONE);
921925
if (err)
922-
return err;
926+
goto error_dma_unmap;
923927

928+
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
929+
DMA_TO_DEVICE);
924930
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
925931
if (err < 0)
926932
return err;
927933

928934
return len;
935+
936+
error_dma_unmap:
937+
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
938+
DMA_TO_DEVICE);
939+
return err;
929940
}
930941

931942
static int airoha_snand_exec_op(struct spi_mem *mem,
@@ -1016,42 +1027,20 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = {
10161027
static int airoha_snand_setup(struct spi_device *spi)
10171028
{
10181029
struct airoha_snand_ctrl *as_ctrl;
1019-
struct airoha_snand_dev *as_dev;
1020-
1021-
as_ctrl = spi_controller_get_devdata(spi->controller);
1022-
1023-
as_dev = devm_kzalloc(as_ctrl->dev, sizeof(*as_dev), GFP_KERNEL);
1024-
if (!as_dev)
1025-
return -ENOMEM;
1030+
u8 *txrx_buf;
10261031

10271032
/* prepare device buffer */
1028-
as_dev->buf_len = SPI_NAND_CACHE_SIZE;
1029-
as_dev->txrx_buf = devm_kzalloc(as_ctrl->dev, as_dev->buf_len,
1030-
GFP_KERNEL);
1031-
if (!as_dev->txrx_buf)
1032-
return -ENOMEM;
1033-
1034-
as_dev->dma_addr = dma_map_single(as_ctrl->dev, as_dev->txrx_buf,
1035-
as_dev->buf_len, DMA_BIDIRECTIONAL);
1036-
if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))
1033+
as_ctrl = spi_controller_get_devdata(spi->controller);
1034+
txrx_buf = devm_kzalloc(as_ctrl->dev, SPI_NAND_CACHE_SIZE,
1035+
GFP_KERNEL);
1036+
if (!txrx_buf)
10371037
return -ENOMEM;
10381038

1039-
spi_set_ctldata(spi, as_dev);
1039+
spi_set_ctldata(spi, txrx_buf);
10401040

10411041
return 0;
10421042
}
10431043

1044-
static void airoha_snand_cleanup(struct spi_device *spi)
1045-
{
1046-
struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
1047-
struct airoha_snand_ctrl *as_ctrl;
1048-
1049-
as_ctrl = spi_controller_get_devdata(spi->controller);
1050-
dma_unmap_single(as_ctrl->dev, as_dev->dma_addr,
1051-
as_dev->buf_len, DMA_BIDIRECTIONAL);
1052-
spi_set_ctldata(spi, NULL);
1053-
}
1054-
10551044
static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl)
10561045
{
10571046
u32 val, sec_size, sec_num;
@@ -1153,7 +1142,6 @@ static int airoha_snand_probe(struct platform_device *pdev)
11531142
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
11541143
ctrl->mode_bits = SPI_RX_DUAL;
11551144
ctrl->setup = airoha_snand_setup;
1156-
ctrl->cleanup = airoha_snand_cleanup;
11571145
device_set_node(&ctrl->dev, dev_fwnode(dev));
11581146

11591147
err = airoha_snand_nfi_setup(as_ctrl);

0 commit comments

Comments
 (0)