hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/platform/x86/intel_scu_ipc.c
....@@ -19,6 +19,7 @@
1919 #include <linux/init.h>
2020 #include <linux/interrupt.h>
2121 #include <linux/io.h>
22
+#include <linux/iopoll.h>
2223 #include <linux/module.h>
2324 #include <linux/slab.h>
2425
....@@ -232,19 +233,15 @@
232233 /* Wait till scu status is busy */
233234 static inline int busy_loop(struct intel_scu_ipc_dev *scu)
234235 {
235
- unsigned long end = jiffies + IPC_TIMEOUT;
236
+ u8 status;
237
+ int err;
236238
237
- do {
238
- u32 status;
239
+ err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY),
240
+ 100, jiffies_to_usecs(IPC_TIMEOUT));
241
+ if (err)
242
+ return err;
239243
240
- status = ipc_read_status(scu);
241
- if (!(status & IPC_STATUS_BUSY))
242
- return (status & IPC_STATUS_ERR) ? -EIO : 0;
243
-
244
- usleep_range(50, 100);
245
- } while (time_before(jiffies, end));
246
-
247
- return -ETIMEDOUT;
244
+ return (status & IPC_STATUS_ERR) ? -EIO : 0;
248245 }
249246
250247 /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
....@@ -252,10 +249,12 @@
252249 {
253250 int status;
254251
255
- if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT))
256
- return -ETIMEDOUT;
252
+ wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT);
257253
258254 status = ipc_read_status(scu);
255
+ if (status & IPC_STATUS_BUSY)
256
+ return -ETIMEDOUT;
257
+
259258 if (status & IPC_STATUS_ERR)
260259 return -EIO;
261260
....@@ -265,6 +264,24 @@
265264 static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
266265 {
267266 return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
267
+}
268
+
269
+static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu)
270
+{
271
+ u8 status;
272
+
273
+ if (!scu)
274
+ scu = ipcdev;
275
+ if (!scu)
276
+ return ERR_PTR(-ENODEV);
277
+
278
+ status = ipc_read_status(scu);
279
+ if (status & IPC_STATUS_BUSY) {
280
+ dev_dbg(&scu->dev, "device is busy\n");
281
+ return ERR_PTR(-EBUSY);
282
+ }
283
+
284
+ return scu;
268285 }
269286
270287 /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
....@@ -280,11 +297,10 @@
280297 memset(cbuf, 0, sizeof(cbuf));
281298
282299 mutex_lock(&ipclock);
283
- if (!scu)
284
- scu = ipcdev;
285
- if (!scu) {
300
+ scu = intel_scu_ipc_get(scu);
301
+ if (IS_ERR(scu)) {
286302 mutex_unlock(&ipclock);
287
- return -ENODEV;
303
+ return PTR_ERR(scu);
288304 }
289305
290306 for (nc = 0; nc < count; nc++, offset += 2) {
....@@ -439,13 +455,12 @@
439455 int err;
440456
441457 mutex_lock(&ipclock);
442
- if (!scu)
443
- scu = ipcdev;
444
- if (!scu) {
458
+ scu = intel_scu_ipc_get(scu);
459
+ if (IS_ERR(scu)) {
445460 mutex_unlock(&ipclock);
446
- return -ENODEV;
461
+ return PTR_ERR(scu);
447462 }
448
- scu = ipcdev;
463
+
449464 cmdval = sub << 12 | cmd;
450465 ipc_command(scu, cmdval);
451466 err = intel_scu_ipc_check_status(scu);
....@@ -485,11 +500,10 @@
485500 return -EINVAL;
486501
487502 mutex_lock(&ipclock);
488
- if (!scu)
489
- scu = ipcdev;
490
- if (!scu) {
503
+ scu = intel_scu_ipc_get(scu);
504
+ if (IS_ERR(scu)) {
491505 mutex_unlock(&ipclock);
492
- return -ENODEV;
506
+ return PTR_ERR(scu);
493507 }
494508
495509 memcpy(inbuf, in, inlen);
....@@ -583,7 +597,6 @@
583597 scu->dev.parent = parent;
584598 scu->dev.class = &intel_scu_ipc_class;
585599 scu->dev.release = intel_scu_ipc_release;
586
- dev_set_name(&scu->dev, "intel_scu_ipc");
587600
588601 if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem),
589602 "intel_scu_ipc")) {
....@@ -612,6 +625,7 @@
612625 * After this point intel_scu_ipc_release() takes care of
613626 * releasing the SCU IPC resources once refcount drops to zero.
614627 */
628
+ dev_set_name(&scu->dev, "intel_scu_ipc");
615629 err = device_register(&scu->dev);
616630 if (err) {
617631 put_device(&scu->dev);