From patchwork Wed Jan 29 22:37:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 23903 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f197.google.com (mail-pd0-f197.google.com [209.85.192.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0442C20300 for ; Wed, 29 Jan 2014 22:38:23 +0000 (UTC) Received: by mail-pd0-f197.google.com with SMTP id x10sf5131040pdj.4 for ; Wed, 29 Jan 2014 14:38:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=z90lnWvWfNCWa5rVWpACPo4JTxwKaiBNG7untASMYcw=; b=LRQfNG/0CdbWYko1pFrHE1vB1/E49iZKG1ZalwQ2vk00ZYq+j+ZxV86FTKcbnwz/nF upI7Xf043OIZlEeP9juvxbhn3tpCaCGIxknu/zu88fJE/wo1tkZXCr01ZM2XicstnVcR 7rUMRVU/wH6Ufak5KnqP1CcZ7bwNLrOwcn/3rOE+znVWI0GO9wEDLcos83vA4HyB/3jB r1zEh7umd8A1UNRrAc5+8XHaEK4h9L8+8lcTWbsk6l1I6pvzWwhsI9i3u3WNnxqIWTAj FJ/C2D+zZPlzKL2RJIA+p9apSN0Gl8QS6uwjVwSiD6B7yP5kUbYLxomEvOE8+o9N1AUM ffCg== X-Gm-Message-State: ALoCoQmqwpd2iCW4sRlW4lETHhIY6cz7kccE0XJgJ9USTaiucdesAC/DjWP1yh8aUH14XW6tCscd X-Received: by 10.69.16.98 with SMTP id fv2mr3982383pbd.7.1391035103317; Wed, 29 Jan 2014 14:38:23 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.24.215 with SMTP id 81ls339556qgr.14.gmail; Wed, 29 Jan 2014 14:38:23 -0800 (PST) X-Received: by 10.52.166.9 with SMTP id zc9mr7319114vdb.16.1391035103111; Wed, 29 Jan 2014 14:38:23 -0800 (PST) Received: from mail-vb0-f48.google.com (mail-vb0-f48.google.com [209.85.212.48]) by mx.google.com with ESMTPS id ls10si1254830vec.19.2014.01.29.14.38.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Jan 2014 14:38:23 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.48 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.48; Received: by mail-vb0-f48.google.com with SMTP id q16so1560621vbe.7 for ; Wed, 29 Jan 2014 14:38:23 -0800 (PST) X-Received: by 10.52.157.8 with SMTP id wi8mr122383vdb.46.1391035103024; Wed, 29 Jan 2014 14:38:23 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp152461vcz; Wed, 29 Jan 2014 14:38:22 -0800 (PST) X-Received: by 10.112.173.6 with SMTP id bg6mr6711576lbc.17.1391035102140; Wed, 29 Jan 2014 14:38:22 -0800 (PST) Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) by mx.google.com with ESMTPS id t10si1982438lat.27.2014.01.29.14.38.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Jan 2014 14:38:22 -0800 (PST) Received-SPF: neutral (google.com: 209.85.217.180 is neither permitted nor denied by best guess record for domain of ulf.hansson@linaro.org) client-ip=209.85.217.180; Received: by mail-lb0-f180.google.com with SMTP id n15so1983879lbi.11 for ; Wed, 29 Jan 2014 14:38:21 -0800 (PST) X-Received: by 10.112.131.100 with SMTP id ol4mr2921592lbb.38.1391035101561; Wed, 29 Jan 2014 14:38:21 -0800 (PST) Received: from linaro-ulf.lan (90-231-160-185-no158.tbcn.telia.com. [90.231.160.185]) by mx.google.com with ESMTPSA id wt2sm3998221lbb.2.2014.01.29.14.38.19 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Jan 2014 14:38:20 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Cc: Dong Aisheng , Stephen Warren , Vladimir Zapolskiy , Adrian Hunter , Ulf Hansson Subject: [PATCH 05/13] mmc: core: Fixup busy detection for mmc switch operations Date: Wed, 29 Jan 2014 23:37:57 +0100 Message-Id: <1391035085-2747-6-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1391035085-2747-1-git-send-email-ulf.hansson@linaro.org> References: <1391035085-2747-1-git-send-email-ulf.hansson@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ulf.hansson@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.48 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , If the host controller supports busy detection in HW, we expect the MMC_CAP_WAIT_WHILE_BUSY to be set. Likewise the corresponding host->max_busy_timeout should reflect the maximum busy detection timeout supported by the host. Previously we expected a host that supported MMC_CAP_WAIT_WHILE_BUSY to cope with any timeout, which just isn't feasible due to HW limitations. For most switch operations, R1B responses are expected and thus we need to check for busy detection completion. To cope with cases where the requested busy detection timeout is greater than what the host are able to support, we fallback to use a R1 response instead. This will prevent the host from doing HW busy detection. In those cases, busy detection completion is handled by polling the for the card's status using CMD13. This is the same mechanism used when the host doesn't support MMC_CAP_WAIT_WHILE_BUSY. Do note, a host->max_busy_timeout set to zero, is interpreted by the mmc core as it don't know what the host supports. It will then provide the host with whatever timeout the mmc core finds suitable. For some cases the mmc core has unfurtunate no clue of what timeout to use. In these cases we provide the host with a timeout value of zero, which the host may interpret as use whatever timeout it finds suitable. Signed-off-by: Ulf Hansson --- drivers/mmc/core/mmc_ops.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 04ecdb9..f51b5ba 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -418,6 +418,17 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, struct mmc_command cmd = {0}; unsigned long timeout; u32 status = 0; + bool use_r1b_resp = use_busy_signal; + + /* + * If the cmd timeout and the max_busy_timeout of the host are both + * specified, let's validate them. A failure means we need to prevent + * the host from doing hw busy detection, which is done by converting + * to a R1 response instead of a R1B. + */ + if (timeout_ms && host->max_busy_timeout && + (timeout_ms > host->max_busy_timeout)) + use_r1b_resp = false; cmd.opcode = MMC_SWITCH; cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | @@ -425,13 +436,17 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, (value << 8) | set; cmd.flags = MMC_CMD_AC; - if (use_busy_signal) + if (use_r1b_resp) { cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; - else + /* + * A busy_timeout of zero means the host can decide to use + * whatever value it finds suitable. + */ + cmd.busy_timeout = timeout_ms; + } else { cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; + } - - cmd.busy_timeout = timeout_ms; if (index == EXT_CSD_SANITIZE_START) cmd.sanitize_busy = true; @@ -447,18 +462,22 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, * CRC errors shall only be ignored in cases were CMD13 is used to poll * to detect busy completion. */ - if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) + if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) ignore_crc = false; + /* We have an unspecified cmd timeout, use the fallback value. */ + if (!timeout_ms) + timeout_ms = MMC_OPS_TIMEOUT_MS; + /* Must check status to be sure of no errors. */ - timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS); + timeout = jiffies + msecs_to_jiffies(timeout_ms); do { if (send_status) { err = __mmc_send_status(card, &status, ignore_crc); if (err) return err; } - if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) + if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) break; if (mmc_host_is_spi(host)) break;