Initial INC MR3 commit with EVO/BRAVO included and majority of the compile warnings ...
/drivers/mmc/core/core.c
blob:405686771a5b1484f97f0715c1c0c112c6a51ed1 -> blob:c38c2842f30f402e6ac1943e8c2a9fc3398400c6
--- drivers/mmc/core/core.c
+++ drivers/mmc/core/core.c
@@ -184,6 +184,10 @@ static void mmc_wait_done(struct mmc_req
complete(mrq->done_data);
}
+struct msmsdcc_host;
+void msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq);
+void msmsdcc_stop_data(struct msmsdcc_host *host);
+
/**
* mmc_wait_for_req - start a request and wait for completion
* @host: MMC host to start command
@@ -195,6 +199,10 @@ static void mmc_wait_done(struct mmc_req
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
+#ifdef CONFIG_WIMAX
+ int ret = 0;
+#endif
+
DECLARE_COMPLETION_ONSTACK(complete);
mrq->done_data = &complete;
@@ -202,7 +210,20 @@ void mmc_wait_for_req(struct mmc_host *h
mmc_start_request(host, mrq);
+#ifdef CONFIG_WIMAX
+ ret = wait_for_completion_timeout(&complete, msecs_to_jiffies(5000));
+ if (ret <= 0) {
+ struct msmsdcc_host *msm_host = mmc_priv(host);
+ printk("[ERR] %s: %s wait_for_completion_timeout!\n", __func__, mmc_hostname(host));
+
+ msmsdcc_stop_data(msm_host);
+
+ mrq->cmd->error = -ETIMEDOUT;
+ msmsdcc_request_end(msm_host, mrq);
+ }
+#else
wait_for_completion(&complete);
+#endif
}
EXPORT_SYMBOL(mmc_wait_for_req);
@@ -424,6 +445,17 @@ static int mmc_host_do_disable(struct mm
int mmc_host_disable(struct mmc_host *host)
{
int err;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ if (host->rescan_disable) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ return;
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
if (!(host->caps & MMC_CAP_DISABLE))
return 0;
@@ -1082,6 +1114,7 @@ void mmc_remove_sd_card(struct work_stru
mmc_release_host(host);
}
mmc_bus_put(host);
+ wake_unlock(&mmc_delayed_work_wake_lock);
printk(KERN_INFO "%s: %s exit\n", mmc_hostname(host),
__func__);
}
@@ -1330,18 +1363,6 @@ int mmc_suspend_host(struct mmc_host *ho
if (host->bus_ops && !host->bus_dead) {
if (host->bus_ops->suspend)
err = host->bus_ops->suspend(host);
- if (err == -ENOSYS || !host->bus_ops->resume) {
- /*
- * We simply "remove" the card in this case.
- * It will be redetected on resume.
- */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
- mmc_claim_host(host);
- mmc_detach_bus(host);
- mmc_release_host(host);
- err = 0;
- }
}
mmc_bus_put(host);
@@ -1377,28 +1398,60 @@ int mmc_resume_host(struct mmc_host *hos
printk(KERN_WARNING "%s: error %d during resume "
"(card was removed?)\n",
mmc_hostname(host), err);
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
- mmc_claim_host(host);
- mmc_detach_bus(host);
- mmc_release_host(host);
- /* no need to bother upper layers */
err = 0;
}
}
mmc_bus_put(host);
- /*
- * We add a slight delay here so that resume can progress
- * in parallel.
- */
- mmc_detect_change(host, 1);
-
return err;
}
-
EXPORT_SYMBOL(mmc_resume_host);
+/* Do the card removal on suspend if card is assumed removeable
+ * Do that in pm notifier while userspace isn't yet frozen, so we will be able
+ to sync the card.
+*/
+int mmc_pm_notify(struct notifier_block *notify_block,
+ unsigned long mode, void *unused)
+{
+ struct mmc_host *host = container_of(
+ notify_block, struct mmc_host, pm_notify);
+ unsigned long flags;
+
+
+ switch (mode) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->rescan_disable = 1;
+ spin_unlock_irqrestore(&host->lock, flags);
+ cancel_delayed_work_sync(&host->detect);
+
+ if (!host->bus_ops || host->bus_ops->suspend)
+ break;
+
+ mmc_claim_host(host);
+
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+
+ mmc_detach_bus(host);
+ mmc_release_host(host);
+ break;
+
+ case PM_POST_SUSPEND:
+ case PM_POST_HIBERNATION:
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->rescan_disable = 0;
+ spin_unlock_irqrestore(&host->lock, flags);
+ mmc_detect_change(host, 0);
+
+ }
+
+ return 0;
+}
#endif
#ifdef CONFIG_MMC_EMBEDDED_SDIO