Merge master.kernel.org:/home/rmk/linux-2.6-mmc
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0a117c6..ceae379 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1079,13 +1079,17 @@
/**
* mmc_detect_change - process change of state on a MMC socket
* @host: host which changed state.
+ * @delay: optional delay to wait before detection (jiffies)
*
* All we know is that card(s) have been inserted or removed
* from the socket(s). We don't know which socket or cards.
*/
-void mmc_detect_change(struct mmc_host *host)
+void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
- schedule_work(&host->detect);
+ if (delay)
+ schedule_delayed_work(&host->detect, delay);
+ else
+ schedule_work(&host->detect);
}
EXPORT_SYMBOL(mmc_detect_change);
@@ -1189,7 +1193,7 @@
ret = mmc_add_host_sysfs(host);
if (ret == 0) {
mmc_power_off(host);
- mmc_detect_change(host);
+ mmc_detect_change(host, 0);
}
return ret;
@@ -1259,7 +1263,7 @@
*/
int mmc_resume_host(struct mmc_host *host)
{
- mmc_detect_change(host);
+ mmc_detect_change(host, 0);
return 0;
}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 716c4ef..91c7484 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -442,7 +442,7 @@
status = host->plat->status(mmc_dev(host->mmc));
if (status ^ host->oldstat)
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
host->oldstat = status;
mod_timer(&host->timer, jiffies + HZ);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index e99a53b..b53af57 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -423,7 +423,9 @@
static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
{
- mmc_detect_change(devid);
+ struct pxamci_host *host = mmc_priv(devid);
+
+ mmc_detect_change(devid, host->pdata->detect_delay);
return IRQ_HANDLED;
}
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index dec01d3..a62c86f 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1122,7 +1122,7 @@
DBG("Executing card detection\n");
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
}
/*
@@ -1198,7 +1198,7 @@
*/
spin_unlock(&host->lock);
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
}
else
spin_unlock(&host->lock);
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
index 9718063..88c17dd 100644
--- a/include/asm-arm/arch-pxa/mmc.h
+++ b/include/asm-arm/arch-pxa/mmc.h
@@ -9,6 +9,7 @@
struct pxamci_platform_data {
unsigned int ocr_mask; /* available voltages */
+ unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */
int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
int (*get_ro)(struct device *);
void (*setpower)(struct device *, unsigned int);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6014160..c1f021e 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -109,6 +109,8 @@
struct mmc_card *card_selected; /* the selected MMC card */
struct work_struct detect;
+
+ unsigned long private[0] ____cacheline_aligned;
};
extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
@@ -116,14 +118,18 @@
extern void mmc_remove_host(struct mmc_host *);
extern void mmc_free_host(struct mmc_host *);
-#define mmc_priv(x) ((void *)((x) + 1))
+static inline void *mmc_priv(struct mmc_host *host)
+{
+ return (void *)host->private;
+}
+
#define mmc_dev(x) ((x)->dev)
#define mmc_hostname(x) ((x)->class_dev.class_id)
extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
extern int mmc_resume_host(struct mmc_host *);
-extern void mmc_detect_change(struct mmc_host *);
+extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
#endif