提交 e7b7ab38 编写于 作者: M Mika Westerberg 提交者: Andy Shevchenko

platform/x86: intel_scu_ipc: Sleeping is fine when polling

There is no reason why the driver would need to block other threads from
running the CPU while it is waiting for the SCU IPC to complete its
work. For this reason switch the driver to use usleep_range() instead
with a bit more relaxed polling loop.

Also add constant for the timeout and use the same value for both
polling and interrupt modes.
Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
上级 74e9748b
...@@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ ...@@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
#define IPC_WRITE_BUFFER 0x80 #define IPC_WRITE_BUFFER 0x80
#define IPC_READ_BUFFER 0x90 #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 */ 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) ...@@ -132,24 +135,20 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
/* Wait till scu status is busy */ /* Wait till scu status is busy */
static inline int busy_loop(struct intel_scu_ipc_dev *scu) static inline int busy_loop(struct intel_scu_ipc_dev *scu)
{ {
u32 status = ipc_read_status(scu); unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT);
u32 loop_count = 100000;
/* break if scu doesn't reset busy bit after huge retry */ do {
while ((status & IPC_STATUS_BUSY) && --loop_count) { u32 status;
udelay(1); /* scu processing time is in few u secods */
status = ipc_read_status(scu);
}
if (status & IPC_STATUS_BUSY) { status = ipc_read_status(scu);
dev_err(scu->dev, "IPC timed out"); if (!(status & IPC_STATUS_BUSY))
return -ETIMEDOUT; return (status & IPC_STATUS_ERR) ? -EIO : 0;
}
if (status & IPC_STATUS_ERR) usleep_range(50, 100);
return -EIO; } 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 */ /* 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) ...@@ -157,7 +156,7 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
{ {
int status; 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"); dev_err(scu->dev, "IPC timed out\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册