Re: [PATCH] mmc: sdio: reset card during power_restore

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8 June 2011 10:33, Ohad Ben-Cohen <ohad@xxxxxxxxxx> wrote:
> Sounds like you didn't power the card off then in the driver after probe ?
>
> Can you show the diff with which you did this experiment ?

Attached. This is on top of your fix for correct driver deinit during suspend.

Test case is:
1. boot, load libertas driver
2. suspend in a way that libertas returns -ENOSYS to power down card
(this is the default)
3. resume
4. MMC layer powers up card to identify it, then powers it down, then
fails to power it up for libertas probe

If I add the reset (shown commented-out in the patch), it matches the
behaviour of other known-good codepaths and also solves the problem.

Output logs are:
bash-4.1# insmod /media/4E11-1D7C/libertas_sdio.ko
[   53.847863] libertas_sdio: Libertas SDIO driver
[   53.853104] libertas_sdio: Copyright Pierre Ossman
[   53.858040] mmc_power_restore_host mmc1
[   54.809019] libertas_sdio mmc1:0001:1: (unregistered net_device):
00:17:c4:a7:50:57, fw 9.70.3p36, cap 0x000003a3
[   54.825485] libertas_sdio mmc1:0001:1: wlan0: Marvell WLAN 802.11 adapter
bash-4.1# [   54.920650] udev[992]: renamed network interface wlan0 to eth0
[   54.978168] ieee80211 phy0: assoc: bss   (null) not in scan results
[   56.295225] ieee80211 phy0: assoc: bss   (null) not in scan results
[   56.337101] cfg80211: Calling CRDA for country: EU
bash-4.1# echo mem > /sys/power/state
[   65.393797] PM: Syncing filesystems ...
[   65.672372] done.
[   65.803121] Freezing user space processes ... (elapsed 0.01 seconds) done.
[   65.823048] Freezing remaining freezable tasks ... (elapsed 0.01
seconds) done.
[   65.884808] i8042 kbd 00:04: wake-up capability enabled by ACPI
[   65.891251] i8042 aux 00:03: wake-up capability disabled by ACPI
[   65.897820] ehci_hcd 0000:00:10.4: PCI INT D disabled
[   65.903294] uhci_hcd 0000:00:10.2: PCI INT C disabled
[   65.908900] uhci_hcd 0000:00:10.1: PCI INT B disabled
[   65.914431] libertas_sdio mmc1:0001:1: mmc1:0001:1: suspend: PM flags = 0x3
[   65.922077] uhci_hcd 0000:00:10.0: PCI INT A disabled
[   65.927578] viafb 0000:00:01.0: PCI INT A disabled
[   65.932646] libertas_sdio mmc1:0001:1: Suspend without wake params
-- powering down card
[   65.944166] cfg80211: Calling CRDA to update world regulatory domain
[   66.010534] mmc1: card 0001 removed
[   66.014310] sdhci-pci 0000:00:0c.0: PCI INT A disabled
[   66.030103] PM: suspend of devices complete after 186.534 msecs
[   66.110284] PM: late suspend of devices complete after 74.153 msecs
[   66.116751] ACPI: Preparing to enter system sleep state S3
[   66.122976] PM: Saving platform NVS memory
+r[   66.122976] ACPI: Low-level resume complete
[   66.122976] PM: Restoring platform NVS memory
[   66.122976] ACPI: Waking up from system sleep state S3
[   66.150047] uhci_hcd 0000:00:10.0: BAR 4: set to [io
0x8000-0x801f] (PCI address [0x8000-0x801f])
[   66.170036] uhci_hcd 0000:00:10.1: BAR 4: set to [io
0x8020-0x803f] (PCI address [0x8020-0x803f])
[   66.190035] uhci_hcd 0000:00:10.2: BAR 4: set to [io
0x8040-0x805f] (PCI address [0x8040-0x805f])
[   66.210034] ehci_hcd 0000:00:10.4: BAR 0: set to [mem
0x80003000-0x800030ff] (PCI address [0x80003000-0x800030ff])
[   66.220917] PM: early resume of devices complete after 87.797 msecs
[   66.227558] viafb 0000:00:01.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[   66.234561] sdhci-pci 0000:00:0c.0: PCI INT A -> GSI 22 (level,
low) -> IRQ 22
[   66.241931] uhci_hcd 0000:00:10.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
[   66.249168] usb usb2: root hub lost power or was reset
[   66.260047] uhci_hcd 0000:00:10.1: PCI INT B -> GSI 22 (level, low) -> IRQ 22
[   66.260077] usb usb3: root hub lost power or was reset
[   66.260116] uhci_hcd 0000:00:10.2: PCI INT C -> GSI 21 (level, low) -> IRQ 21
[   66.260145] usb usb4: root hub lost power or was reset
[   66.260179] ehci_hcd 0000:00:10.4: PCI INT D -> GSI 23 (level, low) -> IRQ 23
[   66.260761] i8042 kbd 00:04: wake-up capability disabled by ACPI
[   66.560225] PM: resume of devices complete after 332.791 msecs
[   66.580429] Restarting tasks ... done.
[   66.650427] mmc0: mmc_rescan_try_freq: trying to init card at 400000 Hz
bash-4.1# [   66.690461] cfg80211: World regulatory domain updated:
[   66.695701] cfg80211:     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)
[   66.733049] cfg80211:     (2402000 KHz - 2472000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   66.751195] cfg80211:     (2457000 KHz - 2482000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[   66.759333] cfg80211:     (2474000 KHz - 2494000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[   66.795426] mmc0: mmc_rescan_try_freq: trying to init card at 300000 Hz
[   66.808884] cfg80211:     (5170000 KHz - 5250000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   66.830830] cfg80211:     (5735000 KHz - 5835000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   66.865778] cfg80211: Calling CRDA to update world regulatory domain
[   66.905733] cfg80211: World regulatory domain updated:
[   66.917952] mmc0: mmc_rescan_try_freq: trying to init card at 200000 Hz
[   66.968065] cfg80211:     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)
[   66.985155] cfg80211:     (2402000 KHz - 2472000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   67.015441] cfg80211:     (2457000 KHz - 2482000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[   67.045234] mmc0: mmc_rescan_try_freq: trying to init card at 187500 Hz
[   67.053616] cfg80211:     (2474000 KHz - 2494000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[   67.122604] cfg80211:     (5170000 KHz - 5250000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   67.151879] mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz
[   67.189830] cfg80211:     (5735000 KHz - 5835000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[   67.296211] mmc1: new SDIO card at address 0001
[   67.337105] mmc_power_save_host mmc1
[   67.356088] mmc_power_restore_host mmc1
[   67.471529] CMD5 reset returned -110
[   67.477144] libertas_sdio: probe of mmc1:0001:1 failed with error -16
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 68091dd..92405e2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1662,7 +1662,7 @@ void mmc_stop_host(struct mmc_host *host)
 int mmc_power_save_host(struct mmc_host *host)
 {
 	int ret = 0;
-
+printk("mmc_power_save_host %s\n", mmc_hostname(host));
 	mmc_bus_get(host);
 
 	if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
@@ -1685,6 +1685,7 @@ int mmc_power_restore_host(struct mmc_host *host)
 {
 	int ret;
 
+printk("mmc_power_restore_host %s\n", mmc_hostname(host));
 	mmc_bus_get(host);
 
 	if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 8af3330..61ee53a 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -706,10 +706,27 @@ static int mmc_sdio_power_restore(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+
+	/*
+	 * Reset the card by performing the same steps that are taken by
+	 * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe
+	 */
+	//sdio_reset(host);
+	//mmc_go_idle(host);
+	//mmc_send_if_cond(host, host->ocr_avail);
+
+	ret = mmc_send_io_op_cond(host, 0, NULL);
+	if (ret) {
+		printk("CMD5 reset returned %d\n", ret);
+		//goto out;
+	}
+
 	ret = mmc_sdio_init_card(host, host->ocr, host->card,
 				mmc_card_keep_power(host));
 	if (!ret && host->sdio_irqs)
 		mmc_signal_sdio_irq(host);
+
+out:
 	mmc_release_host(host);
 
 	return ret;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 58d5436..ce3e2e2 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2488,7 +2488,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	} else
 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
 
-	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
+	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_POWER_OFF_CARD;
 
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
 		host->flags |= SDHCI_AUTO_CMD12;

[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux