From patchwork Mon Aug 2 07:52:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Mingkai-B21284 X-Patchwork-Id: 116455 Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o728Mhgi023537 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 2 Aug 2010 08:23:19 GMT Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1OfqID-0003F6-Ho; Mon, 02 Aug 2010 08:22:41 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1OfqIC-0003F0-Ge for spi-devel-general@lists.sourceforge.net; Mon, 02 Aug 2010 08:22:40 +0000 X-ACL-Warn: Received: from db3ehsobe002.messaging.microsoft.com ([213.199.154.140] helo=DB3EHSOBE002.bigfish.com) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-MD5:128) (Exim 4.69) id 1OfqIB-0001At-JP for spi-devel-general@lists.sourceforge.net; Mon, 02 Aug 2010 08:22:40 +0000 Received: from mail49-db3-R.bigfish.com (10.3.81.240) by DB3EHSOBE002.bigfish.com (10.3.84.22) with Microsoft SMTP Server id 8.1.436.0; Mon, 2 Aug 2010 08:07:25 +0000 Received: from mail49-db3 (localhost.localdomain [127.0.0.1]) by mail49-db3-R.bigfish.com (Postfix) with ESMTP id B8A2214A843D for ; Mon, 2 Aug 2010 08:07:25 +0000 (UTC) X-SpamScore: 17 X-BigFish: VS17(zz936eM6aa9wzz1202hzzz2dh2a8h465j419m61h) X-Spam-TCS-SCL: 0:0 Received: from mail49-db3 (localhost.localdomain [127.0.0.1]) by mail49-db3 (MessageSwitch) id 1280736445138703_24830; Mon, 2 Aug 2010 08:07:25 +0000 (UTC) Received: from DB3EHSMHS006.bigfish.com (unknown [10.3.81.248]) by mail49-db3.bigfish.com (Postfix) with ESMTP id 1FB80B40053 for ; Mon, 2 Aug 2010 08:07:25 +0000 (UTC) Received: from az33egw02.freescale.net (192.88.158.103) by DB3EHSMHS006.bigfish.com (10.3.87.106) with Microsoft SMTP Server (TLS) id 14.0.482.44; Mon, 2 Aug 2010 08:07:15 +0000 Received: from de01smr01.freescale.net (de01smr01.freescale.net [10.208.0.31]) by az33egw02.freescale.net (8.14.3/8.14.3) with ESMTP id o7287D7C012356 for ; Mon, 2 Aug 2010 01:07:14 -0700 (MST) Received: from zch01exm21.fsl.freescale.net (zch01exm21.ap.freescale.net [10.192.129.205]) by de01smr01.freescale.net (8.13.1/8.13.0) with ESMTP id o728JmSe021245 for ; Mon, 2 Aug 2010 03:19:56 -0500 (CDT) Received: from localhost ([10.193.20.106]) by zch01exm21.fsl.freescale.net with Microsoft SMTPSVC(6.0.3790.3959); Mon, 2 Aug 2010 16:07:05 +0800 From: Mingkai Hu To: linuxppc-dev@ozlabs.org, spi-devel-general@lists.sourceforge.net Date: Mon, 2 Aug 2010 15:52:02 +0800 Message-ID: <1280735524-17547-5-git-send-email-Mingkai.hu@freescale.com> X-Mailer: git-send-email 1.6.4 In-Reply-To: <1280735524-17547-4-git-send-email-Mingkai.hu@freescale.com> References: <1280735524-17547-1-git-send-email-Mingkai.hu@freescale.com> <1280735524-17547-2-git-send-email-Mingkai.hu@freescale.com> <1280735524-17547-3-git-send-email-Mingkai.hu@freescale.com> <1280735524-17547-4-git-send-email-Mingkai.hu@freescale.com> X-OriginalArrivalTime: 02 Aug 2010 08:07:05.0729 (UTC) FILETIME=[B24F1710:01CB3219] MIME-Version: 1.0 X-Reverse-DNS: az33egw02.freescale.net X-Spam-Score: 0.0 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. _SUMMARY_ X-Headers-End: 1OfqIB-0001At-JP Cc: kumar.gala@freescale.com, tie-fei.zang@freescale.com, Mingkai Hu Subject: [spi-devel-general] [PATCH v2 4/6] mtd: m25p80: add a read function to read page by page X-BeenThere: spi-devel-general@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux SPI core/device drivers discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: spi-devel-general-bounces@lists.sourceforge.net X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 02 Aug 2010 08:23:19 +0000 (UTC) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 5f00075..30e4568 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -376,6 +376,81 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, } /* + * Read an address range from the flash chip page by page. + * Some controller has transaction length limitation such as the + * Freescale's eSPI controller can only trasmit 0xFFFF bytes one + * time, so we have to read page by page if the len is more than + * the limitation. + */ +static int m25p80_page_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct m25p *flash = mtd_to_m25p(mtd); + struct spi_transfer t[2]; + struct spi_message m; + u32 i, page_size = 0; + + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", + dev_name(&flash->spi->dev), __func__, "from", + (u32)from, len); + + /* sanity checks */ + if (!len) + return 0; + + if (from + len > flash->mtd.size) + return -EINVAL; + + spi_message_init(&m); + memset(t, 0, (sizeof t)); + + /* NOTE: + * OPCODE_FAST_READ (if available) is faster. + * Should add 1 byte DUMMY_BYTE. + */ + t[0].tx_buf = flash->command; + t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = buf; + spi_message_add_tail(&t[1], &m); + + /* Byte count starts at zero. */ + if (retlen) + *retlen = 0; + + mutex_lock(&flash->lock); + + /* Wait till previous write/erase is done. */ + if (wait_till_ready(flash)) { + /* REVISIT status return?? */ + mutex_unlock(&flash->lock); + return 1; + } + + /* Set up the write data buffer. */ + flash->command[0] = OPCODE_READ; + + for (i = page_size; i < len; i += page_size) { + page_size = len - i; + if (page_size > flash->page_size) + page_size = flash->page_size; + m25p_addr2cmd(flash, from + i, flash->command); + t[1].len = page_size; + t[1].rx_buf = buf + i; + + spi_sync(flash->spi, &m); + + *retlen += m.actual_length - m25p_cmdsz(flash) + - FAST_READ_DUMMY_BYTE; + } + + mutex_unlock(&flash->lock); + + return 0; +} + +/* * Write an address range to the flash chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided * it is within the physical boundaries. @@ -877,6 +952,9 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; + if (spi->master->flags & SPI_MASTER_TRANS_LIMIT) + flash->mtd.read = m25p80_page_read; + /* sst flash chips use AAI word program */ if (info->jedec_id >> 16 == 0xbf) flash->mtd.write = sst_write; diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index 61987cf..e15b7dc 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c @@ -470,6 +470,7 @@ static struct spi_master * __devinit fsl_espi_probe(struct device *dev, goto err_probe; master->setup = fsl_espi_setup; + master->flags = SPI_MASTER_TRANS_LIMIT; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_espi_do_one_msg; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index af56071..0729cbd 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -261,6 +261,7 @@ struct spi_master { #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ #define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */ #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ +#define SPI_MASTER_TRANS_LIMIT BIT(3) /* have trans length limit */ /* Setup mode and clock, etc (spi driver may call many times). *