return -ENODEV;
}
- writel(offset, ipcdev.ipc_base + IPC_DPTR_ADDR);
- writel((len + 3) / 4, ipcdev.ipc_base + IPC_SPTR_ADDR);
-
- cmdid = issigned ? IPC_CMD_SMIP_RD : IPC_CMD_UMIP_RD;
- ipc_command(4 << 16 | cmdid << 12 | IPCMSG_MIP_ACCESS);
- ret = ipc_wait_interrupt();
+ do {
+ writel(offset, ipcdev.ipc_base + IPC_DPTR_ADDR);
+ writel((len + 3) / 4, ipcdev.ipc_base + IPC_SPTR_ADDR);
+
+ cmdid = issigned ? IPC_CMD_SMIP_RD : IPC_CMD_UMIP_RD;
+ ipc_command(4 << 16 | cmdid << 12 | IPCMSG_MIP_ACCESS);
+ ret = ipc_wait_interrupt();
+ } while (ret == -EIO);
if (!ret) {
data_off = ipc_data_readl(0);
memcpy(data, ipcdev.mip_base + data_off, len);
mutex_unlock(&ipclock);
return -ENODEV;
}
-
- writel(offset, ipcdev.ipc_base + IPC_DPTR_ADDR);
- writel((len + 3) / 4, ipcdev.ipc_base + IPC_SPTR_ADDR);
- memcpy(ipcdev.mip_base, data, len);
- ipc_command(IPC_CMD_UMIP_WR << 12 | IPCMSG_MIP_ACCESS);
- ret = ipc_wait_interrupt();
+ do {
+ writel(offset, ipcdev.ipc_base + IPC_DPTR_ADDR);
+ writel((len + 3) / 4, ipcdev.ipc_base + IPC_SPTR_ADDR);
+ memcpy(ipcdev.mip_base, data, len);
+ ipc_command(IPC_CMD_UMIP_WR << 12 | IPCMSG_MIP_ACCESS);
+ ret = ipc_wait_interrupt();
+ } while (ret == -EIO);
mutex_unlock(&ipclock);
return ret;