From patchwork Sat Jun 25 18:20:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Drake X-Patchwork-Id: 918372 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5PIibJW031344 for ; Sat, 25 Jun 2011 18:44:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751809Ab1FYSog (ORCPT ); Sat, 25 Jun 2011 14:44:36 -0400 Received: from queueout04-winn.ispmail.ntl.com ([81.103.221.58]:48691 "EHLO queueout04-winn.ispmail.ntl.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751678Ab1FYSof (ORCPT ); Sat, 25 Jun 2011 14:44:35 -0400 Received: from aamtaout03-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout03-winn.ispmail.ntl.com (InterMail vM.7.08.04.00 201-2186-134-20080326) with ESMTP id <20110625182013.UJMW5301.mtaout03-winn.ispmail.ntl.com@aamtaout03-winn.ispmail.ntl.com>; Sat, 25 Jun 2011 19:20:13 +0100 Received: from zog.reactivated.net ([86.14.215.141]) by aamtaout03-winn.ispmail.ntl.com (InterMail vG.3.00.04.00 201-2196-133-20080908) with ESMTP id <20110625182013.TNXX24017.aamtaout03-winn.ispmail.ntl.com@zog.reactivated.net>; Sat, 25 Jun 2011 19:20:13 +0100 Received: by zog.reactivated.net (Postfix, from userid 1000) id 7CB8E9D401C; Sat, 25 Jun 2011 19:20:11 +0100 (BST) From: Daniel Drake To: cjb@laptop.org Cc: linux-mmc@vger.kernel.org Cc: ohad@wizery.com Subject: [PATCH] mmc: sdio: reset card during power_restore Message-Id: <20110625182011.7CB8E9D401C@zog.reactivated.net> Date: Sat, 25 Jun 2011 19:20:11 +0100 (BST) X-Cloudmark-Analysis: v=1.1 cv=JvdXmxIgLJv2/GthKqHpGJEEHukvLcvELVXUanXFreg= c=1 sm=0 a=QfTNKbwSQXoA:10 a=vJ1w_8FsMGIA:10 a=Op-mwl0xAAAA:8 a=Vk7Tw0Xac2v01vbl2PgA:9 a=OhgPWCVca2bcfbZd1Q8A:7 a=d4CUUju0HPYA:10 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Sat, 25 Jun 2011 18:44:37 +0000 (UTC) mmc_sdio_power_restore() skips some steps that are performed in other power-related codepaths which are necessary to fully reset the card. Without this, runtime PM fails for SD8686 SDIO wifi on OLPC XO-1.5. Signed-off-by: Daniel Drake Acked-by: Ohad Ben-Cohen --- drivers/mmc/core/sdio.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-) Replaces existing patch with the same name diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4d0c15b..262fff0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -691,15 +691,54 @@ static int mmc_sdio_resume(struct mmc_host *host) static int mmc_sdio_power_restore(struct mmc_host *host) { int ret; + u32 ocr; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); + + /* + * Reset the card by performing the same steps that are taken by + * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. + * + * sdio_reset() is technically not needed. Having just powered up the + * hardware, it should already be in reset state. However, some + * platforms (such as SD8686 on OLPC) do not instantly cut power, + * meaning that a reset is required when restoring power soon after + * powering off. It is harmless in other cases. + * + * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, + * is not necessary for non-removable cards. However, it is required + * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and + * harmless in other situations. + * + * With these steps taken, mmc_select_voltage() is also required to + * restore the correct voltage setting of the card. + */ + sdio_reset(host); + mmc_go_idle(host); + mmc_send_if_cond(host, host->ocr_avail); + + ret = mmc_send_io_op_cond(host, 0, &ocr); + if (ret) + goto out; + + if (host->ocr_avail_sdio) + host->ocr_avail = host->ocr_avail_sdio; + + host->ocr = mmc_select_voltage(host, ocr & ~0x7F); + if (!host->ocr) { + ret = -EINVAL; + goto out; + } + ret = mmc_sdio_init_card(host, host->ocr, host->card, mmc_card_keep_power(host)); if (!ret && host->sdio_irqs) mmc_signal_sdio_irq(host); + +out: mmc_release_host(host); return ret;