From patchwork Sat Nov 9 10:30:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179016 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp4014789ilf; Sat, 9 Nov 2019 02:30:58 -0800 (PST) X-Received: by 2002:a2e:9981:: with SMTP id w1mr9550500lji.205.1573295458069; Sat, 09 Nov 2019 02:30:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573295458; cv=none; d=google.com; s=arc-20160816; b=GhQ+v/hKyjAU2g4TIXbW+2W0H5v0+9jNwo9c1xPSdpu8RPk2motF1FRhpQ3orX1XLx a8lzQwkS8bR1qk2Yx0jgCfWKehXa3cg2WLEogbqtGNjCRabO9o+OnTxR9zLaXZXiGya6 DO919rkc9P0xo9QZLgj/KHIPwa+8CBbsUFQWSFD9ynBp40wM74YJDjWbRBSz0BdLmHXV 7LmaQRWPFNH2u38llOKlkooRCzIQmyiz3WB2ewWn8fpwBWiIqM3Fq66Vfmv9lD9VG0uA MPY6+6h80bQxkinIrxXWPTIkBkquj9AY0eU+k6I8kvqGttLlw1mbVtoJB6rVfCr2/io6 FwTA== 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=EPWrQqTPprKbNvtZzwl7Za5KTqnwSV8dkxRhESPvVMk=; b=QpeCFxkOkP+s4qKGNgiijoDxRlh9jZSA+r6tTZMDoFD96wIob29M3Kfk/i6U8LIvr3 Xv9afnaEn6L7GA7GxHthjMlJ1oZN1Pg10eIEfL5vJGz9XxwFg4B/anf3FgYFsZDuZC5a VQxZZBQneyWr/x12P1OK8SYA2dkdBGUddLJgVKGYunBIRol36zuvxRy3FU8QuPnT+6H7 jya1nuA4DjHx0Am02ii4gwMUvl6HI0o8qn1aMLDDlgScHa6YFzFvf82NFGc2Y6NIFuyr aedYmDFynatVTqM6CHj438lTRsy1TVG4M+XOjHlVmDDMuojM/hlnO77s0onW1ayDo44o FXGQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RAqHiaQM; 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 r1sor5418103ljd.12.2019.11.09.02.30.57 for (Google Transport Security); Sat, 09 Nov 2019 02:30:58 -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=RAqHiaQM; 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=EPWrQqTPprKbNvtZzwl7Za5KTqnwSV8dkxRhESPvVMk=; b=RAqHiaQMFxA519DIisu77r0ZpVMnv8kweBZO7SMmcg6i0g742jVy3xPif0n3vdm34V MV009qQmF9+y1gGekHF/Qgg17CNOxjc1hkX1S3WA1m7Q62Tn0Hw6AKNQTlHUGHP/8DAO /MSNwgaIpWUi7noyAV0LXnTcJVxjqNQnOqvBHImU8mRLPsVz4idOT1mH96kNEgHCHWKO 9/LTrnXqtaiepxdnDkoUWXmlUy9lZwxp8MYN+pUbaIwtLmSFLKBz74VK3sBA2WiVChDs rojmiTtD/l8+1XGvEfzJiOeBrDvNdUE+/zAHY59tCi7vPZlaX7Sz9/hGj+a803Y0km2X 2W7Q== 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=EPWrQqTPprKbNvtZzwl7Za5KTqnwSV8dkxRhESPvVMk=; b=Nx8r5bm8IgszemLL79hHywr/r78cpJjB5HUrt7YptfGEYnuJG1VaCczlo/P8tlhKgh +1M0i3BI2fz1tkVg1zYs+YYySTqlkPDOsLw7rcyllqsldLN9MXLrIv2V9HEwe6nbqKX7 pm8E8NwIm4QY8e8Za01vKRYIl0sekobhrT1/ik49iZ1k2lBNc+vZ9ExWgaZCkoZSIpHX YxLn0bQsI4UvQFGQeiWyILy8s03PP4/JdaudCaj2z4OeBt2IHghyP1/+DHUS7ruEs89C Rm6wDFN9IlRl8Z3BRR8whC1k6kMD2ov6PIzhT95MbcpMiX7/2qdFU1H6rKBF8qwCRRVo mW2Q== X-Gm-Message-State: APjAAAW57ruRg+kqi2FP5wjYkkBYEEoARfGcB1oiqS4r74CYdU1Nb0FN 07idQkJ+6ou3r3wBvT7HXZ5G9i8h X-Google-Smtp-Source: APXvYqxMcNlet3RO6I64yAC6SNgkkocsxLQndYEuLIb2XeUMBXV3VvlCRMZuVWKcCw1fQBAgGNAsIA== X-Received: by 2002:a2e:2a42:: with SMTP id q63mr8791758ljq.180.1573295457543; Sat, 09 Nov 2019 02:30:57 -0800 (PST) Return-Path: Received: from localhost.localdomain (h-158-174-22-210.NA.cust.bahnhof.se. [158.174.22.210]) by smtp.gmail.com with ESMTPSA id z3sm343927lji.36.2019.11.09.02.30.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 Nov 2019 02:30:57 -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 v2 1/3] mwifiex: Re-work support for SDIO HW reset Date: Sat, 9 Nov 2019 11:30:44 +0100 Message-Id: <20191109103046.26445-2-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191109103046.26445-1-ulf.hansson@linaro.org> References: <20191109103046.26445-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. Signed-off-by: Ulf Hansson --- drivers/net/wireless/marvell/mwifiex/main.c | 6 +++- drivers/net/wireless/marvell/mwifiex/main.h | 1 + drivers/net/wireless/marvell/mwifiex/sdio.c | 33 ++++++++++++++------- 3 files changed, 28 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..dbdbdd6769a9 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -76,6 +76,7 @@ static int mwifiex_register(void *card, struct device *dev, *padapter = adapter; adapter->dev = dev; adapter->card = card; + adapter->is_adapter_up = false; /* Save interface specific operations in adapter */ memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops)); @@ -631,6 +632,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_adapter_up = true; goto done; err_add_intf: @@ -1469,6 +1471,7 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) mwifiex_deauthenticate(priv, NULL); mwifiex_uninit_sw(adapter); + adapter->is_adapter_up = false; if (adapter->if_ops.down_dev) adapter->if_ops.down_dev(adapter); @@ -1730,7 +1733,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter) if (!adapter) return 0; - mwifiex_uninit_sw(adapter); + if (adapter->is_adapter_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..7703d2e5d2e0 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_adapter_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..2417c94c29c0 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_adapter_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 Sat Nov 9 10:30:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179017 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp4014815ilf; Sat, 9 Nov 2019 02:30:59 -0800 (PST) X-Received: by 2002:a2e:8809:: with SMTP id x9mr9804737ljh.82.1573295459268; Sat, 09 Nov 2019 02:30:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573295459; cv=none; d=google.com; s=arc-20160816; b=s3um0U5H+2xbvTTCVLCNpt8iDEijcu2LKpyPR5K6avonAYI9dqr/7ICpUizT//GkLt UryzvYxjc7/WRlA9SQL+oiZsC716rgw9vqdVknbmClkVjLM2efM6EwSXKIWhimuH1nD8 Ndbp23OPf7LHeaZmZSf6RlGwFj9p3WZMYhMxFvGyVhBq4QhVBqAG2W24uhYiXx5fmjU5 rOXzkkH2RoelUVmN8SeCnY93X5VeVns9Ffl6x3diDKn5H7ZTNzms/2GJbkqqeV+Am/WU Q/3Y1hCjo8ZBqXo8wqy+ScDLGQeZyl3hkzIwJsc2VoFpU9+YJXXTVwGXe1WI3cEimtTd f7MA== 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=Irawu8SRoNtzmKfb3mCNZp3oXWFM6rn9ptozR56UkwA=; b=YBbkc3tkWmeSNjZ5dXPoOHaRXXG9KKi2673jnHy4F+VNhBGBT2dk7k8ujavCSf+1Sy W0uM0zHhqxb7+qFEH+abXAjjVMCJ2xwMZykXpfY5WxBnaaA+p0Hun6sZUQmTWMcSH3FA VdpunuBU7oIP0S4SEEUYIZlxqdowxatoLkmZXZlaKxszIplEoV9PzYsHosoU//x6Kvd6 0QdgS/YIBjzAvjQ3YD4GJFfFr1vk13U8vbJufC7cXbmjiWP9MLMszawG5xYxzz2tY4yZ +whowYOvz23eRkdekdH4XRTI/c4UYy0lGJsTL+tqTtapy2hIhv4MSfq4pupiJyQXwTgB 2V+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZFczlxVJ; 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 i26sor5398041ljj.20.2019.11.09.02.30.59 for (Google Transport Security); Sat, 09 Nov 2019 02:30:59 -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=ZFczlxVJ; 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=Irawu8SRoNtzmKfb3mCNZp3oXWFM6rn9ptozR56UkwA=; b=ZFczlxVJpHEkN6j+5EYvSNhGZMycMzimX6bbksHznbxmkE6ALM4OpnnZdIJ3gJlBYM 1rqArbEMRDznWCxXDoHRuoV5ui7IfChnVNy3fiuWgy4Wj6YYEZknpqJ9wqcZXcLRBDQp jWGaYpbwcgu7AQvC0Yv3OtvZ2/gCFvWRNdxqBLLFgpmzPGaGXGN6rJssKwAXyx27xLAw 7ysXH8byqmGHuIVhBJ8Altmvvbk5FMHSJw7OHwHsKUIRo9HyatT7nsYAHcFYGSPYc5Zp 8lwMBrZHWPuHJq+krl63Bmgouor7LRcz+W5cGNfsGCZzJZL8/BNIW7HUW/IygBeXjgxH ngow== 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=Irawu8SRoNtzmKfb3mCNZp3oXWFM6rn9ptozR56UkwA=; b=cS59vD0y8MweTS7WZSSSLK385jYEUKDjHbapvpYD+ItTY09h6zQI7ZgMCi+ynwstzx WYkc7XoIodxcjPpRi4owxxsSAuUkVjm7QKQJTdXlH3DZdGT7XLuuLYkagIg0kQDmoSdS r/thbzE7Ngd/TsEnHddKsR8gfwbyA8ExafZL4VfzoIJ/svk2R1XFVDRey6BANfUuoyAu RM96tuOskmDkE1SpqB0CUH3qZVbruIcDFm2v0QsgOfYeWL6dOXQcOGK19VWiehu8vmT/ 2oAPHABW6OT4T8lSVgN1ZpAJzpD7BfI0LSWLGwBzLt+PR95GlVU8wWcM+MEEIgXFbE8W uYhQ== X-Gm-Message-State: APjAAAWEwezKKo9hQYP8gX3lInSWnlBSOm1a0pUipwJEsiMubno3jjn/ ehNvsqepH42GSCtjqZsvJjmqSjup X-Google-Smtp-Source: APXvYqxIoztXOQ6EZI33BdfF0jjZWB8NBuswW97qLqIH/zyK5sFRmGHkxaqCaf1Q9H5zKjEZOviDaw== X-Received: by 2002:a2e:2a05:: with SMTP id q5mr9924181ljq.170.1573295458900; Sat, 09 Nov 2019 02:30:58 -0800 (PST) Return-Path: Received: from localhost.localdomain (h-158-174-22-210.NA.cust.bahnhof.se. [158.174.22.210]) by smtp.gmail.com with ESMTPSA id z3sm343927lji.36.2019.11.09.02.30.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 Nov 2019 02:30:58 -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 v2 2/3] mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() Date: Sat, 9 Nov 2019 11:30:45 +0100 Message-Id: <20191109103046.26445-3-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191109103046.26445-1-ulf.hansson@linaro.org> References: <20191109103046.26445-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 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 Sat Nov 9 10:30:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179018 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp4014835ilf; Sat, 9 Nov 2019 02:31:00 -0800 (PST) X-Received: by 2002:a19:10:: with SMTP id 16mr9768377lfa.100.1573295460855; Sat, 09 Nov 2019 02:31:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573295460; cv=none; d=google.com; s=arc-20160816; b=TLRPCqEHhhTZcJzcIX8XUCTPV4bZ44tZ7qhZ7ewmS0RHiC5hB2WvR15r8JpxrGrbq+ UIA/nX5nn2krbONjILEHxYm+gWEY4P25PVhEmVRnQwjLbk0Sny+FKyOAQFkxVJIviuCx /G9U1Wq3HfWowOr2M+vZLr80poiJc88XjgJG+c8u39WQtzanzBh5WZKuUp0CGAbXXPYv LxaHd+97zCfpQU6aiFcmZa5p6nOrkM0mAxXXK6J6H8GFrtR7G+my91YS67+em409uPin UYXhyywatJGQ9QnU+/9PWI67RsR3phhQ3jCmswTQRkEBYZe9gEueABHZIOXtujdz/wtR yUAA== 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=43TLBzD+brgRSav+FBPD6YlPA+X6uN9U0bQoOJqUWac=; b=q/kX5zVpMjd4Vd9gtsAr7og2HNOvzPmBg6itocLXWnJ4JZzbrL3L/RreC+/80VxZC1 3x6tlY23V6wyMS9XEqefgX0BhT4cCxQje1v4ntPZyN/3NEaAZwh3ECTCUDAKZRbarrzu amm1f4Tf3jXffE0PhxAUy0S6HObfAMXIc/AZo0PzvYuiNcmTC5c0JV9F4LoEnsCFGhbv /6V/vl+HOhbYzaHCPgC6EvLmhBFjw4NpYxczFtP+eB7OD6o5pWiIpOgpV9Y3SiIR3N0b TA7QmKeDwP42oG2L6pc8EOp1MYW1X+2e0OTyHMOSGFih8+fyJ0DGBNW/GKiSsD4kPUcF nXGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RxUww9sL; 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 a3sor5492468ljn.26.2019.11.09.02.31.00 for (Google Transport Security); Sat, 09 Nov 2019 02:31:00 -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=RxUww9sL; 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=43TLBzD+brgRSav+FBPD6YlPA+X6uN9U0bQoOJqUWac=; b=RxUww9sLiE2jv3n6iM+WDlCT7GBVNYvgjghW/cZfIc0BBUTgAYupb2eXtPWCG2FnIQ NOgqrlErw/xaTDL6CBD6zVKuZEa0dI4MB6ezt9XD4PlHRS0j1/m4u9QejzpdhSj79zWq AEpZYn+KklCAEMEgN3tzR/GCDQR26TvQBeeSSjduK/4gLIo0O0yi+sehqmU6IE0mz8yV Sn/kJebpVYfK4eYqtrFQfPiQjhnfZzcJ2MC/uMu7Zl6x+0HVhwxqankKVgukFKhfzzoq o+RdWYpgvErl2OMrNq02W+lSgkUSJ/7UdMWAFh9uDVRY222MZdw8ykib/P9lu4c/mMMv LeUw== 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=43TLBzD+brgRSav+FBPD6YlPA+X6uN9U0bQoOJqUWac=; b=Y+k2lLFSE44tuM/V8Bm5hZnsKTYFSbBD9uXClWQZWqsOnEY3rqiil7hRudBQ+bZgU5 ktNlDiQA6McX8IqpXDWq7+Z724f9hPeCYUiRUxtSPwy85kTe+XF4/emOOUjV19h/A5Tp P6p+j4RCXCqfvOV09mawaeSkdQOfYsPMqZFirnkKWhEl9/tqxO7Tv98mVylDAaD0C6XT DgTz0aKuu4zASEEqkvLWqH8YZrE0QkKklEPouSeiATzVrWLLn0wmEiEx1H/fQRl/PqEo mPv/tPyIb74FWBxudAPrOHTI09qlTQuM8+278T6KaZIavPBj6uYwCJBTVjkju20uC5V5 xe6g== X-Gm-Message-State: APjAAAX0JKQCixLwQ4dVB2bM+ZjlAkpwTAPjQtGMl6uuCbt8qCdmUztj OooVRC+C6FCrhG/KOBzWmL5kGYuB X-Google-Smtp-Source: APXvYqw57oSCDmLhEK/T+cTX47L5QIJWO6b9etZKfvoraSKwP/ZQ4FPlblc/SUqB0LOTdezhz3c0DA== X-Received: by 2002:a2e:9a0c:: with SMTP id o12mr10128391lji.141.1573295460431; Sat, 09 Nov 2019 02:31:00 -0800 (PST) Return-Path: Received: from localhost.localdomain (h-158-174-22-210.NA.cust.bahnhof.se. [158.174.22.210]) by smtp.gmail.com with ESMTPSA id z3sm343927lji.36.2019.11.09.02.30.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 Nov 2019 02:30:59 -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 v2 3/3] mmc: core: Re-work HW reset for SDIO cards Date: Sat, 9 Nov 2019 11:30:46 +0100 Message-Id: <20191109103046.26445-4-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191109103046.26445-1-ulf.hansson@linaro.org> References: <20191109103046.26445-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. 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 Reviewed-by: Douglas Anderson 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) */