mmc: msm_sdcc: print sdcc state when request timeout happens

Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 3de5f03..78b3338 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3349,6 +3349,63 @@
 };
 #endif
 
+void msmsdcc_print_regs(const char *name, void __iomem *base,
+			unsigned int no_of_regs)
+{
+	unsigned int i;
+
+	if (!base)
+		return;
+	pr_info("===== %s: Register Dumps @base=0x%x =====\n",
+		name, (u32)base);
+	for (i = 0; i < no_of_regs; i = i + 4) {
+		pr_info("Reg=0x%.2x: 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x.\n", i*4,
+				(u32)readl_relaxed(base + i*4),
+				(u32)readl_relaxed(base + ((i+1)*4)),
+				(u32)readl_relaxed(base + ((i+2)*4)),
+				(u32)readl_relaxed(base + ((i+3)*4)));
+	}
+}
+
+static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host)
+{
+	/* Dump current state of SDCC clocks, power and irq */
+	pr_info("%s: SDCC PWR is %s\n", mmc_hostname(host->mmc),
+			(host->pwr ? "ON" : "OFF"));
+	pr_info("%s: SDCC clks are %s, MCLK rate=%d\n",
+			mmc_hostname(host->mmc),
+			(host->clks_on ? "ON" : "OFF"),
+			(u32)clk_get_rate(host->clk));
+	pr_info("%s: SDCC irq is %s\n", mmc_hostname(host->mmc),
+		(host->sdcc_irq_disabled ? "disabled" : "enabled"));
+
+	/* Now dump SDCC registers. Don't print FIFO registers */
+	if (host->clks_on)
+		msmsdcc_print_regs("SDCC-CORE", host->base, 28);
+
+	if (host->curr.data) {
+		if (msmsdcc_check_dma_op_req(host->curr.data))
+			pr_info("%s: PIO mode\n", mmc_hostname(host->mmc));
+		else if (host->is_dma_mode)
+			pr_info("%s: ADM mode: busy=%d, chnl=%d, crci=%d\n",
+				mmc_hostname(host->mmc), host->dma.busy,
+				host->dma.channel, host->dma.crci);
+		else if (host->is_sps_mode)
+			pr_info("%s: SPS mode: busy=%d\n",
+				mmc_hostname(host->mmc), host->sps.busy);
+
+		pr_info("%s: xfer_size=%d, data_xfered=%d, xfer_remain=%d\n",
+			mmc_hostname(host->mmc), host->curr.xfer_size,
+			host->curr.data_xfered, host->curr.xfer_remain);
+		pr_info("%s: got_dataend=%d, prog_enable=%d,"
+			" wait_for_auto_prog_done=%d,"
+			" got_auto_prog_done=%d\n",
+			mmc_hostname(host->mmc), host->curr.got_dataend,
+			host->prog_enable, host->curr.wait_for_auto_prog_done,
+			host->curr.got_auto_prog_done);
+	}
+
+}
 static void msmsdcc_req_tout_timer_hdlr(unsigned long data)
 {
 	struct msmsdcc_host *host = (struct msmsdcc_host *)data;
@@ -3365,15 +3422,14 @@
 	mrq = host->curr.mrq;
 
 	if (mrq && mrq->cmd) {
-		pr_info("%s: %s CMD%d\n", mmc_hostname(host->mmc),
-				__func__, mrq->cmd->opcode);
+		pr_info("%s: CMD%d: Request timeout\n", mmc_hostname(host->mmc),
+				mrq->cmd->opcode);
+		msmsdcc_dump_sdcc_state(host);
+
 		if (!mrq->cmd->error)
 			mrq->cmd->error = -ETIMEDOUT;
-		if (host->dummy_52_needed)
-			host->dummy_52_needed = 0;
+		host->dummy_52_needed = 0;
 		if (host->curr.data) {
-			pr_info("%s: %s Request timeout\n",
-					mmc_hostname(host->mmc), __func__);
 			if (mrq->data && !mrq->data->error)
 				mrq->data->error = -ETIMEDOUT;
 			host->curr.data_xfered = 0;