From 1e72859e3ae16346d4007024b20d2d4ef387dcc3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 16 Apr 2008 19:13:13 +0200 Subject: sdhci: handle hot-remove Gracefully handle when the device is suddenly removed. Do a test read and avoid any further access if that read returns -1. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci-pci.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/mmc/host/sdhci-pci.c') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5dcb4958e47..8554466e0f4 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -47,7 +47,7 @@ struct sdhci_pci_fixes { int (*probe)(struct sdhci_pci_chip*); int (*probe_slot)(struct sdhci_pci_slot*); - void (*remove_slot)(struct sdhci_pci_slot*); + void (*remove_slot)(struct sdhci_pci_slot*, int); int (*suspend)(struct sdhci_pci_chip*, pm_message_t); @@ -209,8 +209,11 @@ static int jmicron_probe_slot(struct sdhci_pci_slot *slot) return 0; } -static void jmicron_remove_slot(struct sdhci_pci_slot *slot) +static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) { + if (dead) + return; + if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) jmicron_enable_mmc(slot->host, 0); } @@ -540,7 +543,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( remove: if (chip->fixes && chip->fixes->remove_slot) - chip->fixes->remove_slot(slot); + chip->fixes->remove_slot(slot, 0); unmap: iounmap(host->ioaddr); @@ -554,10 +557,18 @@ release: static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) { - sdhci_remove_host(slot->host); + int dead; + u32 scratch; + + dead = 0; + scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); + if (scratch == (u32)-1) + dead = 1; + + sdhci_remove_host(slot->host, dead); if (slot->chip->fixes && slot->chip->fixes->remove_slot) - slot->chip->fixes->remove_slot(slot); + slot->chip->fixes->remove_slot(slot, dead); pci_release_region(slot->chip->pdev, slot->pci_bar); -- cgit v1.2.3