Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3379783imu; Mon, 19 Nov 2018 15:15:02 -0800 (PST) X-Google-Smtp-Source: AJdET5fIZkS3v/0MrMSxyoowgsGOEjfbDywtBqXHMMxkYzl8WkwYIo0GB4kwsvWG4hCsvAQc2wns X-Received: by 2002:a63:4c04:: with SMTP id z4mr22151976pga.312.1542669302117; Mon, 19 Nov 2018 15:15:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542669302; cv=none; d=google.com; s=arc-20160816; b=0q/owUif2Z/s07v7P6M2lNMjZcUosEFPylvcMppKHZ4/UQHOdnhSOstYv7XXcbUGuz hobA6aQaHIA+WlEwGl7ofLSUyIK9r+dUtkMjX1uU8nGzX8rwI6H7bLjaWlBbs7Kt5qK5 NMvQPS3ZBKRA0ZDHUBkdKpVekBC0RyoeYmFlkcM82PzCy1vC75PCl6FQjbSc0SXYZib4 2r9yXJWPDgN2HQzXhjAeNvv+RDvNg7Kuw8U+RvjfsTeCy9E6rMANLoyD1jgKOat5fQFX zkxV7CNODrz7yXKaNnEOoRJq2P1fhOiLIwqQi4I7VvbMfpLZOswSDzaz3VxgH3j+cxKt W9jA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=RsmIFVb84mOLf5pXjua5n0sKSSUczC8r6ntH+XSU4go=; b=v0Zvst8UQ3UySO0yO7sxxg5ZgdDP1MpP8rX8Y9GXF9qLe5Q2tJdG+07XB5nUnD0cjb LaQJy9JUo2JVgAa01uJyGT2Yx6F5EY+M6gjYeJoDS/zOeBWnlU6nFauGvRCKkgH8Tqy3 JYdarc8wNcz8uwacqNdtTnvRFjVo97HZY7uXrUqzlF2XrWKsnoQ6+BdQwySOh5T30YsN Gd349/J/QIi+wj44p/FJkt2ad/ZmqPHXZHTOuCWfbfy8hEVZ1R02CFpisUJGAFPwlpq/ c8lKnrnXdyWcYy1j5aWkcH1NY0kxXvCk8pV1GvQJVLZ9QK0tv0zeziUKDjnSlGL42z/4 H22A== 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 a32si886503pla.168.2018.11.19.15.14.45; Mon, 19 Nov 2018 15:15:02 -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 S1730943AbeKTJkG (ORCPT + 99 others); Tue, 20 Nov 2018 04:40:06 -0500 Received: from emh01.mail.saunalahti.fi ([62.142.5.107]:33902 "EHLO emh01.mail.saunalahti.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728979AbeKTJkG (ORCPT ); Tue, 20 Nov 2018 04:40:06 -0500 Received: from localhost.localdomain (85-76-71-135-nat.elisa-mobile.fi [85.76.71.135]) by emh01.mail.saunalahti.fi (Postfix) with ESMTP id 4386F2003A; Tue, 20 Nov 2018 01:14:03 +0200 (EET) From: Aaro Koskinen To: Ulf Hansson Cc: Tony Lindgren , Ladislav Michl , Andrzej Zaborowski , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, Aaro Koskinen Subject: [PATCH v2] MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310 Date: Tue, 20 Nov 2018 01:14:00 +0200 Message-Id: <20181119231400.2375-1-aaro.koskinen@iki.fi> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20181118201919.14401-1-aaro.koskinen@iki.fi> References: <20181118201919.14401-1-aaro.koskinen@iki.fi> 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 (OMAP5910 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 Tested-by: Ladislav Michl Acked-by: Tony Lindgren Signed-off-by: Aaro Koskinen --- v2: Corrected commit message: OMAP5912 => OMAP5910 Added Tested-by and Acked-by tags. v1: https://marc.info/?t=154258870700045&r=1&w=2 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