Skip to content

Commit 3a457d2

Browse files
committed
Merge tag 'platform-drivers-x86-v6.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform driver fixes from Hans de Goede: "The most noteworthy change in here is the addition of Ilpo Järvinen as co-maintainer of platform-drivers-x86. Ilpo will be helping me with platform-drivers-x86 maintenance going forward and you can expect pull-requests from Ilpo in the future. Other then that there is a set of Intel SCU IPC fixes and a thinkpad_acpi locking fix" * tag 'platform-drivers-x86-v6.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: MAINTAINERS: Add x86 platform drivers patchwork MAINTAINERS: Add myself into x86 platform driver maintainers platform/x86: thinkpad_acpi: Take mutex in hotkey_resume platform/x86: intel_scu_ipc: Fail IPC send if still busy platform/x86: intel_scu_ipc: Don't override scu in intel_scu_ipc_dev_simple_command() platform/x86: intel_scu_ipc: Check status upon timeout in ipc_wait_for_interrupt() platform/x86: intel_scu_ipc: Check status after timeout in busy_loop()
2 parents 27bbf45 + bc3b6f5 commit 3a457d2

File tree

3 files changed

+46
-26
lines changed

3 files changed

+46
-26
lines changed

MAINTAINERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13616,6 +13616,7 @@ F: drivers/net/ethernet/mellanox/mlxfw/
1361613616

1361713617
MELLANOX HARDWARE PLATFORM SUPPORT
1361813618
M: Hans de Goede <hdegoede@redhat.com>
13619+
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1361913620
M: Mark Gross <markgross@kernel.org>
1362013621
M: Vadim Pasternak <vadimp@nvidia.com>
1362113622
L: platform-driver-x86@vger.kernel.org
@@ -14210,6 +14211,7 @@ F: drivers/platform/surface/surface_gpe.c
1421014211

1421114212
MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
1421214213
M: Hans de Goede <hdegoede@redhat.com>
14214+
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1421314215
M: Mark Gross <markgross@kernel.org>
1421414216
M: Maximilian Luz <luzmaximilian@gmail.com>
1421514217
L: platform-driver-x86@vger.kernel.org
@@ -23423,9 +23425,11 @@ F: drivers/platform/x86/x86-android-tablets/
2342323425

2342423426
X86 PLATFORM DRIVERS
2342523427
M: Hans de Goede <hdegoede@redhat.com>
23428+
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2342623429
M: Mark Gross <markgross@kernel.org>
2342723430
L: platform-driver-x86@vger.kernel.org
2342823431
S: Maintained
23432+
Q: https://patchwork.kernel.org/project/platform-driver-x86/list/
2342923433
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
2343023434
F: drivers/platform/olpc/
2343123435
F: drivers/platform/x86/

drivers/platform/x86/intel_scu_ipc.c

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -231,30 +232,28 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
231232
/* Wait till scu status is busy */
232233
static inline int busy_loop(struct intel_scu_ipc_dev *scu)
233234
{
234-
unsigned long end = jiffies + IPC_TIMEOUT;
235-
236-
do {
237-
u32 status;
238-
239-
status = ipc_read_status(scu);
240-
if (!(status & IPC_STATUS_BUSY))
241-
return (status & IPC_STATUS_ERR) ? -EIO : 0;
235+
u8 status;
236+
int err;
242237

243-
usleep_range(50, 100);
244-
} while (time_before(jiffies, end));
238+
err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY),
239+
100, jiffies_to_usecs(IPC_TIMEOUT));
240+
if (err)
241+
return err;
245242

246-
return -ETIMEDOUT;
243+
return (status & IPC_STATUS_ERR) ? -EIO : 0;
247244
}
248245

249246
/* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
250247
static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
251248
{
252249
int status;
253250

254-
if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT))
255-
return -ETIMEDOUT;
251+
wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT);
256252

257253
status = ipc_read_status(scu);
254+
if (status & IPC_STATUS_BUSY)
255+
return -ETIMEDOUT;
256+
258257
if (status & IPC_STATUS_ERR)
259258
return -EIO;
260259

@@ -266,6 +265,24 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
266265
return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
267266
}
268267

268+
static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu)
269+
{
270+
u8 status;
271+
272+
if (!scu)
273+
scu = ipcdev;
274+
if (!scu)
275+
return ERR_PTR(-ENODEV);
276+
277+
status = ipc_read_status(scu);
278+
if (status & IPC_STATUS_BUSY) {
279+
dev_dbg(&scu->dev, "device is busy\n");
280+
return ERR_PTR(-EBUSY);
281+
}
282+
283+
return scu;
284+
}
285+
269286
/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
270287
static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
271288
u32 count, u32 op, u32 id)
@@ -279,11 +296,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
279296
memset(cbuf, 0, sizeof(cbuf));
280297

281298
mutex_lock(&ipclock);
282-
if (!scu)
283-
scu = ipcdev;
284-
if (!scu) {
299+
scu = intel_scu_ipc_get(scu);
300+
if (IS_ERR(scu)) {
285301
mutex_unlock(&ipclock);
286-
return -ENODEV;
302+
return PTR_ERR(scu);
287303
}
288304

289305
for (nc = 0; nc < count; nc++, offset += 2) {
@@ -438,13 +454,12 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
438454
int err;
439455

440456
mutex_lock(&ipclock);
441-
if (!scu)
442-
scu = ipcdev;
443-
if (!scu) {
457+
scu = intel_scu_ipc_get(scu);
458+
if (IS_ERR(scu)) {
444459
mutex_unlock(&ipclock);
445-
return -ENODEV;
460+
return PTR_ERR(scu);
446461
}
447-
scu = ipcdev;
462+
448463
cmdval = sub << 12 | cmd;
449464
ipc_command(scu, cmdval);
450465
err = intel_scu_ipc_check_status(scu);
@@ -484,11 +499,10 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd,
484499
return -EINVAL;
485500

486501
mutex_lock(&ipclock);
487-
if (!scu)
488-
scu = ipcdev;
489-
if (!scu) {
502+
scu = intel_scu_ipc_get(scu);
503+
if (IS_ERR(scu)) {
490504
mutex_unlock(&ipclock);
491-
return -ENODEV;
505+
return PTR_ERR(scu);
492506
}
493507

494508
memcpy(inbuf, in, inlen);

drivers/platform/x86/thinkpad_acpi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,9 +4116,11 @@ static void hotkey_resume(void)
41164116
{
41174117
tpacpi_disable_brightness_delay();
41184118

4119+
mutex_lock(&hotkey_mutex);
41194120
if (hotkey_status_set(true) < 0 ||
41204121
hotkey_mask_set(hotkey_acpi_mask) < 0)
41214122
pr_err("error while attempting to reset the event firmware interface\n");
4123+
mutex_unlock(&hotkey_mutex);
41224124

41234125
tpacpi_send_radiosw_update();
41244126
tpacpi_input_send_tabletsw();

0 commit comments

Comments
 (0)