IPC: add delay if read mip failed
authorDong Yang <dong.yang@intel.com>
Tue, 19 Jun 2012 05:20:29 +0000 (13:20 +0800)
committerbuildbot <buildbot@intel.com>
Thu, 21 Jun 2012 14:35:48 +0000 (07:35 -0700)
BZ: 42495

The read_mip() function uses a dead loop to access mip, if read
mip access failed, this is not reasonable, since SCU will access
the emmc, and get the emmc mutex, if get mutex failed, SCU will
return and this function will read error return status and
trigger the IPC again. This will bring up the SCU interrupt storm,
about 800 times/second, and impact the other IPC. So we add a
delay in this loop, or IPC will continue until IA release the
emmc mutex.

Change-Id: I022fd46e04530b31d5118f91f3b1404b3ab85d0d
Signed-off-by: Dong Yang <dong.yang@intel.com>
Reviewed-on: http://android.intel.com:8080/53241
Reviewed-by: Zhang, Shijie <shijie.zhang@intel.com>
Reviewed-by: Du, Alek <alek.du@intel.com>
Reviewed-by: Mansoor, Illyas <illyas.mansoor@intel.com>
Reviewed-by: He, Bo <bo.he@intel.com>
Tested-by: Tang, HaifengX <haifengx.tang@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/platform/x86/intel_scu_mip.c

index bce3da1..594ed24 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/ipc_device.h>
 #include <linux/fs.h>
+#include <linux/delay.h>
 #include <asm/intel_scu_ipc.h>
 
 #define IPC_MIP_BASE     0xFFFD8000    /* sram base address for mip accessing*/
@@ -44,6 +45,8 @@ static int read_mip(u8 *data, int len, int offset, int issigned)
        do {
                ret = intel_scu_ipc_raw_cmd(cmd, 0, NULL, 0, &data_off, 1,
                                dptr, sptr);
+               if (ret == -EIO)
+                       msleep(20);
        } while (ret == -EIO);
 
        if (!ret)
@@ -101,10 +104,13 @@ int intel_scu_ipc_write_umip(u8 *data, int len, int offset)
        sptr = len_align / 4;
        cmd = IPC_CMD_UMIP_WR << 12 | IPCMSG_MIP_ACCESS;
 
+       memcpy(intel_mip_base, buf, len_align);
+
        do {
-               memcpy(intel_mip_base, buf, len_align);
                ret = intel_scu_ipc_raw_cmd(cmd, 0, NULL, 0, NULL, 0,
                                dptr, sptr);
+               if (ret == -EIO)
+                       msleep(20);
        } while (ret == -EIO);
 
 fail: