Commit 03498b71 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mtd/fixes-for-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux

Pull MTD fixes from Miquel Raynal:
 "Core fix:

   - Fix a possible data corruption of the 'part' field in mtd_info

  Rawnand fixes:

   - Fix the check on the return value of wait_for_completion_timeout

   - Fix wrong ECC parameters for mt7622

   - Fix a possible memory corruption that might panic in the Qcom
     driver"

* tag 'mtd/fixes-for-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux:
  mtd: rawnand: qcom: fix memory corruption that causes panic
  mtd: fix 'part' field data corruption in mtd_info
  mtd: rawnand: Fix return value check of wait_for_completion_timeout
  mtd: rawnand: fix ecc parameters for mt7622
parents 233087ca ba7542eb
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
struct mtk_ecc_caps { struct mtk_ecc_caps {
u32 err_mask; u32 err_mask;
u32 err_shift;
const u8 *ecc_strength; const u8 *ecc_strength;
const u32 *ecc_regs; const u32 *ecc_regs;
u8 num_ecc_strength; u8 num_ecc_strength;
...@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = { ...@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = {
}; };
static const u8 ecc_strength_mt7622[] = { static const u8 ecc_strength_mt7622[] = {
4, 6, 8, 10, 12, 14, 16 4, 6, 8, 10, 12
}; };
enum mtk_ecc_regs { enum mtk_ecc_regs {
...@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats, ...@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
for (i = 0; i < sectors; i++) { for (i = 0; i < sectors; i++) {
offset = (i >> 2) << 2; offset = (i >> 2) << 2;
err = readl(ecc->regs + ECC_DECENUM0 + offset); err = readl(ecc->regs + ECC_DECENUM0 + offset);
err = err >> ((i % 4) * 8); err = err >> ((i % 4) * ecc->caps->err_shift);
err &= ecc->caps->err_mask; err &= ecc->caps->err_mask;
if (err == ecc->caps->err_mask) { if (err == ecc->caps->err_mask) {
/* uncorrectable errors */ /* uncorrectable errors */
...@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits); ...@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
.err_mask = 0x3f, .err_mask = 0x3f,
.err_shift = 8,
.ecc_strength = ecc_strength_mt2701, .ecc_strength = ecc_strength_mt2701,
.ecc_regs = mt2701_ecc_regs, .ecc_regs = mt2701_ecc_regs,
.num_ecc_strength = 20, .num_ecc_strength = 20,
...@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { ...@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
.err_mask = 0x7f, .err_mask = 0x7f,
.err_shift = 8,
.ecc_strength = ecc_strength_mt2712, .ecc_strength = ecc_strength_mt2712,
.ecc_regs = mt2712_ecc_regs, .ecc_regs = mt2712_ecc_regs,
.num_ecc_strength = 23, .num_ecc_strength = 23,
...@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { ...@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
}; };
static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = { static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
.err_mask = 0x3f, .err_mask = 0x1f,
.err_shift = 5,
.ecc_strength = ecc_strength_mt7622, .ecc_strength = ecc_strength_mt7622,
.ecc_regs = mt7622_ecc_regs, .ecc_regs = mt7622_ecc_regs,
.num_ecc_strength = 7, .num_ecc_strength = 5,
.ecc_mode_shift = 4, .ecc_mode_shift = 4,
.parity_bits = 13, .parity_bits = 13,
.pg_irq_sel = 0, .pg_irq_sel = 0,
......
...@@ -2651,10 +2651,23 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) ...@@ -2651,10 +2651,23 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
/* Free the initially allocated BAM transaction for reading the ONFI params */
if (nandc->props->is_bam)
free_bam_transaction(nandc);
nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
cwperpage); cwperpage);
/* Now allocate the BAM transaction based on updated max_cwperpage */
if (nandc->props->is_bam) {
nandc->bam_txn = alloc_bam_transaction(nandc);
if (!nandc->bam_txn) {
dev_err(nandc->dev,
"failed to allocate bam transaction\n");
return -ENOMEM;
}
}
/* /*
* DATA_UD_BYTES varies based on whether the read/write command protects * DATA_UD_BYTES varies based on whether the read/write command protects
* spare data with ECC too. We protect spare data by default, so we set * spare data with ECC too. We protect spare data by default, so we set
...@@ -2955,17 +2968,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, ...@@ -2955,17 +2968,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
if (ret) if (ret)
return ret; return ret;
if (nandc->props->is_bam) {
free_bam_transaction(nandc);
nandc->bam_txn = alloc_bam_transaction(nandc);
if (!nandc->bam_txn) {
dev_err(nandc->dev,
"failed to allocate bam transaction\n");
nand_cleanup(chip);
return -ENOMEM;
}
}
ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
if (ret) if (ret)
nand_cleanup(chip); nand_cleanup(chip);
......
...@@ -384,7 +384,8 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, ...@@ -384,7 +384,8 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
dma_addr_t dma_addr; dma_addr_t dma_addr;
dma_cookie_t cookie; dma_cookie_t cookie;
uint32_t reg; uint32_t reg;
int ret; int ret = 0;
unsigned long time_left;
if (dir == DMA_FROM_DEVICE) { if (dir == DMA_FROM_DEVICE) {
chan = flctl->chan_fifo0_rx; chan = flctl->chan_fifo0_rx;
...@@ -425,13 +426,14 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, ...@@ -425,13 +426,14 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
goto out; goto out;
} }
ret = time_left =
wait_for_completion_timeout(&flctl->dma_complete, wait_for_completion_timeout(&flctl->dma_complete,
msecs_to_jiffies(3000)); msecs_to_jiffies(3000));
if (ret <= 0) { if (time_left == 0) {
dmaengine_terminate_all(chan); dmaengine_terminate_all(chan);
dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
ret = -ETIMEDOUT;
} }
out: out:
...@@ -441,7 +443,7 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, ...@@ -441,7 +443,7 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
dma_unmap_single(chan->device->dev, dma_addr, len, dir); dma_unmap_single(chan->device->dev, dma_addr, len, dir);
/* ret > 0 is success */ /* ret == 0 is success */
return ret; return ret;
} }
...@@ -465,7 +467,7 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) ...@@ -465,7 +467,7 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
/* initiate DMA transfer */ /* initiate DMA transfer */
if (flctl->chan_fifo0_rx && rlen >= 32 && if (flctl->chan_fifo0_rx && rlen >= 32 &&
flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE) > 0) !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE))
goto convert; /* DMA success */ goto convert; /* DMA success */
/* do polling transfer */ /* do polling transfer */
...@@ -524,7 +526,7 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, ...@@ -524,7 +526,7 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
/* initiate DMA transfer */ /* initiate DMA transfer */
if (flctl->chan_fifo0_tx && rlen >= 32 && if (flctl->chan_fifo0_tx && rlen >= 32 &&
flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE) > 0) !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE))
return; /* DMA success */ return; /* DMA success */
/* do polling transfer */ /* do polling transfer */
......
...@@ -389,10 +389,8 @@ struct mtd_info { ...@@ -389,10 +389,8 @@ struct mtd_info {
/* List of partitions attached to this MTD device */ /* List of partitions attached to this MTD device */
struct list_head partitions; struct list_head partitions;
union { struct mtd_part part;
struct mtd_part part; struct mtd_master master;
struct mtd_master master;
};
}; };
static inline struct mtd_info *mtd_get_master(struct mtd_info *mtd) static inline struct mtd_info *mtd_get_master(struct mtd_info *mtd)
......
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