Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757284Ab1F1LLw (ORCPT ); Tue, 28 Jun 2011 07:11:52 -0400 Received: from metis.ext.pengutronix.de ([92.198.50.35]:57951 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756702Ab1F1LKy (ORCPT ); Tue, 28 Jun 2011 07:10:54 -0400 Date: Tue, 28 Jun 2011 13:10:43 +0200 From: Uwe =?iso-8859-1?Q?Kleine-K=F6nig?= To: Nicolas Ferre Cc: linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org, hong.xu@atmel.com, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH] MTD: atmel_nand: optimize read/write buffer functions Message-ID: <20110628111043.GH6588@pengutronix.de> References: <1309261856-27402-1-git-send-email-nicolas.ferre@atmel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1309261856-27402-1-git-send-email-nicolas.ferre@atmel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SA-Exim-Connect-IP: 2001:6f8:1178:2:215:17ff:fe12:23b0 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3433 Lines: 102 On Tue, Jun 28, 2011 at 01:50:56PM +0200, Nicolas Ferre wrote: > For PIO NAND access functions, we use the features of the SMC: > - no need to take into account the NAND bus width: SMC will deal with this > - a word aligned memcpy on the NAND chip-select space is able to generate > proper SMC behavior while optimizing AHB bus usage thanks to optimized memcpy > implementation. > > Signed-off-by: Nicolas Ferre > --- > drivers/mtd/nand/atmel_nand.c | 71 +++++++++++++++++----------------------- > 1 files changed, 30 insertions(+), 41 deletions(-) > > diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c > index b300705..cb8a04b 100644 > --- a/drivers/mtd/nand/atmel_nand.c > +++ b/drivers/mtd/nand/atmel_nand.c > @@ -160,37 +160,6 @@ 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); > @@ -265,33 +234,53 @@ 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; > + u32 align; > + u8 *pbuf; > > 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 (host->board->bus_width_16) > - atmel_read_buf16(mtd, buf, len); > - else > - atmel_read_buf8(mtd, buf, len); > + /* if no DMA operation possible, use PIO */ > + pbuf = buf; > + align = 0x03 & ((unsigned)pbuf); > + > + if (align) { > + u32 align_len = 4 - align; > + > + /* non aligned buffer: re-align to next word boundary */ > + ioread8_rep(chip->IO_ADDR_R, pbuf, align_len); > + pbuf += align_len; > + len -= align_len; > + } > + memcpy((void *)pbuf, chip->IO_ADDR_R, len); I think you don't need to cast to (void *). I think you need to cast the 2nd parameter instead because sparse don't like you passing an void __iomem *. Is it correct to read from chip->IO_ADDR_R, don't you need chip->IO_ADDR_R + align_len? Taking this into account, does it really help to align pbuf? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/