platform: msm_shared: Handle Non-Fatal UE errors
UE errors which are UECPA and UECDL are non-fatal. Hence
just clear the UE bit in IS register and continue.
Change-Id: Ibbb707223e6da7e082e7d781b152e7c735716b62
diff --git a/platform/msm_shared/ufs_hci.c b/platform/msm_shared/ufs_hci.c
index 0605678..db930ed 100644
--- a/platform/msm_shared/ufs_hci.c
+++ b/platform/msm_shared/ufs_hci.c
@@ -92,12 +92,11 @@
enum handler_return ufs_irq_handler(void* data)
{
- uint32_t val;
+ uint32_t val, val_uecpa, val_uecdl, base;
struct ufs_dev *dev = (struct ufs_dev *) data;
struct ufs_req_irq_type irq;
-
- val = readl(UFS_IS(dev->base));
-
+ base = dev->base;
+ val = readl(UFS_IS(base));
if (val & UFS_IS_SBFES)
{
/* Controller might be in a bad state, unrecoverable error. */
@@ -122,9 +121,25 @@
else if (val & UFS_IS_UE)
{
/* Error in one of the layers in the UniPro stack */
- dprintf(CRITICAL, "UFS error: UE. Dumping UIC Error code registers\n");
- ufs_dump_hc_registers(dev);
- ASSERT(0);
+ dprintf(CRITICAL, "UFS error: UE.\n");
+ /* Check if the error is because of UECPA or UECDL */
+ val_uecpa = readl(UFS_UECPA(base));
+ val_uecdl = readl(UFS_UECDL(base));
+ if((val_uecpa & UFS_IS_UECPA) || (val_uecdl & UFS_IS_UECDL))
+ {
+ dprintf(CRITICAL, "UIC non-fatal error. IS: 0x%x UECPA: 0x%x UECDL: 0x%x\n",
+ val, val_uecpa, val_uecdl);
+ irq.irq_handled = BIT(2);
+ val &= ~UFS_IS_UE;
+ writel(irq.irq_handled, UFS_IS(dev->base));
+ dprintf(CRITICAL, "UIC non-fatal error handled. Pending interrupt mask: 0x%x\n", val);
+ }
+ else
+ {
+ dprintf(CRITICAL, "UIC fatal error.\n");
+ ufs_dump_hc_registers(dev);
+ ASSERT(0);
+ }
}
while (val)