Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1954048imu; Sun, 18 Nov 2018 12:21:59 -0800 (PST) X-Google-Smtp-Source: AJdET5fMVz5uLK4i+uD+vHgL5r1sGouapNu95n3D1ubuNKy5Bwye016yHL6GSTnm0+VeM1O0MJOf X-Received: by 2002:a62:35c2:: with SMTP id c185-v6mr20276557pfa.82.1542572519442; Sun, 18 Nov 2018 12:21:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542572519; cv=none; d=google.com; s=arc-20160816; b=fJiEhF/tqvPVFjHw+K1Z8i8cnR6d6hRAE71He2VwkY6zztKjZp17YgHpKuMzZnSj7M DM6/4zE/6zVHoG4bxXo7E9FLMbPivM5I6p7JvjNEKI9aGmkGWirWwcV1tRyiVR5y/zzX sW75aVNdplrx2HKvf25Vwak1sEl6hVznlYbGqkV74sPVo6BFsmQP4IVGEbHc8+oLRcPv Cw8FUCW0NPvrJuKZzaBzzCawTz89PpkyEBs+ElWk9zPaOhgYZ9rahzTadIX0r9PVj1ah ExqYwnH4xPTs2YwxFvIBpLrUny7ASBb9fENGpacG/9yXITeSRVN+MIqSp6Px0LeYuxQ/ wIXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=DPgJ2dVv47rznij/uo87Mzpi/7fdA2nyUAZnNvADPig=; b=pMVnkMa1CreGt9OdzW7NGnQtLkRyzzzeN0nvmpjwo3HVSBWUEl5KWy4UOGGxIv/pQO 5DAPt8lDiS+JIPJpEUCvi0uQtyf6nFkuMc/seVdZWAmooFnI85ntrKCMC+2QfoP0oEuE mBTeMNoBcAUUHUKgvUmn3fYtidaen+ERk4UufXl1R7RrFs0g+fScnRCX6h4JDY8rn35x 0JttKsOsteUd/QJlAFfM8UBmch1itk79Xk8DBUU9ancqopqrcLepb81PHlepqemeSfkW hz6o6E8t3NcTfo26yc2LdavxOqsdISEgCcI1Czjt8z2iqVVIrU+6pBZZbPV+jlZ3b6Rf 1aIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=iki.fi Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w187-v6si36090492pfb.8.2018.11.18.12.21.43; Sun, 18 Nov 2018 12:21:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=iki.fi Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727503AbeKSGlE (ORCPT + 99 others); Mon, 19 Nov 2018 01:41:04 -0500 Received: from emh06.mail.saunalahti.fi ([62.142.5.116]:42104 "EHLO emh06.mail.saunalahti.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727381AbeKSGlE (ORCPT ); Mon, 19 Nov 2018 01:41:04 -0500 Received: from localhost.localdomain (85-76-71-135-nat.elisa-mobile.fi [85.76.71.135]) by emh06.mail.saunalahti.fi (Postfix) with ESMTP id 513DF3000B; Sun, 18 Nov 2018 22:19:47 +0200 (EET) From: Aaro Koskinen To: Ulf Hansson , Tony Lindgren , Ladislav Michl , linux-mmc@vger.kernel.org Cc: Andrzej Zaborowski , linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org, Aaro Koskinen Subject: [PATCH] MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5912/OMAP310 Date: Sun, 18 Nov 2018 22:19:19 +0200 Message-Id: <20181118201919.14401-1-aaro.koskinen@iki.fi> X-Mailer: git-send-email 2.17.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since v2.6.22 or so there has been reports [1] about OMAP MMC being broken on OMAP15XX based hardware (OMAP5912 and OMAP310). The breakage seems to have been caused by commit 46a6730e3ff9 ("mmc-omap: Fix omap to use MMC_POWER_ON") that changed clock enabling to be done on MMC_POWER_ON. This can happen multiple times in a row, and on 15XX the hardware doesn't seem to like it and the MMC just stops responding. Fix by memorizing the power mode and do the init only when necessary. Before the patch (on Palm TE): mmc0: new SD card at address b368 mmcblk0: mmc0:b368 SDC 977 MiB mmci-omap mmci-omap.0: command timeout (CMD18) mmci-omap mmci-omap.0: command timeout (CMD13) mmci-omap mmci-omap.0: command timeout (CMD13) mmci-omap mmci-omap.0: command timeout (CMD12) [x 6] mmci-omap mmci-omap.0: command timeout (CMD13) [x 6] mmcblk0: error -110 requesting status mmci-omap mmci-omap.0: command timeout (CMD8) mmci-omap mmci-omap.0: command timeout (CMD18) mmci-omap mmci-omap.0: command timeout (CMD13) mmci-omap mmci-omap.0: command timeout (CMD13) mmci-omap mmci-omap.0: command timeout (CMD12) [x 6] mmci-omap mmci-omap.0: command timeout (CMD13) [x 6] mmcblk0: error -110 requesting status mmcblk0: recovery failed! print_req_error: I/O error, dev mmcblk0, sector 0 Buffer I/O error on dev mmcblk0, logical block 0, async page read mmcblk0: unable to read partition table After the patch: mmc0: new SD card at address b368 mmcblk0: mmc0:b368 SDC 977 MiB mmcblk0: p1 The patch is based on a fix and analysis done by Ladislav Michl. Tested on OMAP15XX/OMAP310 (Palm TE), OMAP1710 (Nokia 770) and OMAP2420 (Nokia N810). [1] https://marc.info/?t=123175197000003&r=1&w=2 Fixes: 46a6730e3ff9 ("mmc-omap: Fix omap to use MMC_POWER_ON") Reported-by: Ladislav Michl Reported-by: Andrzej Zaborowski Signed-off-by: Aaro Koskinen --- drivers/mmc/host/omap.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index adf32682f27a..c60a7625b1fa 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -104,6 +104,7 @@ struct mmc_omap_slot { unsigned int vdd; u16 saved_con; u16 bus_mode; + u16 power_mode; unsigned int fclk_freq; struct tasklet_struct cover_tasklet; @@ -1157,7 +1158,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct mmc_omap_slot *slot = mmc_priv(mmc); struct mmc_omap_host *host = slot->host; int i, dsor; - int clk_enabled; + int clk_enabled, init_stream; mmc_omap_select_slot(slot, 0); @@ -1167,6 +1168,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) slot->vdd = ios->vdd; clk_enabled = 0; + init_stream = 0; switch (ios->power_mode) { case MMC_POWER_OFF: mmc_omap_set_power(slot, 0, ios->vdd); @@ -1174,13 +1176,17 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) case MMC_POWER_UP: /* Cannot touch dsor yet, just power up MMC */ mmc_omap_set_power(slot, 1, ios->vdd); + slot->power_mode = ios->power_mode; goto exit; case MMC_POWER_ON: mmc_omap_fclk_enable(host, 1); clk_enabled = 1; dsor |= 1 << 11; + if (slot->power_mode != MMC_POWER_ON) + init_stream = 1; break; } + slot->power_mode = ios->power_mode; if (slot->bus_mode != ios->bus_mode) { if (slot->pdata->set_bus_mode != NULL) @@ -1196,7 +1202,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) for (i = 0; i < 2; i++) OMAP_MMC_WRITE(host, CON, dsor); slot->saved_con = dsor; - if (ios->power_mode == MMC_POWER_ON) { + if (init_stream) { /* worst case at 400kHz, 80 cycles makes 200 microsecs */ int usecs = 250; @@ -1234,6 +1240,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) slot->host = host; slot->mmc = mmc; slot->id = id; + slot->power_mode = MMC_POWER_UNDEFINED; slot->pdata = &host->pdata->slots[id]; host->slots[id] = slot; -- 2.17.0