提交 50082319 编写于 作者: A Artem Bityutskiy 提交者: David Woodhouse

Revert "mtd: atmel_nand: optimize read/write buffer functions"

This reverts commit fb542750.

The reason is that it breaks 16 bits NAND flash as it was reported by
Nikolaus Voss and confirmed by Eric Bénard.

Nicolas Ferre <nicolas.ferre@atmel.com> alco confirmed:
"After double checking with designers, I must admit that I misunderstood
the way of optimizing accesses to SMC. 16 bit nand is not so common
those days..."
Reported-by: NNikolaus Voss <n.voss@weinmann.de>
Acked-by: NNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: NArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: NDavid Woodhouse <David.Woodhouse@intel.com>
Cc: stable@kernel.org [3.1+]
上级 1a30871f
...@@ -161,6 +161,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) ...@@ -161,6 +161,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
!!host->board->rdy_pin_active_low; !!host->board->rdy_pin_active_low;
} }
/*
* Minimal-overhead PIO for data access.
*/
static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len)
{
struct nand_chip *nand_chip = mtd->priv;
__raw_readsb(nand_chip->IO_ADDR_R, buf, len);
}
static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len)
{
struct nand_chip *nand_chip = mtd->priv;
__raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2);
}
static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len)
{
struct nand_chip *nand_chip = mtd->priv;
__raw_writesb(nand_chip->IO_ADDR_W, buf, len);
}
static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
{
struct nand_chip *nand_chip = mtd->priv;
__raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2);
}
static void dma_complete_func(void *completion) static void dma_complete_func(void *completion)
{ {
complete(completion); complete(completion);
...@@ -235,27 +266,33 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, ...@@ -235,27 +266,33 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len,
static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
{ {
struct nand_chip *chip = mtd->priv; struct nand_chip *chip = mtd->priv;
struct atmel_nand_host *host = chip->priv;
if (use_dma && len > mtd->oobsize) if (use_dma && len > mtd->oobsize)
/* only use DMA for bigger than oob size: better performances */ /* only use DMA for bigger than oob size: better performances */
if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
return; return;
/* if no DMA operation possible, use PIO */ if (host->board->bus_width_16)
memcpy_fromio(buf, chip->IO_ADDR_R, len); atmel_read_buf16(mtd, buf, len);
else
atmel_read_buf8(mtd, buf, len);
} }
static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
{ {
struct nand_chip *chip = mtd->priv; struct nand_chip *chip = mtd->priv;
struct atmel_nand_host *host = chip->priv;
if (use_dma && len > mtd->oobsize) if (use_dma && len > mtd->oobsize)
/* only use DMA for bigger than oob size: better performances */ /* only use DMA for bigger than oob size: better performances */
if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
return; return;
/* if no DMA operation possible, use PIO */ if (host->board->bus_width_16)
memcpy_toio(chip->IO_ADDR_W, buf, len); atmel_write_buf16(mtd, buf, len);
else
atmel_write_buf8(mtd, buf, len);
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册