From 220adb0416225abe4bdec52ab0e5016aadc963a6 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 May 2016 07:50:35 +0000 Subject: [PATCH] Make sdhci(4) work after suspend/resume for chipsets that require the frequency quirk. This makes it work on eg ThinkPad T420. Without it, after resume one can see this: mmc0: ACMD42 failed, RESULT: 4 mmcsd0: Error indicated: 1 Timeout mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000010 sdhci_pci0-slot0: Argument: 0x00000200 | Trn mode: 0x00000037 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000001 sdhci_pci0-slot0: Argument: 0x00000040 | Trn mode: 0x00000013 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 autofs_flush: /net flushed sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb autofs_flush: /media flushed sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== Afterwards all operations on /dev/mmcsd0 fail with EIO. Reviewed by: jhb@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D6265 --- sys/dev/sdhci/sdhci_pci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/dev/sdhci/sdhci_pci.c b/sys/dev/sdhci/sdhci_pci.c index 3ed43ab95f0d..1ce4e9d3d273 100644 --- a/sys/dev/sdhci/sdhci_pci.c +++ b/sys/dev/sdhci/sdhci_pci.c @@ -412,11 +412,16 @@ static int sdhci_pci_resume(device_t dev) { struct sdhci_pci_softc *sc = device_get_softc(dev); - int i; + int i, err; for (i = 0; i < sc->num_slots; i++) sdhci_generic_resume(&sc->slots[i]); - return (bus_generic_resume(dev)); + err = bus_generic_resume(dev); + if (err) + return (err); + if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY) + sdhci_lower_frequency(dev); + return (0); } static void