diff options
Diffstat (limited to 'drivers/mtd/nand/atmel_nand.c')
| -rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 45 | 
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 4dd056e2e16..35b4fb55dbd 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -161,6 +161,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)                  !!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)  {  	complete(completion); @@ -235,27 +266,33 @@ err_buf:  static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)  {  	struct nand_chip *chip = mtd->priv; +	struct atmel_nand_host *host = chip->priv;  	if (use_dma && len > mtd->oobsize)  		/* only use DMA for bigger than oob size: better performances */  		if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)  			return; -	/* if no DMA operation possible, use PIO */ -	memcpy_fromio(buf, chip->IO_ADDR_R, len); +	if (host->board->bus_width_16) +		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)  {  	struct nand_chip *chip = mtd->priv; +	struct atmel_nand_host *host = chip->priv;  	if (use_dma && len > mtd->oobsize)  		/* only use DMA for bigger than oob size: better performances */  		if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)  			return; -	/* if no DMA operation possible, use PIO */ -	memcpy_toio(chip->IO_ADDR_W, buf, len); +	if (host->board->bus_width_16) +		atmel_write_buf16(mtd, buf, len); +	else +		atmel_write_buf8(mtd, buf, len);  }  /*  |