Skip to content

Commit a3daad8

Browse files
committed
Merge tag 'mtd/fixes-for-6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd fixes from Miquel Raynal: "The two most important fixes in this list are probably the SST write failure and the Qcom raw NAND controller probe failure which are due to some refactoring, otherwise there has been a series of misc fixes on the Cadence raw NAND controller driver and especially on the DMA side" * tag 'mtd/fixes-for-6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: rawnand: cadence: fix unchecked dereference mtd: spi-nor: sst: Fix SST write failure dt-bindings: mtd: cadence: document required clock-names mtd: rawnand: qcom: fix broken config in qcom_param_page_type_exec mtd: rawnand: cadence: fix incorrect device in dma_unmap_single mtd: rawnand: cadence: use dma_map_resource for sdma address mtd: rawnand: cadence: fix error code in cadence_nand_init()
2 parents 534a2c6 + 1dbf602 commit a3daad8

File tree

4 files changed

+53
-25
lines changed

4 files changed

+53
-25
lines changed

Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ properties:
3333
clocks:
3434
maxItems: 1
3535

36+
clock-names:
37+
items:
38+
- const: nf_clk
39+
3640
dmas:
3741
maxItems: 1
3842

@@ -51,6 +55,7 @@ required:
5155
- reg-names
5256
- interrupts
5357
- clocks
58+
- clock-names
5459

5560
unevaluatedProperties: false
5661

@@ -66,7 +71,8 @@ examples:
6671
#address-cells = <1>;
6772
#size-cells = <0>;
6873
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
69-
clocks = <&nf_clk>;
74+
clocks = <&clk>;
75+
clock-names = "nf_clk";
7076
cdns,board-delay-ps = <4830>;
7177
7278
nand@0 {

drivers/mtd/nand/raw/cadence-nand-controller.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ struct cdns_nand_ctrl {
471471
struct {
472472
void __iomem *virt;
473473
dma_addr_t dma;
474+
dma_addr_t iova_dma;
475+
u32 size;
474476
} io;
475477

476478
int irq;
@@ -1835,11 +1837,11 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl,
18351837
}
18361838

18371839
if (dir == DMA_FROM_DEVICE) {
1838-
src_dma = cdns_ctrl->io.dma;
1840+
src_dma = cdns_ctrl->io.iova_dma;
18391841
dst_dma = buf_dma;
18401842
} else {
18411843
src_dma = buf_dma;
1842-
dst_dma = cdns_ctrl->io.dma;
1844+
dst_dma = cdns_ctrl->io.iova_dma;
18431845
}
18441846

18451847
tx = dmaengine_prep_dma_memcpy(cdns_ctrl->dmac, dst_dma, src_dma, len,
@@ -1861,12 +1863,12 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl,
18611863
dma_async_issue_pending(cdns_ctrl->dmac);
18621864
wait_for_completion(&finished);
18631865

1864-
dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir);
1866+
dma_unmap_single(dma_dev->dev, buf_dma, len, dir);
18651867

18661868
return 0;
18671869

18681870
err_unmap:
1869-
dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir);
1871+
dma_unmap_single(dma_dev->dev, buf_dma, len, dir);
18701872

18711873
err:
18721874
dev_dbg(cdns_ctrl->dev, "Fall back to CPU I/O\n");
@@ -2869,6 +2871,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl)
28692871
static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
28702872
{
28712873
dma_cap_mask_t mask;
2874+
struct dma_device *dma_dev = cdns_ctrl->dmac->device;
28722875
int ret;
28732876

28742877
cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2904,15 +2907,24 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
29042907
dma_cap_set(DMA_MEMCPY, mask);
29052908

29062909
if (cdns_ctrl->caps1->has_dma) {
2907-
cdns_ctrl->dmac = dma_request_channel(mask, NULL, NULL);
2908-
if (!cdns_ctrl->dmac) {
2909-
dev_err(cdns_ctrl->dev,
2910-
"Unable to get a DMA channel\n");
2911-
ret = -EBUSY;
2910+
cdns_ctrl->dmac = dma_request_chan_by_mask(&mask);
2911+
if (IS_ERR(cdns_ctrl->dmac)) {
2912+
ret = dev_err_probe(cdns_ctrl->dev, PTR_ERR(cdns_ctrl->dmac),
2913+
"%d: Failed to get a DMA channel\n", ret);
29122914
goto disable_irq;
29132915
}
29142916
}
29152917

2918+
cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma,
2919+
cdns_ctrl->io.size,
2920+
DMA_BIDIRECTIONAL, 0);
2921+
2922+
ret = dma_mapping_error(dma_dev->dev, cdns_ctrl->io.iova_dma);
2923+
if (ret) {
2924+
dev_err(cdns_ctrl->dev, "Failed to map I/O resource to DMA\n");
2925+
goto dma_release_chnl;
2926+
}
2927+
29162928
nand_controller_init(&cdns_ctrl->controller);
29172929
INIT_LIST_HEAD(&cdns_ctrl->chips);
29182930

@@ -2923,18 +2935,22 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
29232935
if (ret) {
29242936
dev_err(cdns_ctrl->dev, "Failed to register MTD: %d\n",
29252937
ret);
2926-
goto dma_release_chnl;
2938+
goto unmap_dma_resource;
29272939
}
29282940

29292941
kfree(cdns_ctrl->buf);
29302942
cdns_ctrl->buf = kzalloc(cdns_ctrl->buf_size, GFP_KERNEL);
29312943
if (!cdns_ctrl->buf) {
29322944
ret = -ENOMEM;
2933-
goto dma_release_chnl;
2945+
goto unmap_dma_resource;
29342946
}
29352947

29362948
return 0;
29372949

2950+
unmap_dma_resource:
2951+
dma_unmap_resource(dma_dev->dev, cdns_ctrl->io.iova_dma,
2952+
cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0);
2953+
29382954
dma_release_chnl:
29392955
if (cdns_ctrl->dmac)
29402956
dma_release_channel(cdns_ctrl->dmac);
@@ -2956,6 +2972,10 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
29562972
static void cadence_nand_remove(struct cdns_nand_ctrl *cdns_ctrl)
29572973
{
29582974
cadence_nand_chips_cleanup(cdns_ctrl);
2975+
if (cdns_ctrl->dmac)
2976+
dma_unmap_resource(cdns_ctrl->dmac->device->dev,
2977+
cdns_ctrl->io.iova_dma, cdns_ctrl->io.size,
2978+
DMA_BIDIRECTIONAL, 0);
29592979
cadence_nand_irq_cleanup(cdns_ctrl->irq, cdns_ctrl);
29602980
kfree(cdns_ctrl->buf);
29612981
dma_free_coherent(cdns_ctrl->dev, sizeof(struct cadence_nand_cdma_desc),
@@ -3020,7 +3040,9 @@ static int cadence_nand_dt_probe(struct platform_device *ofdev)
30203040
cdns_ctrl->io.virt = devm_platform_get_and_ioremap_resource(ofdev, 1, &res);
30213041
if (IS_ERR(cdns_ctrl->io.virt))
30223042
return PTR_ERR(cdns_ctrl->io.virt);
3043+
30233044
cdns_ctrl->io.dma = res->start;
3045+
cdns_ctrl->io.size = resource_size(res);
30243046

30253047
dt->clk = devm_clk_get(cdns_ctrl->dev, "nf_clk");
30263048
if (IS_ERR(dt->clk))

drivers/mtd/nand/raw/qcom_nandc.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,18 +1881,18 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
18811881
nandc->regs->addr0 = 0;
18821882
nandc->regs->addr1 = 0;
18831883

1884-
host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) |
1885-
FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
1886-
FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
1887-
FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
1888-
1889-
host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
1890-
FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
1891-
FIELD_PREP(CS_ACTIVE_BSY, 0) |
1892-
FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
1893-
FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
1894-
FIELD_PREP(WIDE_FLASH, 0) |
1895-
FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
1884+
nandc->regs->cfg0 = cpu_to_le32(FIELD_PREP(CW_PER_PAGE_MASK, 0) |
1885+
FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
1886+
FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
1887+
FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0));
1888+
1889+
nandc->regs->cfg1 = cpu_to_le32(FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
1890+
FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
1891+
FIELD_PREP(CS_ACTIVE_BSY, 0) |
1892+
FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
1893+
FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
1894+
FIELD_PREP(WIDE_FLASH, 0) |
1895+
FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1));
18961896

18971897
if (!nandc->props->qpic_version2)
18981898
nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);

drivers/mtd/spi-nor/sst.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static int sst_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
174174
int ret;
175175

176176
nor->program_opcode = op;
177-
ret = spi_nor_write_data(nor, to, 1, buf);
177+
ret = spi_nor_write_data(nor, to, len, buf);
178178
if (ret < 0)
179179
return ret;
180180
WARN(ret != len, "While writing %zu byte written %i bytes\n", len, ret);

0 commit comments

Comments
 (0)