diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index fa87bf91e5e42a13e1997717855b40733b42fc4d..c93571cea920c939374ff416d423096bb2e146a7 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ #define IPC_WRITE_BUFFER 0x80 #define IPC_READ_BUFFER 0x90 +/* Timeout in jiffies */ +#define IPC_TIMEOUT (3 * HZ) + static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ /* @@ -132,24 +135,20 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) /* Wait till scu status is busy */ static inline int busy_loop(struct intel_scu_ipc_dev *scu) { - u32 status = ipc_read_status(scu); - u32 loop_count = 100000; + unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT); - /* break if scu doesn't reset busy bit after huge retry */ - while ((status & IPC_STATUS_BUSY) && --loop_count) { - udelay(1); /* scu processing time is in few u secods */ - status = ipc_read_status(scu); - } + do { + u32 status; - if (status & IPC_STATUS_BUSY) { - dev_err(scu->dev, "IPC timed out"); - return -ETIMEDOUT; - } + status = ipc_read_status(scu); + if (!(status & IPC_STATUS_BUSY)) + return (status & IPC_STATUS_ERR) ? -EIO : 0; - if (status & IPC_STATUS_ERR) - return -EIO; + usleep_range(50, 100); + } while (time_before(jiffies, end)); - return 0; + dev_err(scu->dev, "IPC timed out"); + return -ETIMEDOUT; } /* Wait till ipc ioc interrupt is received or timeout in 3 HZ */ @@ -157,7 +156,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) { int status; - if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) { + if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) { dev_err(scu->dev, "IPC timed out\n"); return -ETIMEDOUT; }