Skip to content

Commit e7b7ab3

Browse files
westeriandy-shev
authored andcommitted
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: Mika Westerberg <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]>
1 parent 74e9748 commit e7b7ab3

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed

drivers/platform/x86/intel_scu_ipc.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
7979
#define IPC_WRITE_BUFFER 0x80
8080
#define IPC_READ_BUFFER 0x90
8181

82+
/* Timeout in jiffies */
83+
#define IPC_TIMEOUT (3 * HZ)
84+
8285
static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
8386

8487
/*
@@ -132,32 +135,28 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
132135
/* Wait till scu status is busy */
133136
static inline int busy_loop(struct intel_scu_ipc_dev *scu)
134137
{
135-
u32 status = ipc_read_status(scu);
136-
u32 loop_count = 100000;
138+
unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT);
137139

138-
/* break if scu doesn't reset busy bit after huge retry */
139-
while ((status & IPC_STATUS_BUSY) && --loop_count) {
140-
udelay(1); /* scu processing time is in few u secods */
141-
status = ipc_read_status(scu);
142-
}
140+
do {
141+
u32 status;
143142

144-
if (status & IPC_STATUS_BUSY) {
145-
dev_err(scu->dev, "IPC timed out");
146-
return -ETIMEDOUT;
147-
}
143+
status = ipc_read_status(scu);
144+
if (!(status & IPC_STATUS_BUSY))
145+
return (status & IPC_STATUS_ERR) ? -EIO : 0;
148146

149-
if (status & IPC_STATUS_ERR)
150-
return -EIO;
147+
usleep_range(50, 100);
148+
} while (time_before(jiffies, end));
151149

152-
return 0;
150+
dev_err(scu->dev, "IPC timed out");
151+
return -ETIMEDOUT;
153152
}
154153

155154
/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
156155
static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
157156
{
158157
int status;
159158

160-
if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) {
159+
if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) {
161160
dev_err(scu->dev, "IPC timed out\n");
162161
return -ETIMEDOUT;
163162
}

0 commit comments

Comments
 (0)