diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-20 05:25:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-20 05:25:20 -0400 |
commit | 4b92e7fd76e94624e3d5ff56b3d6a5788c4a7ac8 (patch) | |
tree | 468e18bd1e2500d590dd199d56e3731dc40e8b0c | |
parent | d82920849f305a83b893a90eca6391de411d77ef (diff) | |
parent | 4a3e85f2674cbfb81052059107d0165269778e2f (diff) |
Merge tag 'mtd/fixes-for-4.19-rc5' of git://git.infradead.org/linux-mtd
Boris writes:
"- Fixes a bug in the ->read/write_reg() implementation of the m25p80
driver
- Make sure of_node_get/put() calls are balanced in the partition
parsing code
- Fix a race in the denali NAND controller driver
- Fix false positive WARN_ON() in the marvell NAND controller driver"
* tag 'mtd/fixes-for-4.19-rc5' of git://git.infradead.org/linux-mtd:
mtd: devices: m25p80: Make sure the buffer passed in op is DMA-able
mtd: partitions: fix unbalanced of_node_get/put()
mtd: rawnand: denali: fix a race condition when DMA is kicked
mtd: rawnand: marvell: prevent harmless warnings
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 26 | ||||
-rw-r--r-- | drivers/mtd/mtdpart.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/denali.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/marvell_nand.c | 4 |
4 files changed, 36 insertions, 5 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index cbfafc453274..270d3c9580c5 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -39,13 +39,23 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) | |||
39 | struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1), | 39 | struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1), |
40 | SPI_MEM_OP_NO_ADDR, | 40 | SPI_MEM_OP_NO_ADDR, |
41 | SPI_MEM_OP_NO_DUMMY, | 41 | SPI_MEM_OP_NO_DUMMY, |
42 | SPI_MEM_OP_DATA_IN(len, val, 1)); | 42 | SPI_MEM_OP_DATA_IN(len, NULL, 1)); |
43 | void *scratchbuf; | ||
43 | int ret; | 44 | int ret; |
44 | 45 | ||
46 | scratchbuf = kmalloc(len, GFP_KERNEL); | ||
47 | if (!scratchbuf) | ||
48 | return -ENOMEM; | ||
49 | |||
50 | op.data.buf.in = scratchbuf; | ||
45 | ret = spi_mem_exec_op(flash->spimem, &op); | 51 | ret = spi_mem_exec_op(flash->spimem, &op); |
46 | if (ret < 0) | 52 | if (ret < 0) |
47 | dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret, | 53 | dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret, |
48 | code); | 54 | code); |
55 | else | ||
56 | memcpy(val, scratchbuf, len); | ||
57 | |||
58 | kfree(scratchbuf); | ||
49 | 59 | ||
50 | return ret; | 60 | return ret; |
51 | } | 61 | } |
@@ -56,9 +66,19 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) | |||
56 | struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1), | 66 | struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1), |
57 | SPI_MEM_OP_NO_ADDR, | 67 | SPI_MEM_OP_NO_ADDR, |
58 | SPI_MEM_OP_NO_DUMMY, | 68 | SPI_MEM_OP_NO_DUMMY, |
59 | SPI_MEM_OP_DATA_OUT(len, buf, 1)); | 69 | SPI_MEM_OP_DATA_OUT(len, NULL, 1)); |
70 | void *scratchbuf; | ||
71 | int ret; | ||
60 | 72 | ||
61 | return spi_mem_exec_op(flash->spimem, &op); | 73 | scratchbuf = kmemdup(buf, len, GFP_KERNEL); |
74 | if (!scratchbuf) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | op.data.buf.out = scratchbuf; | ||
78 | ret = spi_mem_exec_op(flash->spimem, &op); | ||
79 | kfree(scratchbuf); | ||
80 | |||
81 | return ret; | ||
62 | } | 82 | } |
63 | 83 | ||
64 | static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len, | 84 | static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len, |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 52e2cb35fc79..99c460facd5e 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -873,8 +873,11 @@ static int mtd_part_of_parse(struct mtd_info *master, | |||
873 | int ret, err = 0; | 873 | int ret, err = 0; |
874 | 874 | ||
875 | np = mtd_get_of_node(master); | 875 | np = mtd_get_of_node(master); |
876 | if (!mtd_is_partition(master)) | 876 | if (mtd_is_partition(master)) |
877 | of_node_get(np); | ||
878 | else | ||
877 | np = of_get_child_by_name(np, "partitions"); | 879 | np = of_get_child_by_name(np, "partitions"); |
880 | |||
878 | of_property_for_each_string(np, "compatible", prop, compat) { | 881 | of_property_for_each_string(np, "compatible", prop, compat) { |
879 | parser = mtd_part_get_compatible_parser(compat); | 882 | parser = mtd_part_get_compatible_parser(compat); |
880 | if (!parser) | 883 | if (!parser) |
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 67b2065e7a19..b864b93dd289 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c | |||
@@ -596,6 +596,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, | |||
596 | } | 596 | } |
597 | 597 | ||
598 | iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE); | 598 | iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE); |
599 | /* | ||
600 | * The ->setup_dma() hook kicks DMA by using the data/command | ||
601 | * interface, which belongs to a different AXI port from the | ||
602 | * register interface. Read back the register to avoid a race. | ||
603 | */ | ||
604 | ioread32(denali->reg + DMA_ENABLE); | ||
599 | 605 | ||
600 | denali_reset_irq(denali); | 606 | denali_reset_irq(denali); |
601 | denali->setup_dma(denali, dma_addr, page, write); | 607 | denali->setup_dma(denali, dma_addr, page, write); |
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 7af4d6213ee5..bc2ef5209783 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c | |||
@@ -1547,7 +1547,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, | |||
1547 | for (op_id = 0; op_id < subop->ninstrs; op_id++) { | 1547 | for (op_id = 0; op_id < subop->ninstrs; op_id++) { |
1548 | unsigned int offset, naddrs; | 1548 | unsigned int offset, naddrs; |
1549 | const u8 *addrs; | 1549 | const u8 *addrs; |
1550 | int len = nand_subop_get_data_len(subop, op_id); | 1550 | int len; |
1551 | 1551 | ||
1552 | instr = &subop->instrs[op_id]; | 1552 | instr = &subop->instrs[op_id]; |
1553 | 1553 | ||
@@ -1593,6 +1593,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, | |||
1593 | nfc_op->ndcb[0] |= | 1593 | nfc_op->ndcb[0] |= |
1594 | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | | 1594 | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | |
1595 | NDCB0_LEN_OVRD; | 1595 | NDCB0_LEN_OVRD; |
1596 | len = nand_subop_get_data_len(subop, op_id); | ||
1596 | nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); | 1597 | nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); |
1597 | } | 1598 | } |
1598 | nfc_op->data_delay_ns = instr->delay_ns; | 1599 | nfc_op->data_delay_ns = instr->delay_ns; |
@@ -1606,6 +1607,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, | |||
1606 | nfc_op->ndcb[0] |= | 1607 | nfc_op->ndcb[0] |= |
1607 | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | | 1608 | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | |
1608 | NDCB0_LEN_OVRD; | 1609 | NDCB0_LEN_OVRD; |
1610 | len = nand_subop_get_data_len(subop, op_id); | ||
1609 | nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); | 1611 | nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); |
1610 | } | 1612 | } |
1611 | nfc_op->data_delay_ns = instr->delay_ns; | 1613 | nfc_op->data_delay_ns = instr->delay_ns; |