From patchwork Thu Aug 25 13:29:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanimir Varbanov X-Patchwork-Id: 111570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 09D6CB6F83 for ; Thu, 25 Aug 2011 23:30:17 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qwa0B-0003pO-OY; Thu, 25 Aug 2011 13:29:48 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Qwa0B-00030C-7j; Thu, 25 Aug 2011 13:29:47 +0000 Received: from ns.mm-sol.com ([213.240.235.226] helo=extserv.mm-sol.com) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qwa07-0002zA-H1 for linux-mtd@lists.infradead.org; Thu, 25 Aug 2011 13:29:44 +0000 Received: from intsrv.int.mm-sol.com (unknown [172.18.0.2]) by extserv.mm-sol.com (Postfix) with ESMTP id 5B10AC3F6; Thu, 25 Aug 2011 16:29:42 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by intsrv.int.mm-sol.com (Postfix) with ESMTP id 50E20D26020; Thu, 25 Aug 2011 16:29:42 +0300 (EEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from intsrv.int.mm-sol.com ([127.0.0.1]) by localhost (mail.mm-sol.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MIiGtwh9HGmi; Thu, 25 Aug 2011 16:29:32 +0300 (EEST) Received: from localhost (svarbanov.int.mm-sol.com [172.20.4.186]) by intsrv.int.mm-sol.com (Postfix) with ESMTP id B2EAED2601D; Thu, 25 Aug 2011 16:29:32 +0300 (EEST) From: Stanimir Varbanov To: spi-devel-general@lists.sourceforge.net, linux-mtd@lists.infradead.org Subject: [PATCH/RFC 2/2] mtd: m25p80: Call a platform power method in the driver Date: Thu, 25 Aug 2011 16:29:12 +0300 Message-Id: X-Mailer: git-send-email 1.7.4.1 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110825_092943_905902_FA843DDE X-CRM114-Status: GOOD ( 13.95 ) X-Spam-Score: -0.5 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: grant.likely@secretlab.ca, Stanimir Varbanov , artem.bityutskiy@intel.com, dwmw2@infradead.org X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org On some devices the flash chip could be powered off when m25p driver is probed. To avoid erroneous detection the power of the chip must be turn on, add a power function in m25p_probe to switch on the power by platform data. The power will be turned off at the probe end. Also implement a get/put_device callbacks to power on/off the flash chip. Signed-off-by: Stanimir Varbanov --- drivers/mtd/devices/m25p80.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index e6ba034..6ab5896 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -806,6 +806,27 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) return ERR_PTR(-ENODEV); } +static void m25p_power(struct flash_platform_data *pdata, int on) +{ + if (pdata && pdata->power) + pdata->power(on); +} + +static int m25p_get_device(struct mtd_info *mtd) +{ + struct flash_platform_data *pdata = mtd->dev.parent->platform_data; + + m25p_power(pdata, 1); + + return 0; +} + +static void m25p_put_device(struct mtd_info *mtd) +{ + struct flash_platform_data *pdata = mtd->dev.parent->platform_data; + + m25p_power(pdata, 0); +} /* * board specific setup should have ensured the SPI clock used here @@ -820,6 +841,7 @@ static int __devinit m25p_probe(struct spi_device *spi) struct flash_info *info; unsigned i; struct mtd_part_parser_data ppdata; + int ret; /* Platform data helps sort out which chip type we have, as * well as how this board partitions it. If we don't have @@ -845,12 +867,16 @@ static int __devinit m25p_probe(struct spi_device *spi) info = (void *)id->driver_data; + /* power on device while probing */ + m25p_power(data, 1); + if (info->jedec_id) { const struct spi_device_id *jid; jid = jedec_probe(spi); if (IS_ERR(jid)) { - return PTR_ERR(jid); + ret = PTR_ERR(jid); + goto out; } else if (jid != id) { /* * JEDEC knows better, so overwrite platform ID. We @@ -867,12 +893,15 @@ static int __devinit m25p_probe(struct spi_device *spi) } flash = kzalloc(sizeof *flash, GFP_KERNEL); - if (!flash) - return -ENOMEM; + if (!flash) { + ret = -ENOMEM; + goto out; + } flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); if (!flash->command) { kfree(flash); - return -ENOMEM; + ret = -ENOMEM; + goto out; } flash->spi = spi; @@ -902,6 +931,8 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.size = info->sector_size * info->n_sectors; flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; + flash->mtd.get_device = m25p_get_device; + flash->mtd.put_device = m25p_put_device; /* sst flash chips use AAI word program */ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) @@ -956,6 +987,8 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.eraseregions[i].erasesize / 1024, flash->mtd.eraseregions[i].numblocks); +out: + m25p_power(data, 0); /* partitions should match sector boundaries; and it may be good to * use readonly partitions for writeprotected sectors (BP2..BP0).