diff options
| -rw-r--r-- | drivers/mtd/nand/lpc32xx_mlc.c | 3 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 3 | ||||
| -rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 45 |
3 files changed, 45 insertions, 6 deletions
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index c3bb358ef01e..5796468db653 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
| @@ -707,7 +707,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 707 | } | 707 | } |
| 708 | res = clk_prepare_enable(host->clk); | 708 | res = clk_prepare_enable(host->clk); |
| 709 | if (res) | 709 | if (res) |
| 710 | goto err_exit1; | 710 | goto err_put_clk; |
| 711 | 711 | ||
| 712 | nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; | 712 | nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; |
| 713 | nand_chip->dev_ready = lpc32xx_nand_device_ready; | 713 | nand_chip->dev_ready = lpc32xx_nand_device_ready; |
| @@ -814,6 +814,7 @@ err_exit3: | |||
| 814 | dma_release_channel(host->dma_chan); | 814 | dma_release_channel(host->dma_chan); |
| 815 | err_exit2: | 815 | err_exit2: |
| 816 | clk_disable_unprepare(host->clk); | 816 | clk_disable_unprepare(host->clk); |
| 817 | err_put_clk: | ||
| 817 | clk_put(host->clk); | 818 | clk_put(host->clk); |
| 818 | err_exit1: | 819 | err_exit1: |
| 819 | lpc32xx_wp_enable(host); | 820 | lpc32xx_wp_enable(host); |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bcc8cef1c615..12edaae17d81 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -2668,7 +2668,7 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, | |||
| 2668 | static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | 2668 | static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, |
| 2669 | struct mtd_oob_ops *ops) | 2669 | struct mtd_oob_ops *ops) |
| 2670 | { | 2670 | { |
| 2671 | int chipnr, realpage, page, blockmask, column; | 2671 | int chipnr, realpage, page, column; |
| 2672 | struct nand_chip *chip = mtd_to_nand(mtd); | 2672 | struct nand_chip *chip = mtd_to_nand(mtd); |
| 2673 | uint32_t writelen = ops->len; | 2673 | uint32_t writelen = ops->len; |
| 2674 | 2674 | ||
| @@ -2704,7 +2704,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
| 2704 | 2704 | ||
| 2705 | realpage = (int)(to >> chip->page_shift); | 2705 | realpage = (int)(to >> chip->page_shift); |
| 2706 | page = realpage & chip->pagemask; | 2706 | page = realpage & chip->pagemask; |
| 2707 | blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | ||
| 2708 | 2707 | ||
| 2709 | /* Invalidate the page cache, when we write to the cached page */ | 2708 | /* Invalidate the page cache, when we write to the cached page */ |
| 2710 | if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && | 2709 | if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && |
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index cf1d4a15e10a..19c000722cbc 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
| @@ -1784,7 +1784,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, | |||
| 1784 | * @nor: pointer to a 'struct spi_nor' | 1784 | * @nor: pointer to a 'struct spi_nor' |
| 1785 | * @addr: offset in the SFDP area to start reading data from | 1785 | * @addr: offset in the SFDP area to start reading data from |
| 1786 | * @len: number of bytes to read | 1786 | * @len: number of bytes to read |
| 1787 | * @buf: buffer where the SFDP data are copied into | 1787 | * @buf: buffer where the SFDP data are copied into (dma-safe memory) |
| 1788 | * | 1788 | * |
| 1789 | * Whatever the actual numbers of bytes for address and dummy cycles are | 1789 | * Whatever the actual numbers of bytes for address and dummy cycles are |
| 1790 | * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always | 1790 | * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always |
| @@ -1829,6 +1829,36 @@ read_err: | |||
| 1829 | return ret; | 1829 | return ret; |
| 1830 | } | 1830 | } |
| 1831 | 1831 | ||
| 1832 | /** | ||
| 1833 | * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters. | ||
| 1834 | * @nor: pointer to a 'struct spi_nor' | ||
| 1835 | * @addr: offset in the SFDP area to start reading data from | ||
| 1836 | * @len: number of bytes to read | ||
| 1837 | * @buf: buffer where the SFDP data are copied into | ||
| 1838 | * | ||
| 1839 | * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not | ||
| 1840 | * guaranteed to be dma-safe. | ||
| 1841 | * | ||
| 1842 | * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp() | ||
| 1843 | * otherwise. | ||
| 1844 | */ | ||
| 1845 | static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr, | ||
| 1846 | size_t len, void *buf) | ||
| 1847 | { | ||
| 1848 | void *dma_safe_buf; | ||
| 1849 | int ret; | ||
| 1850 | |||
| 1851 | dma_safe_buf = kmalloc(len, GFP_KERNEL); | ||
| 1852 | if (!dma_safe_buf) | ||
| 1853 | return -ENOMEM; | ||
| 1854 | |||
| 1855 | ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf); | ||
| 1856 | memcpy(buf, dma_safe_buf, len); | ||
| 1857 | kfree(dma_safe_buf); | ||
| 1858 | |||
| 1859 | return ret; | ||
| 1860 | } | ||
| 1861 | |||
| 1832 | struct sfdp_parameter_header { | 1862 | struct sfdp_parameter_header { |
| 1833 | u8 id_lsb; | 1863 | u8 id_lsb; |
| 1834 | u8 minor; | 1864 | u8 minor; |
| @@ -2101,7 +2131,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, | |||
| 2101 | bfpt_header->length * sizeof(u32)); | 2131 | bfpt_header->length * sizeof(u32)); |
| 2102 | addr = SFDP_PARAM_HEADER_PTP(bfpt_header); | 2132 | addr = SFDP_PARAM_HEADER_PTP(bfpt_header); |
| 2103 | memset(&bfpt, 0, sizeof(bfpt)); | 2133 | memset(&bfpt, 0, sizeof(bfpt)); |
| 2104 | err = spi_nor_read_sfdp(nor, addr, len, &bfpt); | 2134 | err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt); |
| 2105 | if (err < 0) | 2135 | if (err < 0) |
| 2106 | return err; | 2136 | return err; |
| 2107 | 2137 | ||
| @@ -2127,6 +2157,15 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, | |||
| 2127 | params->size = bfpt.dwords[BFPT_DWORD(2)]; | 2157 | params->size = bfpt.dwords[BFPT_DWORD(2)]; |
| 2128 | if (params->size & BIT(31)) { | 2158 | if (params->size & BIT(31)) { |
| 2129 | params->size &= ~BIT(31); | 2159 | params->size &= ~BIT(31); |
| 2160 | |||
| 2161 | /* | ||
| 2162 | * Prevent overflows on params->size. Anyway, a NOR of 2^64 | ||
| 2163 | * bits is unlikely to exist so this error probably means | ||
| 2164 | * the BFPT we are reading is corrupted/wrong. | ||
| 2165 | */ | ||
| 2166 | if (params->size > 63) | ||
| 2167 | return -EINVAL; | ||
| 2168 | |||
| 2130 | params->size = 1ULL << params->size; | 2169 | params->size = 1ULL << params->size; |
| 2131 | } else { | 2170 | } else { |
| 2132 | params->size++; | 2171 | params->size++; |
| @@ -2243,7 +2282,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, | |||
| 2243 | int i, err; | 2282 | int i, err; |
| 2244 | 2283 | ||
| 2245 | /* Get the SFDP header. */ | 2284 | /* Get the SFDP header. */ |
| 2246 | err = spi_nor_read_sfdp(nor, 0, sizeof(header), &header); | 2285 | err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header); |
| 2247 | if (err < 0) | 2286 | if (err < 0) |
| 2248 | return err; | 2287 | return err; |
| 2249 | 2288 | ||
