ufs: dump on UIC error

When we hit a UIC error dump the associated error code registers for
debugging.

These aren't always fatal, but we don't yet have the necessary logic to
determine this...

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index a85b137..0631e2c 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -916,6 +916,22 @@
 	return ret;
 }
 
+static void ufshcd_dump_uic_error(struct ufs_hba *hba)
+{
+	u32 val;
+
+	val = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
+	debug("UIC phy adapter layer error: 0x%x\n", val);
+	val = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
+	debug("UIC data link layer error: 0x%x\n", val);
+	val = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER);
+	debug("UIC network layer error: 0x%x\n", val);
+	val = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER);
+	debug("UIC transport layer error: 0x%x\n", val);
+	val = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME);
+	debug("UIC DME error: 0x%x\n", val);
+}
+
 static int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 {
 	unsigned long start;
@@ -946,6 +962,10 @@
 
 			return -1;
 		}
+		if (intr_status & UIC_ERROR) {
+			dev_err(hba->dev, "UIC error\n");
+			ufshcd_dump_uic_error(hba);
+		}
 	} while (!(enabled_intr_status & UTP_TRANSFER_REQ_COMPL));
 
 	return 0;