Commit 4b92e7fd authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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
parents d8292084 4a3e85f2
...@@ -39,13 +39,23 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) ...@@ -39,13 +39,23 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1), struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1),
SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_IN(len, val, 1)); SPI_MEM_OP_DATA_IN(len, NULL, 1));
void *scratchbuf;
int ret; int ret;
scratchbuf = kmalloc(len, GFP_KERNEL);
if (!scratchbuf)
return -ENOMEM;
op.data.buf.in = scratchbuf;
ret = spi_mem_exec_op(flash->spimem, &op); ret = spi_mem_exec_op(flash->spimem, &op);
if (ret < 0) if (ret < 0)
dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret, dev_err(&flash->spimem->spi->dev, "error %d reading %x\n", ret,
code); code);
else
memcpy(val, scratchbuf, len);
kfree(scratchbuf);
return ret; return ret;
} }
...@@ -56,9 +66,19 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) ...@@ -56,9 +66,19 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1), struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1),
SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_OUT(len, buf, 1)); SPI_MEM_OP_DATA_OUT(len, NULL, 1));
void *scratchbuf;
int ret;
return spi_mem_exec_op(flash->spimem, &op); scratchbuf = kmemdup(buf, len, GFP_KERNEL);
if (!scratchbuf)
return -ENOMEM;
op.data.buf.out = scratchbuf;
ret = spi_mem_exec_op(flash->spimem, &op);
kfree(scratchbuf);
return ret;
} }
static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len, static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
......
...@@ -873,8 +873,11 @@ static int mtd_part_of_parse(struct mtd_info *master, ...@@ -873,8 +873,11 @@ static int mtd_part_of_parse(struct mtd_info *master,
int ret, err = 0; int ret, err = 0;
np = mtd_get_of_node(master); np = mtd_get_of_node(master);
if (!mtd_is_partition(master)) if (mtd_is_partition(master))
of_node_get(np);
else
np = of_get_child_by_name(np, "partitions"); np = of_get_child_by_name(np, "partitions");
of_property_for_each_string(np, "compatible", prop, compat) { of_property_for_each_string(np, "compatible", prop, compat) {
parser = mtd_part_get_compatible_parser(compat); parser = mtd_part_get_compatible_parser(compat);
if (!parser) if (!parser)
......
...@@ -596,6 +596,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, ...@@ -596,6 +596,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
} }
iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE); iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
/*
* The ->setup_dma() hook kicks DMA by using the data/command
* interface, which belongs to a different AXI port from the
* register interface. Read back the register to avoid a race.
*/
ioread32(denali->reg + DMA_ENABLE);
denali_reset_irq(denali); denali_reset_irq(denali);
denali->setup_dma(denali, dma_addr, page, write); denali->setup_dma(denali, dma_addr, page, write);
......
...@@ -1547,7 +1547,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, ...@@ -1547,7 +1547,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
for (op_id = 0; op_id < subop->ninstrs; op_id++) { for (op_id = 0; op_id < subop->ninstrs; op_id++) {
unsigned int offset, naddrs; unsigned int offset, naddrs;
const u8 *addrs; const u8 *addrs;
int len = nand_subop_get_data_len(subop, op_id); int len;
instr = &subop->instrs[op_id]; instr = &subop->instrs[op_id];
...@@ -1593,6 +1593,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, ...@@ -1593,6 +1593,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
nfc_op->ndcb[0] |= nfc_op->ndcb[0] |=
NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
NDCB0_LEN_OVRD; NDCB0_LEN_OVRD;
len = nand_subop_get_data_len(subop, op_id);
nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
} }
nfc_op->data_delay_ns = instr->delay_ns; nfc_op->data_delay_ns = instr->delay_ns;
...@@ -1606,6 +1607,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip, ...@@ -1606,6 +1607,7 @@ static void marvell_nfc_parse_instructions(struct nand_chip *chip,
nfc_op->ndcb[0] |= nfc_op->ndcb[0] |=
NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) | NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW) |
NDCB0_LEN_OVRD; NDCB0_LEN_OVRD;
len = nand_subop_get_data_len(subop, op_id);
nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH); nfc_op->ndcb[3] |= round_up(len, FIFO_DEPTH);
} }
nfc_op->data_delay_ns = instr->delay_ns; nfc_op->data_delay_ns = instr->delay_ns;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment