linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Douglas Anderson <dianders@chromium.org>,
	Ulf Hansson <ulf.hansson@linaro.org>
Subject: [PATCH 5.4 05/80] mmc: core: Re-work HW reset for SDIO cards
Date: Thu, 19 Dec 2019 19:33:57 +0100	[thread overview]
Message-ID: <20191219183034.971092272@linuxfoundation.org> (raw)
In-Reply-To: <20191219183031.278083125@linuxfoundation.org>

From: Ulf Hansson <ulf.hansson@linaro.org>

commit 2ac55d5e5ec9ad0a07e194f0eaca865fe5aa3c40 upstream.

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 <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Cc: stable@vger.kernel.org # v5.4+
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 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(-)

--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1469,8 +1469,7 @@ void mmc_detach_bus(struct mmc_host *hos
 	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);
 
--- 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);
 
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1048,9 +1048,35 @@ static int mmc_sdio_runtime_resume(struc
 	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);
 }
 
--- 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
 	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
 	/* 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
 	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
 		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",
--- 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) */



  parent reply	other threads:[~2019-12-19 18:58 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-19 18:33 [PATCH 5.4 00/80] 5.4.6-stable review Greg Kroah-Hartman
2019-12-19 18:33 ` [PATCH 5.4 01/80] USB: Fix incorrect DMA allocations for local memory pool drivers Greg Kroah-Hartman
2019-12-19 18:33 ` [PATCH 5.4 02/80] mmc: block: Make card_busy_detect() a bit more generic Greg Kroah-Hartman
2019-12-19 18:33 ` [PATCH 5.4 03/80] mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response Greg Kroah-Hartman
2019-12-19 18:33 ` [PATCH 5.4 04/80] mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() Greg Kroah-Hartman
2019-12-19 18:33 ` Greg Kroah-Hartman [this message]
2019-12-19 18:33 ` [PATCH 5.4 06/80] PCI/switchtec: Read all 64 bits of part_event_bitmap Greg Kroah-Hartman
2019-12-19 18:33 ` [PATCH 5.4 07/80] PCI/PM: Always return devices to D0 when thawing Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 08/80] PCI: pciehp: Avoid returning prematurely from sysfs requests Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 09/80] PCI: Fix Intel ACS quirk UPDCR register address Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 10/80] PCI/MSI: Fix incorrect MSI-X masking on resume Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 11/80] PCI: Do not use bus number zero from EA capability Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 12/80] PCI: rcar: Fix missing MACCTLR register setting in initialization sequence Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 13/80] PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3 Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 14/80] PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 15/80] block: fix "check bi_size overflow before merge" Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 16/80] xtensa: use MEMBLOCK_ALLOC_ANYWHERE for KASAN shadow map Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 17/80] gfs2: Multi-block allocations in gfs2_page_mkwrite Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 18/80] gfs2: fix glock reference problem in gfs2_trans_remove_revoke Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 19/80] xtensa: fix TLB sanity checker Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 20/80] xtensa: fix syscall_set_return_value Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 21/80] rpmsg: glink: Set tail pointer to 0 at end of FIFO Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 22/80] rpmsg: glink: Fix reuse intents memory leak issue Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 23/80] rpmsg: glink: Fix use after free in open_ack TIMEOUT case Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 24/80] rpmsg: glink: Put an extra reference during cleanup Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 25/80] rpmsg: glink: Fix rpmsg_register_device err handling Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 26/80] rpmsg: glink: Dont send pending rx_done during remove Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 27/80] rpmsg: glink: Free pending deferred work on remove Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 28/80] cifs: smbd: Return -EAGAIN when transport is reconnecting Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 29/80] cifs: smbd: Only queue work for error recovery on memory registration Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 30/80] cifs: smbd: Add messages on RDMA session destroy and reconnection Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 31/80] cifs: smbd: Return -EINVAL when the number of iovs exceeds SMBDIRECT_MAX_SGE Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 32/80] cifs: smbd: Return -ECONNABORTED when trasnport is not in connected state Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 33/80] cifs: Dont display RDMA transport on reconnect Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 34/80] CIFS: Respect O_SYNC and O_DIRECT flags during reconnect Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 35/80] CIFS: Close open handle after interrupted close Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 36/80] CIFS: Do not miss cancelled OPEN responses Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 37/80] CIFS: Fix NULL pointer dereference in mid callback Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 38/80] cifs: Fix retrieval of DFS referrals in cifs_mount() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 39/80] ARM: dts: s3c64xx: Fix init order of clock providers Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 40/80] ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 41/80] vfio/pci: call irq_bypass_unregister_producer() before freeing irq Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 42/80] dma-buf: Fix memory leak in sync_file_merge() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 43/80] drm/panfrost: Fix a race in panfrost_ioctl_madvise() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 44/80] drm/panfrost: Fix a BO leak in panfrost_ioctl_mmap_bo() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 45/80] drm/panfrost: Fix a race in panfrost_gem_free_object() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 46/80] drm/mgag200: Extract device type from flags Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 47/80] drm/mgag200: Store flags from PCI driver data in device structure Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 48/80] drm/mgag200: Add workaround for HW that does not support startadd Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 49/80] drm/mgag200: Flag all G200 SE A machines as broken wrt <startadd> Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 50/80] drm: meson: venc: cvbs: fix CVBS mode matching Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 51/80] dm mpath: remove harmful bio-based optimization Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 52/80] dm btree: increase rebalance threshold in __rebalance2() Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 53/80] dm clone metadata: Track exact changes per transaction Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 54/80] dm clone metadata: Use a two phase commit Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 55/80] dm clone: Flush destination device before committing metadata Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 56/80] dm thin metadata: Add support for a pre-commit callback Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 57/80] dm thin: Flush data device before committing metadata Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 58/80] scsi: ufs: Disable autohibern8 feature in Cadence UFS Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 59/80] scsi: iscsi: Fix a potential deadlock in the timeout handler Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 60/80] scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 61/80] scsi: qla2xxx: Initialize free_work before flushing it Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 62/80] scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 63/80] scsi: qla2xxx: Change discovery state before PLOGI Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 64/80] scsi: qla2xxx: Correctly retrieve and interpret active flash region Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 65/80] scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 66/80] drm/nouveau/kms/nv50-: Call outp_atomic_check_view() before handling PBN Greg Kroah-Hartman
2019-12-19 18:34 ` [PATCH 5.4 67/80] drm/nouveau/kms/nv50-: Store the bpc were using in nv50_head_atom Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 68/80] drm/nouveau/kms/nv50-: Limit MST BPC to 8 Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 69/80] drm/i915/fbc: Disable fbc by default on all glk+ Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 70/80] drm/radeon: fix r1xx/r2xx register checker for POT textures Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 71/80] drm/dp_mst: Correct the bug in drm_dp_update_payload_part1() Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 72/80] drm/amd/display: re-enable wait in pipelock, but add timeout Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 73/80] drm/amd/display: add default clocks if not able to fetch them Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 74/80] drm/amdgpu: initialize vm_inv_eng0_sem for gfxhub and mmhub Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 75/80] drm/amdgpu: invalidate mmhub semaphore workaround in gmc9/gmc10 Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 76/80] drm/amdgpu/gfx10: explicitly wait for cp idle after halt/unhalt Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 77/80] drm/amdgpu/gfx10: re-init clear state buffer after gpu reset Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 78/80] drm/i915/gvt: Fix cmd length check for MI_ATOMIC Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 79/80] drm/amdgpu: avoid using invalidate semaphore for picasso Greg Kroah-Hartman
2019-12-19 18:35 ` [PATCH 5.4 80/80] drm/amdgpu: add invalidate semaphore limit for SRIOV and picasso in gmc9 Greg Kroah-Hartman
2019-12-20  4:30 ` [PATCH 5.4 00/80] 5.4.6-stable review shuah
2019-12-20  6:29   ` Greg Kroah-Hartman
2019-12-20  7:22 ` Naresh Kamboju
2019-12-20  8:20   ` Greg Kroah-Hartman
2019-12-20 10:30 ` Jon Hunter
2019-12-20 13:50   ` Greg Kroah-Hartman
2019-12-20 18:50 ` Guenter Roeck
2019-12-20 21:21   ` Greg Kroah-Hartman
2019-12-21  9:36 ` Jeffrin Jose

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191219183034.971092272@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dianders@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).