From patchwork Tue Nov 12 12:40:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179184 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp8058591ilf; Tue, 12 Nov 2019 04:40:33 -0800 (PST) X-Received: by 2002:a2e:2c19:: with SMTP id s25mr5979296ljs.26.1573562433102; Tue, 12 Nov 2019 04:40:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573562433; cv=none; d=google.com; s=arc-20160816; b=tCkoORUtS3qj4OD3xElY6CpW7xGs8ykvR4oD28k8Nw7eSk4dXEVOI0VnIytoTUlt6E stm6oGCfw0VncID8C3tRbgHG+7Cf5C+xRjiw7Fh0RtvceMUeM9bgEe+GWuYT16e9BUxV 7UPoW1j8aDv8HjqbyLEvNimpWstHGYqJdgrR1KV3WJwQSFmQzys9IVrzL0Aab9j0fg9R QEX9XqXaXSUpNeZGfPKuqb8QKmUFHqIGQcnEcZGzawwRTUxYlv23lQa30yuxR2ek01gk Oyoa200pYz/qNF8JLX3/Evd1uWtFFR3EL1eXpH6d4+ePs8xxsiMMXUDbhw8XXZ/fNlev VN9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=us61Nofstcz0gBzGHxcAtP5U1t6DToeD3Uw4J7qpjsn3y37Y9O0tsNlD0LHoqe5tcV pRRQfrOZdYLzhTcqwH9sPJbzAOdCtylCzqxOmWtWaxD0urDum2v2c33JIgs4PQAyjHS5 Pa4TsGp3/9P6V8MoNRYIFJmWrWnSXz93+vXhKvlqIlqoBpzXsBENAdw8jN1N3n6FtU9o txsiatkq4P5QZB0XEs3J5kBvZe35DTzRwOgoLbtAERhF4/+IOYLG+7HGUDPI8aI0B2pe PKgi6zvea3td58BWDPbqhzSNRQEbJcP64koB2/+dpIcwjIb+VwgPbiurpUT/OlHuBenk gXCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iquP1sqS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id d16sor5098794lfi.66.2019.11.12.04.40.30 for (Google Transport Security); Tue, 12 Nov 2019 04:40:33 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iquP1sqS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=iquP1sqSevDyN6H4A0gAob9E9nwT6mnSoekR+cRxTs9X53+YlmG+LaN167dDKZ5Gan gZoWe5j1hLDegpBYIb3CM+6rqy3xxqj1HIe/sDGSrKqgB0FOCq6hstZ6bV33oYwIBxwR xmk8GVvhquNb7xsF1HBK5Z86pK6yHlSwQBB3a3/J20s353hEdEoGD6h+G9dMvnnL2/bh T1fbssj4pvKA6CkccU034eVO8Xc6LhuswNyDGOTi75CQwgh2+eGSZCDHnGWeWzc888QV 6G8voK5p+WOpR1Sn+04Nx+S2aMEfUgyNHIRyAXTABA4o6ahmb98wkKkXaare8o4uoHNU FxfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=H7E6ef2lWK98O9hR0JBpUYN4vBm7i7Y46fWC8cj2T1eW3CP2HGssii155m4M53UK95 FeyEc/Dlu9JJT7IEw9MnSCiiuxQizhR7ldCkm4jvp+XftI0lst1xBXV1q5TexyaCdAQk No2X8rC+0urHpsDHCeFMaPvf98l5gkDu19SDt3No4iVLGEOa9JvoypFnqughA2JiatVh Mxw44LOc1id8SJYZYRexTX6et1+XRNDqxhN83pGTITm+4+hoOChvWB4gXQJYDrbm6YTf pFGxEZUHfymEEQLk/HKrY6zqAa7ARPndZYQa9f+qGLovULgNT1OOecrj4nmPgYH233vg SPsQ== X-Gm-Message-State: APjAAAXgmDGoBTUAmHtXYUYiQtXDwGWFjPWrHwmpdl/l6cvqQ9Zkjmgf se4rEr55lkv13lprnLWWiKu5ZV9+ X-Google-Smtp-Source: APXvYqxxXzYQvwF+vKgB/yos7imzceRusxPiynjFik+jDFzy0koMp4aiZO329S7Es2YzErYJ7JFiXQ== X-Received: by 2002:a19:22d3:: with SMTP id i202mr19032642lfi.69.1573562429941; Tue, 12 Nov 2019 04:40:29 -0800 (PST) Return-Path: Received: from uffe-XPS-13-9360.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id z19sm8375096ljk.66.2019.11.12.04.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2019 04:40:29 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Douglas Anderson , Matthias Kaehlcke Cc: Kalle Valo , Tony Lindgren , Wen Gong , Erik Stromdahl , Eyal Reizer , linux-wireless@vger.kernel.org Subject: [PATCH v3 1/3] mwifiex: Re-work support for SDIO HW reset Date: Tue, 12 Nov 2019 13:40:19 +0100 Message-Id: <20191112124021.8718-2-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191112124021.8718-1-ulf.hansson@linaro.org> References: <20191112124021.8718-1-ulf.hansson@linaro.org> The SDIO HW reset procedure in mwifiex_sdio_card_reset_work() is broken, when the SDIO card is shared with another SDIO func driver. This is the case when the Bluetooth btmrvl driver is being used in combination with mwifiex. More precisely, when mwifiex_sdio_card_reset_work() runs to resets the SDIO card, the btmrvl driver doesn't get notified about it. Beyond that point, the btmrvl driver will fail to communicate with the SDIO card. This is a generic problem for SDIO func drivers sharing an SDIO card, which are about to be addressed in subsequent changes to the mmc core and the mmc_hw_reset() interface. In principle, these changes means the mmc_hw_reset() interface starts to return 1 if the are multiple drivers for the SDIO card, as to indicate to the caller that the reset needed to be scheduled asynchronously through a hotplug mechanism of the SDIO card. Let's prepare the mwifiex driver to support the upcoming new behaviour of mmc_hw_reset(), which means extending the mwifiex_sdio_card_reset_work() to support the asynchronous SDIO HW reset path. This also means, we need to allow the ->remove() callback to run, without waiting for the FW to be loaded. Additionally, during system suspend, mwifiex_sdio_suspend() may be called when a reset has been scheduled, but waiting to be executed. In this scenario let's simply return -EBUSY to abort the suspend process, as to allow the reset to be completed first. Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Ulf Hansson --- drivers/net/wireless/marvell/mwifiex/main.c | 5 +++- drivers/net/wireless/marvell/mwifiex/main.h | 1 + drivers/net/wireless/marvell/mwifiex/sdio.c | 33 ++++++++++++++------- 3 files changed, 27 insertions(+), 12 deletions(-) -- 2.17.1 diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a9657ae6d782..d14e55e3c9da 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -631,6 +631,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); mwifiex_dbg(adapter, MSG, "driver_version = %s\n", fmt); + adapter->is_up = true; goto done; err_add_intf: @@ -1469,6 +1470,7 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) mwifiex_deauthenticate(priv, NULL); mwifiex_uninit_sw(adapter); + adapter->is_up = false; if (adapter->if_ops.down_dev) adapter->if_ops.down_dev(adapter); @@ -1730,7 +1732,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter) if (!adapter) return 0; - mwifiex_uninit_sw(adapter); + if (adapter->is_up) + mwifiex_uninit_sw(adapter); if (adapter->irq_wakeup >= 0) device_init_wakeup(adapter->dev, false); diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 095837fba300..547ff3c578ee 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -1017,6 +1017,7 @@ struct mwifiex_adapter { /* For synchronizing FW initialization with device lifecycle. */ struct completion *fw_done; + bool is_up; bool ext_scan; u8 fw_api_ver; diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 24c041dad9f6..fec38b6e86ff 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -444,6 +444,9 @@ static int mwifiex_sdio_suspend(struct device *dev) return 0; } + if (!adapter->is_up) + return -EBUSY; + mwifiex_enable_wake(adapter); /* Enable the Host Sleep */ @@ -2220,22 +2223,30 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) struct sdio_func *func = card->func; int ret; + /* Prepare the adapter for the reset. */ mwifiex_shutdown_sw(adapter); + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - /* power cycle the adapter */ + /* Run a HW reset of the SDIO interface. */ sdio_claim_host(func); - mmc_hw_reset(func->card->host); + ret = mmc_hw_reset(func->card->host); sdio_release_host(func); - /* Previous save_adapter won't be valid after this. We will cancel - * pending work requests. - */ - clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); - clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - - ret = mwifiex_reinit_sw(adapter); - if (ret) - dev_err(&func->dev, "reinit failed: %d\n", ret); + switch (ret) { + case 1: + dev_dbg(&func->dev, "SDIO HW reset asynchronous\n"); + complete_all(adapter->fw_done); + break; + case 0: + ret = mwifiex_reinit_sw(adapter); + if (ret) + dev_err(&func->dev, "reinit failed: %d\n", ret); + break; + default: + dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret); + break; + } } /* This function read/write firmware */ From patchwork Tue Nov 12 12:40:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179182 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp8058590ilf; Tue, 12 Nov 2019 04:40:33 -0800 (PST) X-Received: by 2002:a2e:558:: with SMTP id 85mr20280114ljf.67.1573562433098; Tue, 12 Nov 2019 04:40:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573562433; cv=none; d=google.com; s=arc-20160816; b=UiCN9/iZllkVWXmSm1X9c/4CwAbOBL2oCjXSPiv6UDYhMGqFL7bZJhLSpB/NVP9Igw GDCRnYh1w1nR0BaoVk1q8sqkdwKRF0Ueo6yAy7jxjUHtYV0dftasT07ANGfHKWTSRKnQ i+sMEeJjUgPU0/02DgQpAV4dJB4nlUIVVs9S0lCdJUcK1a5bNFeHBgCfW7vvq+y3TIw3 dsiKyCkwQq4eX0k9FbPCFh+KjhQsny12q/D6JIIYNpjBKdd7TwyihFK3qQIk4Zc63cwV hYTuogdP8JZiWWeVbk2/UCvhje/DABORUWjF4oNYWRprxDKdouzLbIQBh5GCys15U4In CS2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=9Sqm3/Atz5RClYiYSLOTyjJ1qxSb0WxsX/5dNJbrB0s=; b=0BVsZdneJlPb8K1+l5cZBiYGMtCnnToI/ZcYuvGf1iQld9znSk09lVZpM+6+Dt1LOH grjC0LJsEpeuA6MgzKL01c4UphjtDuiwcCAYEHlE+5zenXOnk06Px1+jeTs4numPPBUz ejTuWMbl1T0PDK7q3hBGrcmrIVB+mgEGI5mJ+Etq0o4fIfKc5IofSx2hJWxIU1vNUWP0 HV+46sINVyOqjeq4JxRlrR4SOkWGytbRzBObNf87snVuwi8eEZCC7F+TK0GlQb4fBGPc PqO+E7DJP95ghdD21s4GlsjEfhmnBoClvSIiCJsWrC/ix4WvkpaTjukNiawjIhGxx0+i bwRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eWHEtNYc; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id o72sor5188744lff.22.2019.11.12.04.40.31 for (Google Transport Security); Tue, 12 Nov 2019 04:40:33 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eWHEtNYc; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9Sqm3/Atz5RClYiYSLOTyjJ1qxSb0WxsX/5dNJbrB0s=; b=eWHEtNYcLlj0zJowG+spGVziZcmbcfArOdLM+CPHG/CH2DqS6YaVumSZebVJZ7ytUa iVqdfbWo7Sgb3sfI3WJWTU1wg0XTt4AouNa7rXCZRahL37uFggD4mrUNZDhew0QxsYR/ aZBR64htskemNVKTRtRK7udYfPqboxeAfjcRzkTCHDB9LSWG02Xxg3FyTnbKAUfo9Ag6 qmVjEiegZ0CisuAXB5xkZtk6OEA/mUeVaeNoBdXw2W38wj0wLhN50O9vxOkw0chMe0QR GMtemx2bJabrMtr3Cj/05q5CiwH1+/WsEBhWhcIELaPiWMg41Dx/LAlteO4SWzzMz7Q1 qPmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9Sqm3/Atz5RClYiYSLOTyjJ1qxSb0WxsX/5dNJbrB0s=; b=Wx5RxsWP9gEoOPbQt+blgYobhDqN7ZtNinsO3wfrJDgLfLUhJyUX0Yf5gHoTRPzq2T VqIyi8fZheQqv5MO31ziNBLLWPPCG3sVkRrPLnFdmf8Is40sfmTnOtbhtlVgqo0kwmVo EQ4cLoz/OTMDtyEHDd04lxc1Z+7zThx1glj3Dde9zeajqIcgYCYyAC9no9JsHG0ZWtpm LzvEZ7BT9pKmMuDXtd9C0seAN7/XcqlYA3Y/1oEvaCNawESp87wPBx6OzUHvyMJTt705 PsZImZUiUb/Fplzn5ZtcZ39wguyV/TjMZKui+oORUy/jio/rzcOeZen7MhKpa0Wj7Atp bFtA== X-Gm-Message-State: APjAAAWUna0df5r4kBUOZ3mbDSnqrUG/sS61G4WZgomuUPDIn51OyCYG DhIgCs+EJiT6BabDMQukQukAdwz7 X-Google-Smtp-Source: APXvYqwzEDPfwldBJhdBgC0pcUdsBDZ5Sg3IMXMrmP1OC5WRnUap6oE9INtgqyGc/0FBimeDtVZJ9w== X-Received: by 2002:ac2:5395:: with SMTP id g21mr561053lfh.50.1573562431424; Tue, 12 Nov 2019 04:40:31 -0800 (PST) Return-Path: Received: from uffe-XPS-13-9360.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id z19sm8375096ljk.66.2019.11.12.04.40.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2019 04:40:30 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Douglas Anderson , Matthias Kaehlcke Cc: Kalle Valo , Tony Lindgren , Wen Gong , Erik Stromdahl , Eyal Reizer , linux-wireless@vger.kernel.org Subject: [PATCH v3 2/3] mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() Date: Tue, 12 Nov 2019 13:40:20 +0100 Message-Id: <20191112124021.8718-3-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191112124021.8718-1-ulf.hansson@linaro.org> References: <20191112124021.8718-1-ulf.hansson@linaro.org> Upfront in mmc_rescan() we use the host->rescan_entered flag, to allow scanning only once for non-removable cards. Therefore, it's also not possible that we can have a corresponding card bus attached (host->bus_ops is NULL), when we are scanning non-removable cards. For this reason, let' drop the check for mmc_card_is_removable() as it's redundant. Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) -- 2.17.1 diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 221127324709..6f8342702c73 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2297,11 +2297,8 @@ void mmc_rescan(struct work_struct *work) mmc_bus_get(host); - /* - * if there is a _removable_ card registered, check whether it is - * still present - */ - if (host->bus_ops && !host->bus_dead && mmc_card_is_removable(host)) + /* Verify a registered card to be functional, else remove it. */ + if (host->bus_ops && !host->bus_dead) host->bus_ops->detect(host); host->detect_change = 0; From patchwork Tue Nov 12 12:40:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179185 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp8058597ilf; Tue, 12 Nov 2019 04:40:33 -0800 (PST) X-Received: by 2002:a2e:5c09:: with SMTP id q9mr19390489ljb.22.1573562433109; Tue, 12 Nov 2019 04:40:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573562433; cv=none; d=google.com; s=arc-20160816; b=0sNWPZkmyvWJnnlOdKR9rwFzeShEKVhdVAxjvUd9eBkZV3lJc69lhiZW3R3RtOFPlZ 6ruZNyZQt5cBsasAtP7rZpGKaSYlzaEnVdWqnfVVlPEzABuyojrsQVSh+XGCDRTYWWTM /LGyFnGIPVuP1YHfgmmM7zamYGMPohGfmIWK1zzYxUUolXNfr9R19XSwBJzl/FR3/Njn SKuiDm+loH1k177aCYVyxafeA280eOnypCAYhMx5EpKaMQ3y8WzZ+LgNXihVKpwTN4kC sMpfb0JCOwviRWVVe+wACwPgoi+gzTHmaRbKvU514Pf6nT8ZM9+MhE/X2RawooaNo+BZ f7xA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=VYIHY64Ig6hMKas5CfEIAmktuNgjbKEtyRGq8tTo16M=; b=BCzF4yLTpyQ484evIiWNBVLjOWd1MIzLjMK1WDcjTdSbIGoUaxrs5E2qUkjck4fduu eQiRHaoHTNYbdElejMqznODbbdHsysVwtdVCldQItu6nkKrkZ4EXDrb+2DHqUHA8eWmU cMX/1bmrLBUVemu0pcNfXzXci/EW/IVQuYVgSR71nUTD1W/cVY7/shZ1FP/5jSHhU2VY ux9IwLpgCHEdjmYe7mKeXjRzXHpwLo1waNIgWzhmhqJ8Kh35MEwvYxXKdgINWzkKBql/ 80c08/EZhapAgx+Iu1wMLFkkS5g5C1sp4jAnrYJ+T7Zh7hVhEnY4Fkgh0hIi8GW2j+62 3FKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aMrH3Jlv; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id a26sor10592625ljk.7.2019.11.12.04.40.32 for (Google Transport Security); Tue, 12 Nov 2019 04:40:33 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aMrH3Jlv; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VYIHY64Ig6hMKas5CfEIAmktuNgjbKEtyRGq8tTo16M=; b=aMrH3JlvfQFUbEz0UlQFVtwnt/lyMDpRuRM2OClIiWMID0mbPC7n+/hAVDdw4higmm QWe+1bYEU4Q2z7A2bIKdt5ZuF4o8qiYv1tkL1LP2BoDMjRk5E66nr9J4AUf04jEzmt4I bI6v8wAz/vgPwpZ5HUftcchHbgU4niROZW3QH4rtTi1/nUd+drXYVFJF9zTJ/lCa4shQ itUafgd5XCubbbFeIdukgApht9j4eqxAT/Qum3ixjnlSMCl/0mezP3nxtxYBPYuZAYLZ 7i7/NWoMYFbLqD6RCnWWBeQGsVSdTAlcj3EFfKZM5IxmQA/ScBntUxCP95GW4878MAYb A7ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VYIHY64Ig6hMKas5CfEIAmktuNgjbKEtyRGq8tTo16M=; b=apkl61YX4Csdoszrd3tUzUL1itYo3bWT9jSdUaZ8YaXNTygEBZlFtej+d4SGboqi2W HDF6TBwfV3SpvRqOwMFWUssi/sRU1FzmrI3KEGNpKHpEmyAXNyTvXLrK8KUI7VG9TxhZ d6jLw4vPY06AvS6/HVY3v/ScIKp1VjtNfMj1KaWThsNXLOq2QqyR4dT3DtBD53l4XDaW /ZsEP8RINZ6s8Y+xR6zIyGwDkf0+m+wSbkR22/tC59dph5ItHKL4uryGOze4dPkF6vCV QCzCZxajj6YxsVdx4bkyN7vYED7XsVPapV7okpzz7OUaXnUAn/BurpruIX5wSbOaNnIS fIww== X-Gm-Message-State: APjAAAW1xMied8usg2zYTkvvlUvFfCoUk8RWd8JRGXLACrCIVhM5VrcK KzskPBVPBkvsPcAAkom+oFAoncd8 X-Google-Smtp-Source: APXvYqzoUipiI2KkVe9Qz1ndQr2QucogrG5ac6Irt0iozB5VCIRCCN8QE3tN54Hxvo7ukpV1GvFZRw== X-Received: by 2002:a2e:558:: with SMTP id 85mr20280094ljf.67.1573562432644; Tue, 12 Nov 2019 04:40:32 -0800 (PST) Return-Path: Received: from uffe-XPS-13-9360.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id z19sm8375096ljk.66.2019.11.12.04.40.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2019 04:40:32 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Douglas Anderson , Matthias Kaehlcke Cc: Kalle Valo , Tony Lindgren , Wen Gong , Erik Stromdahl , Eyal Reizer , linux-wireless@vger.kernel.org Subject: [PATCH v3 3/3] mmc: core: Re-work HW reset for SDIO cards Date: Tue, 12 Nov 2019 13:40:21 +0100 Message-Id: <20191112124021.8718-4-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191112124021.8718-1-ulf.hansson@linaro.org> References: <20191112124021.8718-1-ulf.hansson@linaro.org> It have turned out that it's not a good idea to unconditionally do a power cycle and then to re-initialize the SDIO card, as currently done through mmc_hw_reset() -> mmc_sdio_hw_reset(). This because there may be multiple SDIO func drivers probed, who also shares the same SDIO card. To address these scenarios, one may be tempted to use a notification mechanism, as to allow the core to inform each of the probed func drivers, about an ongoing HW reset. However, supporting such an operation from the func driver point of view, may not be entirely trivial. Therefore, let's use a more simplistic approach to solve the problem, by instead forcing the card to be removed and re-detected, via scheduling a rescan-work. In this way, we can rely on existing infrastructure, as the func driver's ->remove() and ->probe() callbacks, becomes invoked to deal with the cleanup and the re-initialization. This solution may be considered as rather heavy, especially if a func driver doesn't share its card with other func drivers. To address this, let's keep the current immediate HW reset option as well, but run it only when there is one func driver probed for the card. Finally, to allow the caller of mmc_hw_reset(), to understand if the reset is being asynchronously managed from a scheduled work, it returns 1 (propagated from mmc_sdio_hw_reset()). If the HW reset is executed successfully and synchronously it returns 0, which maintains the existing behaviour. Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 5 ++--- drivers/mmc/core/core.h | 2 ++ drivers/mmc/core/sdio.c | 28 +++++++++++++++++++++++++++- drivers/mmc/core/sdio_bus.c | 9 ++++++++- include/linux/mmc/card.h | 1 + 5 files changed, 40 insertions(+), 5 deletions(-) -- 2.17.1 diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 6f8342702c73..abf8f5eb0a1c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1469,8 +1469,7 @@ void mmc_detach_bus(struct mmc_host *host) mmc_bus_put(host); } -static void _mmc_detect_change(struct mmc_host *host, unsigned long delay, - bool cd_irq) +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq) { /* * If the device is configured as wakeup, we prevent a new sleep for @@ -2129,7 +2128,7 @@ int mmc_hw_reset(struct mmc_host *host) ret = host->bus_ops->hw_reset(host); mmc_bus_put(host); - if (ret) + if (ret < 0) pr_warn("%s: tried to HW reset card, got error %d\n", mmc_hostname(host), ret); diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 328c78dbee66..575ac0257af2 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -70,6 +70,8 @@ void mmc_rescan(struct work_struct *work); void mmc_start_host(struct mmc_host *host); void mmc_stop_host(struct mmc_host *host); +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, + bool cd_irq); int _mmc_detect_card_removed(struct mmc_host *host); int mmc_detect_card_removed(struct mmc_host *host); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 26cabd53ddc5..ebb387aa5158 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -1048,9 +1048,35 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) return ret; } +/* + * SDIO HW reset + * + * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW + * reset was asynchronously scheduled, else a negative error code. + */ static int mmc_sdio_hw_reset(struct mmc_host *host) { - mmc_power_cycle(host, host->card->ocr); + struct mmc_card *card = host->card; + + /* + * In case the card is shared among multiple func drivers, reset the + * card through a rescan work. In this way it will be removed and + * re-detected, thus all func drivers becomes informed about it. + */ + if (atomic_read(&card->sdio_funcs_probed) > 1) { + if (mmc_card_removed(card)) + return 1; + host->rescan_entered = 0; + mmc_card_set_removed(card); + _mmc_detect_change(host, 0, false); + return 1; + } + + /* + * A single func driver has been probed, then let's skip the heavy + * hotplug dance above and execute the reset immediately. + */ + mmc_power_cycle(host, card->ocr); return mmc_sdio_reinit_card(host); } diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 2963e6542958..3cc928282af7 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -138,6 +138,8 @@ static int sdio_bus_probe(struct device *dev) if (ret) return ret; + atomic_inc(&func->card->sdio_funcs_probed); + /* Unbound SDIO functions are always suspended. * During probe, the function is set active and the usage count * is incremented. If the driver supports runtime PM, @@ -153,7 +155,10 @@ static int sdio_bus_probe(struct device *dev) /* Set the default block size so the driver is sure it's something * sensible. */ sdio_claim_host(func); - ret = sdio_set_block_size(func, 0); + if (mmc_card_removed(func->card)) + ret = -ENOMEDIUM; + else + ret = sdio_set_block_size(func, 0); sdio_release_host(func); if (ret) goto disable_runtimepm; @@ -165,6 +170,7 @@ static int sdio_bus_probe(struct device *dev) return 0; disable_runtimepm: + atomic_dec(&func->card->sdio_funcs_probed); if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) pm_runtime_put_noidle(dev); dev_pm_domain_detach(dev, false); @@ -181,6 +187,7 @@ static int sdio_bus_remove(struct device *dev) pm_runtime_get_sync(dev); drv->remove(func); + atomic_dec(&func->card->sdio_funcs_probed); if (func->irq_handler) { pr_warn("WARNING: driver %s did not remove its interrupt handler!\n", diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 9b6336ad3266..e459b38ef33c 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -291,6 +291,7 @@ struct mmc_card { struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ unsigned int sdio_funcs; /* number of SDIO functions */ + atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ struct sdio_cccr cccr; /* common card info */ struct sdio_cis cis; /* common tuple info */ struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */