diff options
author | Tudor.Ambarus@microchip.com <Tudor.Ambarus@microchip.com> | 2018-11-09 11:56:54 -0500 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-11-13 14:37:34 -0500 |
commit | 1d5ceff25aa1edcaf84e7ee26fdcc746cb245af8 (patch) | |
tree | da7f47c18937884279c137ddab6c769440a5252a /drivers/mtd/spi-nor/spi-nor.c | |
parent | b9f07cc8207a2a69496beec3f5a5a8372bacdfdc (diff) |
mtd: spi_nor: pass DMA-able buffer to spi_nor_read_raw()
spi_nor_read_raw() calls nor->read() which might be implemented
by the m25p80 driver. m25p80 uses the spi-mem layer which requires
DMA-able in/out buffers. Pass kmalloc'ed dma buffer to spi_nor_read_raw().
Fixes: b038e8e3be72 ("mtd: spi-nor: parse SFDP Sector Map Parameter Table")
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Diffstat (limited to 'drivers/mtd/spi-nor/spi-nor.c')
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 7f03be9b54bc..eb7bb596416b 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
@@ -2156,7 +2156,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, | |||
2156 | * @nor: pointer to a 'struct spi_nor' | 2156 | * @nor: pointer to a 'struct spi_nor' |
2157 | * @addr: offset in the serial flash memory | 2157 | * @addr: offset in the serial flash memory |
2158 | * @len: number of bytes to read | 2158 | * @len: number of bytes to read |
2159 | * @buf: buffer where the data is copied into | 2159 | * @buf: buffer where the data is copied into (dma-safe memory) |
2160 | * | 2160 | * |
2161 | * Return: 0 on success, -errno otherwise. | 2161 | * Return: 0 on success, -errno otherwise. |
2162 | */ | 2162 | */ |
@@ -2863,11 +2863,17 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, | |||
2863 | u8 smpt_len) | 2863 | u8 smpt_len) |
2864 | { | 2864 | { |
2865 | const u32 *ret; | 2865 | const u32 *ret; |
2866 | u8 *buf; | ||
2866 | u32 addr; | 2867 | u32 addr; |
2867 | int err; | 2868 | int err; |
2868 | u8 i; | 2869 | u8 i; |
2869 | u8 addr_width, read_opcode, read_dummy; | 2870 | u8 addr_width, read_opcode, read_dummy; |
2870 | u8 read_data_mask, data_byte, map_id; | 2871 | u8 read_data_mask, map_id; |
2872 | |||
2873 | /* Use a kmalloc'ed bounce buffer to guarantee it is DMA-able. */ | ||
2874 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | ||
2875 | if (!buf) | ||
2876 | return ERR_PTR(-ENOMEM); | ||
2871 | 2877 | ||
2872 | addr_width = nor->addr_width; | 2878 | addr_width = nor->addr_width; |
2873 | read_dummy = nor->read_dummy; | 2879 | read_dummy = nor->read_dummy; |
@@ -2885,7 +2891,7 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, | |||
2885 | nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); | 2891 | nor->read_opcode = SMPT_CMD_OPCODE(smpt[i]); |
2886 | addr = smpt[i + 1]; | 2892 | addr = smpt[i + 1]; |
2887 | 2893 | ||
2888 | err = spi_nor_read_raw(nor, addr, 1, &data_byte); | 2894 | err = spi_nor_read_raw(nor, addr, 1, buf); |
2889 | if (err) { | 2895 | if (err) { |
2890 | ret = ERR_PTR(err); | 2896 | ret = ERR_PTR(err); |
2891 | goto out; | 2897 | goto out; |
@@ -2895,7 +2901,7 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, | |||
2895 | * Build an index value that is used to select the Sector Map | 2901 | * Build an index value that is used to select the Sector Map |
2896 | * Configuration that is currently in use. | 2902 | * Configuration that is currently in use. |
2897 | */ | 2903 | */ |
2898 | map_id = map_id << 1 | !!(data_byte & read_data_mask); | 2904 | map_id = map_id << 1 | !!(*buf & read_data_mask); |
2899 | } | 2905 | } |
2900 | 2906 | ||
2901 | /* | 2907 | /* |
@@ -2926,6 +2932,7 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, | |||
2926 | 2932 | ||
2927 | /* fall through */ | 2933 | /* fall through */ |
2928 | out: | 2934 | out: |
2935 | kfree(buf); | ||
2929 | nor->addr_width = addr_width; | 2936 | nor->addr_width = addr_width; |
2930 | nor->read_dummy = read_dummy; | 2937 | nor->read_dummy = read_dummy; |
2931 | nor->read_opcode = read_opcode; | 2938 | nor->read_opcode = read_opcode; |