Commit 7993e65f authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MTD fixes from Miquel Raynal:
 "MTD changes:

   - Qcom:
      - Don't print error message on -EPROBE_DEFER
      - Fix kernel panic on skipped partition
      - Fix missing free for pparts in cleanup

   - phram: Prevent divide by zero bug in phram_setup()

  Raw NAND controller changes:

   - ingenic: Fix missing put_device in ingenic_ecc_get

   - qcom: Fix clock sequencing in qcom_nandc_probe()

   - omap2: Prevent invalid configuration and build error

   - gpmi: Don't leak PM reference in error path

   - brcmnand: Fix incorrect sub-page ECC status"

* tag 'mtd/fixes-for-5.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux:
  mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status
  mtd: rawnand: gpmi: don't leak PM reference in error path
  mtd: phram: Prevent divide by zero bug in phram_setup()
  mtd: rawnand: omap2: Prevent invalid configuration and build error
  mtd: parsers: qcom: Fix missing free for pparts in cleanup
  mtd: parsers: qcom: Fix kernel panic on skipped partition
  mtd: parsers: qcom: Don't print error message on -EPROBE_DEFER
  mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe()
  mtd: rawnand: ingenic: Fix missing put_device in ingenic_ecc_get
parents b9889768 36415a79
...@@ -264,16 +264,20 @@ static int phram_setup(const char *val) ...@@ -264,16 +264,20 @@ static int phram_setup(const char *val)
} }
} }
if (erasesize)
div_u64_rem(len, (uint32_t)erasesize, &rem);
if (len == 0 || erasesize == 0 || erasesize > len if (len == 0 || erasesize == 0 || erasesize > len
|| erasesize > UINT_MAX || rem) { || erasesize > UINT_MAX) {
parse_err("illegal erasesize or len\n"); parse_err("illegal erasesize or len\n");
ret = -EINVAL; ret = -EINVAL;
goto error; goto error;
} }
div_u64_rem(len, (uint32_t)erasesize, &rem);
if (rem) {
parse_err("len is not multiple of erasesize\n");
ret = -EINVAL;
goto error;
}
ret = register_device(name, start, len, (uint32_t)erasesize); ret = register_device(name, start, len, (uint32_t)erasesize);
if (ret) if (ret)
goto error; goto error;
......
...@@ -42,7 +42,8 @@ config MTD_NAND_OMAP2 ...@@ -42,7 +42,8 @@ config MTD_NAND_OMAP2
tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller" tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller"
depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
select OMAP_GPMC if ARCH_K3 select MEMORY
select OMAP_GPMC
help help
Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4 Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4
and Keystone platforms. and Keystone platforms.
......
...@@ -2106,7 +2106,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -2106,7 +2106,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
mtd->oobsize / trans, mtd->oobsize / trans,
host->hwcfg.sector_size_1k); host->hwcfg.sector_size_1k);
if (!ret) { if (ret != -EBADMSG) {
*err_addr = brcmnand_get_uncorrecc_addr(ctrl); *err_addr = brcmnand_get_uncorrecc_addr(ctrl);
if (*err_addr) if (*err_addr)
......
...@@ -2285,7 +2285,7 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, ...@@ -2285,7 +2285,7 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip,
this->hw.must_apply_timings = false; this->hw.must_apply_timings = false;
ret = gpmi_nfc_apply_timings(this); ret = gpmi_nfc_apply_timings(this);
if (ret) if (ret)
return ret; goto out_pm;
} }
dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs); dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs);
...@@ -2414,6 +2414,7 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, ...@@ -2414,6 +2414,7 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip,
this->bch = false; this->bch = false;
out_pm:
pm_runtime_mark_last_busy(this->dev); pm_runtime_mark_last_busy(this->dev);
pm_runtime_put_autosuspend(this->dev); pm_runtime_put_autosuspend(this->dev);
......
...@@ -68,9 +68,14 @@ static struct ingenic_ecc *ingenic_ecc_get(struct device_node *np) ...@@ -68,9 +68,14 @@ static struct ingenic_ecc *ingenic_ecc_get(struct device_node *np)
struct ingenic_ecc *ecc; struct ingenic_ecc *ecc;
pdev = of_find_device_by_node(np); pdev = of_find_device_by_node(np);
if (!pdev || !platform_get_drvdata(pdev)) if (!pdev)
return ERR_PTR(-EPROBE_DEFER); return ERR_PTR(-EPROBE_DEFER);
if (!platform_get_drvdata(pdev)) {
put_device(&pdev->dev);
return ERR_PTR(-EPROBE_DEFER);
}
ecc = platform_get_drvdata(pdev); ecc = platform_get_drvdata(pdev);
clk_prepare_enable(ecc->clk); clk_prepare_enable(ecc->clk);
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/* /*
* Copyright (c) 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2016, The Linux Foundation. All rights reserved.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/bitops.h> #include <linux/bitops.h>
...@@ -3073,10 +3072,6 @@ static int qcom_nandc_probe(struct platform_device *pdev) ...@@ -3073,10 +3072,6 @@ static int qcom_nandc_probe(struct platform_device *pdev)
if (dma_mapping_error(dev, nandc->base_dma)) if (dma_mapping_error(dev, nandc->base_dma))
return -ENXIO; return -ENXIO;
ret = qcom_nandc_alloc(nandc);
if (ret)
goto err_nandc_alloc;
ret = clk_prepare_enable(nandc->core_clk); ret = clk_prepare_enable(nandc->core_clk);
if (ret) if (ret)
goto err_core_clk; goto err_core_clk;
...@@ -3085,6 +3080,10 @@ static int qcom_nandc_probe(struct platform_device *pdev) ...@@ -3085,6 +3080,10 @@ static int qcom_nandc_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_aon_clk; goto err_aon_clk;
ret = qcom_nandc_alloc(nandc);
if (ret)
goto err_nandc_alloc;
ret = qcom_nandc_setup(nandc); ret = qcom_nandc_setup(nandc);
if (ret) if (ret)
goto err_setup; goto err_setup;
...@@ -3096,15 +3095,14 @@ static int qcom_nandc_probe(struct platform_device *pdev) ...@@ -3096,15 +3095,14 @@ static int qcom_nandc_probe(struct platform_device *pdev)
return 0; return 0;
err_setup: err_setup:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
clk_disable_unprepare(nandc->aon_clk); clk_disable_unprepare(nandc->aon_clk);
err_aon_clk: err_aon_clk:
clk_disable_unprepare(nandc->core_clk); clk_disable_unprepare(nandc->core_clk);
err_core_clk: err_core_clk:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
dma_unmap_resource(dev, res->start, resource_size(res), dma_unmap_resource(dev, res->start, resource_size(res),
DMA_BIDIRECTIONAL, 0); DMA_BIDIRECTIONAL, 0);
return ret; return ret;
} }
......
...@@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, ...@@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
const struct mtd_partition **pparts, const struct mtd_partition **pparts,
struct mtd_part_parser_data *data) struct mtd_part_parser_data *data)
{ {
size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
int ret, i, j, tmpparts, numparts = 0;
struct smem_flash_pentry *pentry; struct smem_flash_pentry *pentry;
struct smem_flash_ptable *ptable; struct smem_flash_ptable *ptable;
size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
struct mtd_partition *parts; struct mtd_partition *parts;
int ret, i, numparts;
char *name, *c; char *name, *c;
if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS) if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS)
...@@ -75,6 +75,7 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, ...@@ -75,6 +75,7 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
pr_debug("Parsing partition table info from SMEM\n"); pr_debug("Parsing partition table info from SMEM\n");
ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
if (IS_ERR(ptable)) { if (IS_ERR(ptable)) {
if (PTR_ERR(ptable) != -EPROBE_DEFER)
pr_err("Error reading partition table header\n"); pr_err("Error reading partition table header\n");
return PTR_ERR(ptable); return PTR_ERR(ptable);
} }
...@@ -87,8 +88,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, ...@@ -87,8 +88,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
} }
/* Ensure that # of partitions is less than the max we have allocated */ /* Ensure that # of partitions is less than the max we have allocated */
numparts = le32_to_cpu(ptable->numparts); tmpparts = le32_to_cpu(ptable->numparts);
if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { if (tmpparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
pr_err("Partition numbers exceed the max limit\n"); pr_err("Partition numbers exceed the max limit\n");
return -EINVAL; return -EINVAL;
} }
...@@ -116,11 +117,17 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, ...@@ -116,11 +117,17 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
return PTR_ERR(ptable); return PTR_ERR(ptable);
} }
for (i = 0; i < tmpparts; i++) {
pentry = &ptable->pentry[i];
if (pentry->name[0] != '\0')
numparts++;
}
parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL);
if (!parts) if (!parts)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < numparts; i++) { for (i = 0, j = 0; i < tmpparts; i++) {
pentry = &ptable->pentry[i]; pentry = &ptable->pentry[i];
if (pentry->name[0] == '\0') if (pentry->name[0] == '\0')
continue; continue;
...@@ -135,24 +142,25 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, ...@@ -135,24 +142,25 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
for (c = name; *c != '\0'; c++) for (c = name; *c != '\0'; c++)
*c = tolower(*c); *c = tolower(*c);
parts[i].name = name; parts[j].name = name;
parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
parts[i].mask_flags = pentry->attr; parts[j].mask_flags = pentry->attr;
parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize;
pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
i, pentry->name, le32_to_cpu(pentry->offset), i, pentry->name, le32_to_cpu(pentry->offset),
le32_to_cpu(pentry->length), pentry->attr); le32_to_cpu(pentry->length), pentry->attr);
j++;
} }
pr_debug("SMEM partition table found: ver: %d len: %d\n", pr_debug("SMEM partition table found: ver: %d len: %d\n",
le32_to_cpu(ptable->version), numparts); le32_to_cpu(ptable->version), tmpparts);
*pparts = parts; *pparts = parts;
return numparts; return numparts;
out_free_parts: out_free_parts:
while (--i >= 0) while (--j >= 0)
kfree(parts[i].name); kfree(parts[j].name);
kfree(parts); kfree(parts);
*pparts = NULL; *pparts = NULL;
...@@ -166,6 +174,8 @@ static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts, ...@@ -166,6 +174,8 @@ static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts,
for (i = 0; i < nr_parts; i++) for (i = 0; i < nr_parts; i++)
kfree(pparts[i].name); kfree(pparts[i].name);
kfree(pparts);
} }
static const struct of_device_id qcomsmem_of_match_table[] = { static const struct of_device_id qcomsmem_of_match_table[] = {
......
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