Commit 3a457d28 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'platform-drivers-x86-v6.6-3' of...

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()
parents 27bbf45e bc3b6f59
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -13616,6 +13616,7 @@ F: drivers/net/ethernet/mellanox/mlxfw/
MELLANOX HARDWARE PLATFORM SUPPORT
M:	Hans de Goede <hdegoede@redhat.com>
M:	Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
M:	Mark Gross <markgross@kernel.org>
M:	Vadim Pasternak <vadimp@nvidia.com>
L:	platform-driver-x86@vger.kernel.org
@@ -14210,6 +14211,7 @@ F: drivers/platform/surface/surface_gpe.c
MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
M:	Hans de Goede <hdegoede@redhat.com>
M:	Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
M:	Mark Gross <markgross@kernel.org>
M:	Maximilian Luz <luzmaximilian@gmail.com>
L:	platform-driver-x86@vger.kernel.org
@@ -23423,9 +23425,11 @@ F: drivers/platform/x86/x86-android-tablets/
X86 PLATFORM DRIVERS
M:	Hans de Goede <hdegoede@redhat.com>
M:	Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
M:	Mark Gross <markgross@kernel.org>
L:	platform-driver-x86@vger.kernel.org
S:	Maintained
Q:	https://patchwork.kernel.org/project/platform-driver-x86/list/
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
F:	drivers/platform/olpc/
F:	drivers/platform/x86/
+40 −26
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/slab.h>

@@ -231,19 +232,15 @@ 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)
{
	unsigned long end = jiffies + IPC_TIMEOUT;
	u8 status;
	int err;

	do {
		u32 status;
	err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY),
				 100, jiffies_to_usecs(IPC_TIMEOUT));
	if (err)
		return err;

		status = ipc_read_status(scu);
		if (!(status & IPC_STATUS_BUSY))
	return (status & IPC_STATUS_ERR) ? -EIO : 0;

		usleep_range(50, 100);
	} while (time_before(jiffies, end));

	return -ETIMEDOUT;
}

/* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
@@ -251,10 +248,12 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
{
	int status;

	if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT))
		return -ETIMEDOUT;
	wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT);

	status = ipc_read_status(scu);
	if (status & IPC_STATUS_BUSY)
		return -ETIMEDOUT;

	if (status & IPC_STATUS_ERR)
		return -EIO;

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

static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu)
{
	u8 status;

	if (!scu)
		scu = ipcdev;
	if (!scu)
		return ERR_PTR(-ENODEV);

	status = ipc_read_status(scu);
	if (status & IPC_STATUS_BUSY) {
		dev_dbg(&scu->dev, "device is busy\n");
		return ERR_PTR(-EBUSY);
	}

	return scu;
}

/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data,
			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,
	memset(cbuf, 0, sizeof(cbuf));

	mutex_lock(&ipclock);
	if (!scu)
		scu = ipcdev;
	if (!scu) {
	scu = intel_scu_ipc_get(scu);
	if (IS_ERR(scu)) {
		mutex_unlock(&ipclock);
		return -ENODEV;
		return PTR_ERR(scu);
	}

	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,
	int err;

	mutex_lock(&ipclock);
	if (!scu)
		scu = ipcdev;
	if (!scu) {
	scu = intel_scu_ipc_get(scu);
	if (IS_ERR(scu)) {
		mutex_unlock(&ipclock);
		return -ENODEV;
		return PTR_ERR(scu);
	}
	scu = ipcdev;

	cmdval = sub << 12 | cmd;
	ipc_command(scu, cmdval);
	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,
		return -EINVAL;

	mutex_lock(&ipclock);
	if (!scu)
		scu = ipcdev;
	if (!scu) {
	scu = intel_scu_ipc_get(scu);
	if (IS_ERR(scu)) {
		mutex_unlock(&ipclock);
		return -ENODEV;
		return PTR_ERR(scu);
	}

	memcpy(inbuf, in, inlen);
+2 −0
Original line number Diff line number Diff line
@@ -4116,9 +4116,11 @@ static void hotkey_resume(void)
{
	tpacpi_disable_brightness_delay();

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

	tpacpi_send_radiosw_update();
	tpacpi_input_send_tabletsw();