msm: sdio: Use mmc_host data structure without accessing mmc_card

mmc_host data structure can be accessed from mmc_card data structure.
When there is a modem reset, the mmc_card structure is removed but
the mmc_host structure is never freed. Hence keep a reference to the
mmc_host data structure for use.

Change-Id: Iba7af3dd08a1fca772df15913f29484e341f9e38
CRs-fixed: 310148
Signed-off-by: Maya Erez <merez@codeaurora.org>
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
index 3acd4a4..1967a14 100644
--- a/arch/arm/mach-msm/sdio_al.c
+++ b/arch/arm/mach-msm/sdio_al.c
@@ -993,7 +993,7 @@
 	}
 	/* Prevent modem to go to sleep until we get the PROG_DONE on
 	   the dummy CMD52 */
-	msmsdcc_set_pwrsave(sdio_al_dev->card->host, 0);
+	msmsdcc_set_pwrsave(sdio_al_dev->host, 0);
 	/* Mark HOST_OK_TOSLEEP */
 	sdio_al_dev->is_ok_to_sleep = 1;
 	write_lpm_info(sdio_al_dev);
@@ -2359,10 +2359,9 @@
 			   u32 not_from_int, struct sdio_channel *ch)
 {
 	int ret = 0;
-	struct sdio_func *wk_func =
-		sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
+	struct sdio_func *wk_func = NULL;
 	unsigned long time_to_wait;
-	struct mmc_host *host = wk_func->card->host;
+	struct mmc_host *host = sdio_al_dev->host;
 
 	if (sdio_al_dev->is_err) {
 		SDIO_AL_ERR(__func__);
@@ -2398,7 +2397,7 @@
 	sdio_al_vote_for_sleep(sdio_al_dev, 0);
 
 	msmsdcc_lpm_disable(host);
-	msmsdcc_set_pwrsave(sdio_al_dev->card->host, 0);
+	msmsdcc_set_pwrsave(host, 0);
 	/* Poll the GPIO */
 	time_to_wait = jiffies + msecs_to_jiffies(1000);
 	while (time_before(jiffies, time_to_wait)) {
@@ -2416,6 +2415,13 @@
 				"get_mdm2ap_status() is 0\n");
 
 	/* Enable Wake up Function */
+	if (!sdio_al_dev->card ||
+	    !sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1]) {
+		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
+				": NULL card or wk_func\n");
+		return -ENODEV;
+	}
+	wk_func = sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
 	ret = sdio_al_enable_func_retry(wk_func, "wakeup func");
 	if (ret) {
 		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
@@ -2442,13 +2448,13 @@
 	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME "Finished Wake up sequence"
 			" for card %d", sdio_al_dev->host->index);
 
-	msmsdcc_set_pwrsave(sdio_al_dev->card->host, 1);
+	msmsdcc_set_pwrsave(host, 1);
 	pr_debug(MODULE_NAME ":Turn clock off\n");
 
 	return ret;
 error_exit:
 	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-	msmsdcc_set_pwrsave(sdio_al_dev->card->host, 1);
+	msmsdcc_set_pwrsave(host, 1);
 	WARN_ON(ret);
 	sdio_al_get_into_err_state(sdio_al_dev);
 	return ret;
@@ -2476,8 +2482,7 @@
 	pr_debug(MODULE_NAME ":start %s.\n", __func__);
 
 	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL sdio_al_dev"
-				" for card %d\n", func->card->host->index);
+		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL device");
 		return;
 	}
 
@@ -2527,18 +2532,13 @@
 	int i = 0;
 	int fn = 0;
 
-	if (card == NULL) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_al_setup: No Card detected\n");
+	if (sdio_al_verify_func1(sdio_al_dev, __func__))
 		return -ENODEV;
-	}
-
+	func1 = card->sdio_func[0];
 
 	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":sdio_al_setup for "
 			"card %d\n", sdio_al_dev->host->index);
 
-	func1 = card->sdio_func[0];
-
 	ret = sdio_al->pdata->config_mdm2ap_status(1);
 	if (ret) {
 		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME "Could not "
@@ -2560,13 +2560,13 @@
 
 	sdio_set_drvdata(func1, sdio_al_dev);
 	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":claim IRQ for card "
-			"%d\n",	card->host->index);
+			"%d\n",	sdio_al_dev->host->index);
 
 	ret = sdio_claim_irq(func1, sdio_func_irq);
 	if (ret) {
 		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to claim"
 				" IRQ for card %d\n",
-				card->host->index);
+				sdio_al_dev->host->index);
 		return ret;
 	}