Commit 83abd4d4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Merge tag 'platform-drivers-x86-v6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:

 -  Fix false positive apple_gmux backlight detection on older iGPU only
    MacBook models

 -  Various other small fixes and hardware-id additions

* tag 'platform-drivers-x86-v6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
  platform/x86: thinkpad_acpi: Fix profile modes on Intel platforms
  ACPI: video: Fix apple gmux detection
  platform/x86: apple-gmux: Add apple_gmux_detect() helper
  platform/x86: apple-gmux: Move port defines to apple-gmux.h
  platform/x86: hp-wmi: Fix cast to smaller integer type warning
  platform/x86/amd: pmc: Add a module parameter to disable workarounds
  platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN
  platform/x86: asus-wmi: Fix kbd_dock_devid tablet-switch reporting
  platform/x86: gigabyte-wmi: add support for B450M DS3H WIFI-CF
  platform/x86: hp-wmi: Handle Omen Key event
  platform/x86: dell-wmi: Add a keymap for KEY_MUTE in type 0x0010 table
parents 28b4387f 1bc5d819
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -110,26 +110,6 @@ static bool nvidia_wmi_ec_supported(void)
}
#endif

static bool apple_gmux_backlight_present(void)
{
	struct acpi_device *adev;
	struct device *dev;

	adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
	if (!adev)
		return false;

	dev = acpi_get_first_physical_node(adev);
	if (!dev)
		return false;

	/*
	 * drivers/platform/x86/apple-gmux.c only supports old style
	 * Apple GMUX with an IO-resource.
	 */
	return pnp_get_resource(to_pnp_dev(dev), IORESOURCE_IO, 0) != NULL;
}

/* Force to use vendor driver when the ACPI device is known to be
 * buggy */
static int video_detect_force_vendor(const struct dmi_system_id *d)
@@ -766,6 +746,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
{
	static DEFINE_MUTEX(init_mutex);
	static bool nvidia_wmi_ec_present;
	static bool apple_gmux_present;
	static bool native_available;
	static bool init_done;
	static long video_caps;
@@ -779,6 +760,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
				    ACPI_UINT32_MAX, find_video, NULL,
				    &video_caps, NULL);
		nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
		apple_gmux_present = apple_gmux_detect(NULL, NULL);
		init_done = true;
	}
	if (native)
@@ -800,7 +782,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
	if (nvidia_wmi_ec_present)
		return acpi_backlight_nvidia_wmi_ec;

	if (apple_gmux_backlight_present())
	if (apple_gmux_present)
		return acpi_backlight_apple_gmux;

	/* Use ACPI video if available, except when native should be preferred. */
+56 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/serio.h>
#include <linux/suspend.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
@@ -160,6 +161,10 @@ static bool enable_stb;
module_param(enable_stb, bool, 0644);
MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");

static bool disable_workarounds;
module_param(disable_workarounds, bool, 0644);
MODULE_PARM_DESC(disable_workarounds, "Disable workarounds for platform bugs");

static struct amd_pmc_dev pmc;
static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
@@ -653,6 +658,33 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
	return -EINVAL;
}

static int amd_pmc_czn_wa_irq1(struct amd_pmc_dev *pdev)
{
	struct device *d;
	int rc;

	if (!pdev->major) {
		rc = amd_pmc_get_smu_version(pdev);
		if (rc)
			return rc;
	}

	if (pdev->major > 64 || (pdev->major == 64 && pdev->minor > 65))
		return 0;

	d = bus_find_device_by_name(&serio_bus, NULL, "serio0");
	if (!d)
		return 0;
	if (device_may_wakeup(d)) {
		dev_info_once(d, "Disabling IRQ1 wakeup source to avoid platform firmware bug\n");
		disable_irq_wake(1);
		device_set_wakeup_enable(d, false);
	}
	put_device(d);

	return 0;
}

static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
{
	struct rtc_device *rtc_device;
@@ -715,8 +747,8 @@ static void amd_pmc_s2idle_prepare(void)
	/* Reset and Start SMU logging - to monitor the s0i3 stats */
	amd_pmc_setup_smu_logging(pdev);

	/* Activate CZN specific RTC functionality */
	if (pdev->cpu_id == AMD_CPU_ID_CZN) {
	/* Activate CZN specific platform bug workarounds */
	if (pdev->cpu_id == AMD_CPU_ID_CZN && !disable_workarounds) {
		rc = amd_pmc_verify_czn_rtc(pdev, &arg);
		if (rc) {
			dev_err(pdev->dev, "failed to set RTC: %d\n", rc);
@@ -782,6 +814,25 @@ static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
	.check = amd_pmc_s2idle_check,
	.restore = amd_pmc_s2idle_restore,
};

static int __maybe_unused amd_pmc_suspend_handler(struct device *dev)
{
	struct amd_pmc_dev *pdev = dev_get_drvdata(dev);

	if (pdev->cpu_id == AMD_CPU_ID_CZN && !disable_workarounds) {
		int rc = amd_pmc_czn_wa_irq1(pdev);

		if (rc) {
			dev_err(pdev->dev, "failed to adjust keyboard wakeup: %d\n", rc);
			return rc;
		}
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);

#endif

static const struct pci_device_id pmc_pci_ids[] = {
@@ -980,6 +1031,9 @@ static struct platform_driver amd_pmc_driver = {
		.name = "amd_pmc",
		.acpi_match_table = amd_pmc_acpi_ids,
		.dev_groups = pmc_groups,
#ifdef CONFIG_SUSPEND
		.pm = &amd_pmc_pm,
#endif
	},
	.probe = amd_pmc_probe,
	.remove = amd_pmc_remove,
+18 −75
Original line number Diff line number Diff line
@@ -64,29 +64,6 @@ struct apple_gmux_data {

static struct apple_gmux_data *apple_gmux_data;

/*
 * gmux port offsets. Many of these are not yet used, but may be in the
 * future, and it's useful to have them documented here anyhow.
 */
#define GMUX_PORT_VERSION_MAJOR		0x04
#define GMUX_PORT_VERSION_MINOR		0x05
#define GMUX_PORT_VERSION_RELEASE	0x06
#define GMUX_PORT_SWITCH_DISPLAY	0x10
#define GMUX_PORT_SWITCH_GET_DISPLAY	0x11
#define GMUX_PORT_INTERRUPT_ENABLE	0x14
#define GMUX_PORT_INTERRUPT_STATUS	0x16
#define GMUX_PORT_SWITCH_DDC		0x28
#define GMUX_PORT_SWITCH_EXTERNAL	0x40
#define GMUX_PORT_SWITCH_GET_EXTERNAL	0x41
#define GMUX_PORT_DISCRETE_POWER	0x50
#define GMUX_PORT_MAX_BRIGHTNESS	0x70
#define GMUX_PORT_BRIGHTNESS		0x74
#define GMUX_PORT_VALUE			0xc2
#define GMUX_PORT_READ			0xd0
#define GMUX_PORT_WRITE			0xd4

#define GMUX_MIN_IO_LEN			(GMUX_PORT_BRIGHTNESS + 4)

#define GMUX_INTERRUPT_ENABLE		0xff
#define GMUX_INTERRUPT_DISABLE		0x00

@@ -249,23 +226,6 @@ static void gmux_write32(struct apple_gmux_data *gmux_data, int port,
		gmux_pio_write32(gmux_data, port, val);
}

static bool gmux_is_indexed(struct apple_gmux_data *gmux_data)
{
	u16 val;

	outb(0xaa, gmux_data->iostart + 0xcc);
	outb(0x55, gmux_data->iostart + 0xcd);
	outb(0x00, gmux_data->iostart + 0xce);

	val = inb(gmux_data->iostart + 0xcc) |
		(inb(gmux_data->iostart + 0xcd) << 8);

	if (val == 0x55aa)
		return true;

	return false;
}

/**
 * DOC: Backlight control
 *
@@ -605,60 +565,43 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
	int ret = -ENXIO;
	acpi_status status;
	unsigned long long gpe;
	bool indexed = false;
	u32 version;

	if (apple_gmux_data)
		return -EBUSY;

	if (!apple_gmux_detect(pnp, &indexed)) {
		pr_info("gmux device not present\n");
		return -ENODEV;
	}

	gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
	if (!gmux_data)
		return -ENOMEM;
	pnp_set_drvdata(pnp, gmux_data);

	res = pnp_get_resource(pnp, IORESOURCE_IO, 0);
	if (!res) {
		pr_err("Failed to find gmux I/O resource\n");
		goto err_free;
	}

	gmux_data->iostart = res->start;
	gmux_data->iolen = resource_size(res);

	if (gmux_data->iolen < GMUX_MIN_IO_LEN) {
		pr_err("gmux I/O region too small (%lu < %u)\n",
		       gmux_data->iolen, GMUX_MIN_IO_LEN);
		goto err_free;
	}

	if (!request_region(gmux_data->iostart, gmux_data->iolen,
			    "Apple gmux")) {
		pr_err("gmux I/O already in use\n");
		goto err_free;
	}

	/*
	 * Invalid version information may indicate either that the gmux
	 * device isn't present or that it's a new one that uses indexed
	 * io
	 */

	ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
	ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
	ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
	if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
		if (gmux_is_indexed(gmux_data)) {
			u32 version;
	if (indexed) {
		mutex_init(&gmux_data->index_lock);
		gmux_data->indexed = true;
			version = gmux_read32(gmux_data,
				GMUX_PORT_VERSION_MAJOR);
		version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR);
		ver_major = (version >> 24) & 0xff;
		ver_minor = (version >> 16) & 0xff;
		ver_release = (version >> 8) & 0xff;
	} else {
			pr_info("gmux device not present\n");
			ret = -ENODEV;
			goto err_release;
		}
		ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
		ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
		ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
	}
	pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
		ver_release, (gmux_data->indexed ? "indexed" : "classic"));
+12 −5
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ struct asus_wmi {

	int tablet_switch_event_code;
	u32 tablet_switch_dev_id;
	bool tablet_switch_inverted;

	enum fan_type fan_type;
	enum fan_type gpu_fan_type;
@@ -493,6 +494,13 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
}

/* Input **********************************************************************/
static void asus_wmi_tablet_sw_report(struct asus_wmi *asus, bool value)
{
	input_report_switch(asus->inputdev, SW_TABLET_MODE,
			    asus->tablet_switch_inverted ? !value : value);
	input_sync(asus->inputdev);
}

static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event_code)
{
	struct device *dev = &asus->platform_device->dev;
@@ -501,7 +509,7 @@ static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event
	result = asus_wmi_get_devstate_simple(asus, dev_id);
	if (result >= 0) {
		input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
		input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
		asus_wmi_tablet_sw_report(asus, result);
		asus->tablet_switch_dev_id = dev_id;
		asus->tablet_switch_event_code = event_code;
	} else if (result == -ENODEV) {
@@ -534,6 +542,7 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
	case asus_wmi_no_tablet_switch:
		break;
	case asus_wmi_kbd_dock_devid:
		asus->tablet_switch_inverted = true;
		asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_KBD_DOCK, NOTIFY_KBD_DOCK_CHANGE);
		break;
	case asus_wmi_lid_flip_devid:
@@ -573,10 +582,8 @@ static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
		return;

	result = asus_wmi_get_devstate_simple(asus, asus->tablet_switch_dev_id);
	if (result >= 0) {
		input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
		input_sync(asus->inputdev);
	}
	if (result >= 0)
		asus_wmi_tablet_sw_report(asus, result);
}

/* dGPU ********************************************************************/
+3 −0
Original line number Diff line number Diff line
@@ -261,6 +261,9 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
	{ KE_KEY,    0x57, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY,    0x58, { KEY_BRIGHTNESSUP } },

	/*Speaker Mute*/
	{ KE_KEY, 0x109, { KEY_MUTE} },

	/* Mic mute */
	{ KE_KEY, 0x150, { KEY_MICMUTE } },

Loading