From: Rafał Miłecki Date: Wed, 27 Apr 2016 21:20:45 +0000 (+0000) Subject: bcm53xx: add m25p80 workaround for SPI flash writing problems X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=cf3b3cfc565be99677b7f2b6d617518f2dd87f23;p=openwrt%2Fstaging%2Fneocturne.git bcm53xx: add m25p80 workaround for SPI flash writing problems Signed-off-by: Rafał Miłecki SVN-Revision: 49264 --- diff --git a/target/linux/bcm53xx/patches-4.4/406-mtd-m25p80-use-single-SPI-message-for-writing-data.patch b/target/linux/bcm53xx/patches-4.4/406-mtd-m25p80-use-single-SPI-message-for-writing-data.patch new file mode 100644 index 0000000000..0e0cce219c --- /dev/null +++ b/target/linux/bcm53xx/patches-4.4/406-mtd-m25p80-use-single-SPI-message-for-writing-data.patch @@ -0,0 +1,62 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Subject: [PATCH] mtd: m25p80: use single SPI message for writing data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On all 3 tested Northstar devices with following flash memories: +mx25l6405d (8192 Kbytes) +mx25l12805d (16384 Kbytes) +mx25l25635e (32768 Kbytes) +I noticed writing to be broken. Not a single bit was changed leaving all +bytes set to 0xff. + +This is most likely some problem related to the SPI controller or its +driver. Using a single SPI message seems to workaround this. Of course +it's not perfect solution as copying whole data into a new buffer makes +writing slower. + +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -78,29 +78,30 @@ static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len, + { + struct m25p *flash = nor->priv; + struct spi_device *spi = flash->spi; ++ u8 *command = kzalloc(MAX_CMD_SIZE + len, GFP_KERNEL); + struct spi_transfer t[2] = {}; + struct spi_message m; + int cmd_sz = m25p_cmdsz(nor); ++ int i; + + spi_message_init(&m); + + if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) + cmd_sz = 1; + +- flash->command[0] = nor->program_opcode; +- m25p_addr2cmd(nor, to, flash->command); ++ command[0] = nor->program_opcode; ++ m25p_addr2cmd(nor, to, command); ++ memcpy(&command[cmd_sz], buf, len); + +- t[0].tx_buf = flash->command; +- t[0].len = cmd_sz; ++ t[0].tx_buf = command; ++ t[0].len = cmd_sz + len; + spi_message_add_tail(&t[0], &m); + +- t[1].tx_buf = buf; +- t[1].len = len; +- spi_message_add_tail(&t[1], &m); +- + spi_sync(spi, &m); + + *retlen += m.actual_length - cmd_sz; ++ ++ kfree(command); + } + + static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor)