diff options
author | Hans de Goede <hdegoede@redhat.com> | 2023-08-23 18:30:50 +0300 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2023-08-23 18:30:50 +0300 |
commit | b0c7f1d9d742911dd22703bf8b25ea85ae2363dd (patch) | |
tree | 6de0444803bb3211f9914bcc610f7e4f4a150f45 /drivers | |
parent | 559eed7776c6557acf58e86c48ddaed9301550fd (diff) | |
parent | 0848cab765c634597636810bf76d0934003cce28 (diff) | |
download | linux-b0c7f1d9d742911dd22703bf8b25ea85ae2363dd.tar.xz |
Merge remote-tracking branch 'pdx86/fixes' into pdx86/for-next
Merge pdx86/fixes into pdx86/for-next because there are some
pdx86 patches pending for the next release which build on top
of some of the fixes.
Diffstat (limited to 'drivers')
27 files changed, 514 insertions, 243 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5b145f1aaa1b..87e385542576 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1714,6 +1714,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) {"BSG1160", }, {"BSG2150", }, {"CSC3551", }, + {"CSC3556", }, {"INT33FE", }, {"INT3515", }, /* Non-conforming _HID for Cirrus Logic already released */ diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c index a79318e90a13..b600b77d91ef 100644 --- a/drivers/platform/mellanox/mlxbf-tmfifo.c +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -887,6 +887,7 @@ static bool mlxbf_tmfifo_virtio_notify(struct virtqueue *vq) tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE]; mlxbf_tmfifo_console_output(tm_vdev, vring); spin_unlock_irqrestore(&fifo->spin_lock[0], flags); + set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events)) { return true; diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile index 2c229198e24c..65732f0a3913 100644 --- a/drivers/platform/x86/amd/Makefile +++ b/drivers/platform/x86/amd/Makefile @@ -4,7 +4,7 @@ # AMD x86 Platform-Specific Drivers # -amd-pmc-y := pmc.o +amd-pmc-y := pmc.o pmc-quirks.o obj-$(CONFIG_AMD_PMC) += amd-pmc.o amd_hsmp-y := hsmp.o obj-$(CONFIG_AMD_HSMP) += amd_hsmp.o diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c new file mode 100644 index 000000000000..ad702463a65d --- /dev/null +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD SoC Power Management Controller Driver Quirks + * + * Copyright (c) 2023, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Mario Limonciello <mario.limonciello@amd.com> + */ + +#include <linux/dmi.h> +#include <linux/io.h> +#include <linux/ioport.h> + +#include "pmc.h" + +struct quirk_entry { + u32 s2idle_bug_mmio; +}; + +static struct quirk_entry quirk_s2idle_bug = { + .s2idle_bug_mmio = 0xfed80380, +}; + +static const struct dmi_system_id fwbug_list[] = { + { + .ident = "L14 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), + } + }, + { + .ident = "T14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), + } + }, + { + .ident = "X13 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), + } + }, + { + .ident = "T14 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), + } + }, + { + .ident = "T14 Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), + } + }, + { + .ident = "T14 Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), + } + }, + { + .ident = "T14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), + } + }, + { + .ident = "T14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"), + } + }, + { + .ident = "P14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), + } + }, + { + .ident = "P14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), + } + }, + { + .ident = "P14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), + } + }, + /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ + { + .ident = "HP Laptop 15s-eq2xxx", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"), + } + }, + {} +}; + +/* + * Laptops that run a SMI handler during the D3->D0 transition that occurs + * specifically when exiting suspend to idle which can cause + * large delays during resume when the IOMMU translation layer is enabled (the default + * behavior) for NVME devices: + * + * To avoid this firmware problem, skip the SMI handler on these machines before the + * D0 transition occurs. + */ +static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) +{ + void __iomem *addr; + u8 val; + + if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80")) + return; + + addr = ioremap(s2idle_bug_mmio, 1); + if (!addr) + goto cleanup_resource; + + val = ioread8(addr); + iowrite8(val & ~BIT(0), addr); + + iounmap(addr); +cleanup_resource: + release_mem_region(s2idle_bug_mmio, 1); +} + +void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) +{ + if (dev->quirks && dev->quirks->s2idle_bug_mmio) + amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio); +} + +void amd_pmc_quirks_init(struct amd_pmc_dev *dev) +{ + const struct dmi_system_id *dmi_id; + + dmi_id = dmi_first_match(fwbug_list); + if (!dmi_id) + return; + dev->quirks = dmi_id->driver_data; + if (dev->quirks->s2idle_bug_mmio) + pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", + dmi_id->ident); +} diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c index 7d3d080ff174..c1e788b67a74 100644 --- a/drivers/platform/x86/amd/pmc.c +++ b/drivers/platform/x86/amd/pmc.c @@ -28,6 +28,8 @@ #include <linux/seq_file.h> #include <linux/uaccess.h> +#include "pmc.h" + /* SMU communication registers */ #define AMD_PMC_REGISTER_MESSAGE 0x538 #define AMD_PMC_REGISTER_RESPONSE 0x980 @@ -94,6 +96,7 @@ #define AMD_CPU_ID_CB 0x14D8 #define AMD_CPU_ID_PS 0x14E8 #define AMD_CPU_ID_SP 0x14A4 +#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 #define PMC_MSG_DELAY_MIN_US 50 #define RESPONSE_REGISTER_LOOP_MAX 20000 @@ -146,29 +149,6 @@ static const struct amd_pmc_bit_map soc15_ip_blk[] = { {} }; -struct amd_pmc_dev { - void __iomem *regbase; - void __iomem *smu_virt_addr; - void __iomem *stb_virt_addr; - void __iomem *fch_virt_addr; - bool msg_port; - u32 base_addr; - u32 cpu_id; - u32 active_ips; - u32 dram_size; - u32 num_ips; - u32 s2d_msg_id; -/* SMU version information */ - u8 smu_program; - u8 major; - u8 minor; - u8 rev; - struct device *dev; - struct pci_dev *rdev; - struct mutex lock; /* generic mutex lock */ - struct dentry *dbgfs_dir; -}; - static bool enable_stb; module_param(enable_stb, bool, 0644); MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism"); @@ -891,6 +871,8 @@ static void amd_pmc_s2idle_restore(void) /* Notify on failed entry */ amd_pmc_validate_deepest(pdev); + + amd_pmc_process_restore_quirks(pdev); } static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = { @@ -926,6 +908,7 @@ static const struct pci_device_id pmc_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SP) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { } }; @@ -1087,6 +1070,8 @@ static int amd_pmc_probe(struct platform_device *pdev) err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops); if (err) dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n"); + if (!disable_workarounds) + amd_pmc_quirks_init(dev); } amd_pmc_dbgfs_register(dev); @@ -1115,6 +1100,7 @@ static const struct acpi_device_id amd_pmc_acpi_ids[] = { {"AMDI0007", 0}, {"AMDI0008", 0}, {"AMDI0009", 0}, + {"AMDI000A", 0}, {"AMD0004", 0}, {"AMD0005", 0}, { } diff --git a/drivers/platform/x86/amd/pmc.h b/drivers/platform/x86/amd/pmc.h new file mode 100644 index 000000000000..c27bd6a5642f --- /dev/null +++ b/drivers/platform/x86/amd/pmc.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD SoC Power Management Controller Driver + * + * Copyright (c) 2023, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Mario Limonciello <mario.limonciello@amd.com> + */ + +#ifndef PMC_H +#define PMC_H + +#include <linux/types.h> +#include <linux/mutex.h> + +struct amd_pmc_dev { + void __iomem *regbase; + void __iomem *smu_virt_addr; + void __iomem *stb_virt_addr; + void __iomem *fch_virt_addr; + bool msg_port; + u32 base_addr; + u32 cpu_id; + u32 active_ips; + u32 dram_size; + u32 num_ips; + u32 s2d_msg_id; +/* SMU version information */ + u8 smu_program; + u8 major; + u8 minor; + u8 rev; + struct device *dev; + struct pci_dev *rdev; + struct mutex lock; /* generic mutex lock */ + struct dentry *dbgfs_dir; + struct quirk_entry *quirks; +}; + +void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev); +void amd_pmc_quirks_init(struct amd_pmc_dev *dev); + +#endif /* PMC_H */ diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 081e84e116e7..3fc5e4547d9f 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, data, sizeof(*data)); } +int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) +{ + struct os_power_slider args; + struct acpi_buffer params; + union acpi_object *info; + int err = 0; + + args.size = sizeof(args); + args.slider_event = event; + + params.length = sizeof(args); + params.pointer = (void *)&args; + + info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, ¶ms); + if (!info) + err = -EIO; + + kfree(info); + return err; +} + static void apmf_sbios_heartbeat_notify(struct work_struct *work) { struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work); @@ -289,7 +310,7 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) ret = apmf_get_system_params(pmf_dev); if (ret) { - dev_err(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); + dev_dbg(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); goto out; } diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 7780705917b7..57bf1a9f0e76 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -40,6 +40,7 @@ /* List of supported CPU ids */ #define AMD_CPU_ID_RMB 0x14b5 #define AMD_CPU_ID_PS 0x14e8 +#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 #define PMF_MSG_DELAY_MIN_US 50 #define RESPONSE_REGISTER_LOOP_MAX 20000 @@ -71,7 +72,11 @@ static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long return NOTIFY_DONE; } - amd_pmf_set_sps_power_limits(pmf); + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) + amd_pmf_set_sps_power_limits(pmf); + + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) + amd_pmf_power_slider_update_event(pmf); return NOTIFY_OK; } @@ -242,6 +247,7 @@ out_unlock: static const struct pci_device_id pmf_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RMB) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { } }; @@ -295,7 +301,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev) int ret; /* Enable Static Slider */ - if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || + is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { amd_pmf_init_sps(dev); dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; power_supply_reg_notifier(&dev->pwr_src_notifier); @@ -333,6 +340,7 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) static const struct acpi_device_id amd_pmf_acpi_ids[] = { {"AMDI0100", 0x100}, {"AMDI0102", 0}, + {"AMDI0103", 0}, { } }; MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 06c30cdc0573..deba88e6e4c8 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -21,6 +21,7 @@ #define APMF_FUNC_SBIOS_HEARTBEAT 4 #define APMF_FUNC_AUTO_MODE 5 #define APMF_FUNC_SET_FAN_IDX 7 +#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8 #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 #define APMF_FUNC_DYN_SLIDER_AC 11 #define APMF_FUNC_DYN_SLIDER_DC 12 @@ -44,6 +45,14 @@ #define GET_STT_LIMIT_APU 0x20 #define GET_STT_LIMIT_HS2 0x21 +/* OS slider update notification */ +#define DC_BEST_PERF 0 +#define DC_BETTER_PERF 1 +#define DC_BATTERY_SAVER 3 +#define AC_BEST_PERF 4 +#define AC_BETTER_PERF 5 +#define AC_BETTER_BATTERY 6 + /* Fan Index for Auto Mode */ #define FAN_INDEX_AUTO 0xFFFFFFFF @@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular { struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX][POWER_MODE_MAX]; }; +struct os_power_slider { + u16 size; + u8 slider_event; +} __packed; + struct fan_table_control { bool manual; unsigned long fan_id; @@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev); int amd_pmf_get_power_source(void); int apmf_install_handler(struct amd_pmf_dev *pmf_dev); +int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); /* SPS Layer */ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); @@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, struct apmf_static_slider_granular_output *output); bool is_pprof_balanced(struct amd_pmf_dev *pmf); +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev); int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index 445ff053b4df..a70e67749be3 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -174,14 +174,78 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) return mode; } +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) +{ + u8 flag = 0; + int mode; + int src; + + mode = amd_pmf_get_pprof_modes(dev); + if (mode < 0) + return mode; + + src = amd_pmf_get_power_source(); + + if (src == POWER_SOURCE_AC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(AC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(AC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(AC_BETTER_BATTERY); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + + } else if (src == POWER_SOURCE_DC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(DC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(DC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(DC_BATTERY_SAVER); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + } + + apmf_os_power_slider_update(dev, flag); + + return 0; +} + static int amd_pmf_profile_set(struct platform_profile_handler *pprof, enum platform_profile_option profile) { struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); + int ret = 0; pmf->current_profile = profile; - return amd_pmf_set_sps_power_limits(pmf); + /* Notify EC about the slider position change */ + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { + ret = amd_pmf_power_slider_update_event(pmf); + if (ret) + return ret; + } + + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + ret = amd_pmf_set_sps_power_limits(pmf); + if (ret) + return ret; + } + + return 0; } int amd_pmf_init_sps(struct amd_pmf_dev *dev) @@ -189,10 +253,13 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) int err; dev->current_profile = PLATFORM_PROFILE_BALANCED; - amd_pmf_load_defaults_sps(dev); - /* update SPS balanced power mode thermals */ - amd_pmf_set_sps_power_limits(dev); + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + amd_pmf_load_defaults_sps(dev); + + /* update SPS balanced power mode thermals */ + amd_pmf_set_sps_power_limits(dev); + } dev->pprof.profile_get = amd_pmf_profile_get; dev->pprof.profile_set = amd_pmf_profile_set; diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index e861e569e37e..9783893d2d6e 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -854,13 +854,23 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - u32 cmd, mode, r, g, b, speed; + u32 cmd, mode, r, g, b, speed; int err; if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) return -EINVAL; - cmd = !!cmd; + /* B3 is set and B4 is save to BIOS */ + switch (cmd) { + case 0: + cmd = 0xb3; + break; + case 1: + cmd = 0xb4; + break; + default: + return -EINVAL; + } /* These are the known usable modes across all TUF/ROG */ if (mode >= 12 || mode == 9) diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c index 2750dee99c3e..db1e9240dd02 100644 --- a/drivers/platform/x86/dell/dell-wmi-ddv.c +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c @@ -616,7 +616,8 @@ static int dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data *data) } if (index < 2) { - ret = -ENODEV; + /* Finding no available sensors is not an error */ + ret = 0; goto err_release; } @@ -841,13 +842,13 @@ static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context) if (IS_REACHABLE(CONFIG_ACPI_BATTERY)) { ret = dell_wmi_ddv_battery_add(data); - if (ret < 0 && ret != -ENODEV) + if (ret < 0) dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret); } if (IS_REACHABLE(CONFIG_HWMON)) { ret = dell_wmi_ddv_hwmon_add(data); - if (ret < 0 && ret != -ENODEV) + if (ret < 0) dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret); } diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 70e5c4c0574d..0ef1c46b617b 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -85,6 +85,8 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, + // Ignore Ambient Light Sensoring + { KE_KEY, 0x2c1, { KEY_RESERVED } }, { KE_END, 0 } }; diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index d2fee9a3e239..6d9297c1d96c 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -1049,6 +1049,11 @@ static const struct key_entry ideapad_keymap[] = { { KE_IGNORE, 0x03 | IDEAPAD_WMI_KEY }, /* Customizable Lenovo Hotkey ("star" with 'S' inside) */ { KE_KEY, 0x01 | IDEAPAD_WMI_KEY, { KEY_FAVORITES } }, + { KE_KEY, 0x04 | IDEAPAD_WMI_KEY, { KEY_SELECTIVE_SCREENSHOT } }, + /* Lenovo Support */ + { KE_KEY, 0x07 | IDEAPAD_WMI_KEY, { KEY_HELP } }, + { KE_KEY, 0x0e | IDEAPAD_WMI_KEY, { KEY_PICKUP_PHONE } }, + { KE_KEY, 0x0f | IDEAPAD_WMI_KEY, { KEY_HANGUP_PHONE } }, /* Dark mode toggle */ { KE_KEY, 0x13 | IDEAPAD_WMI_KEY, { KEY_PROG1 } }, /* Sound profile switch */ diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 5632bd3c534a..7457ca2b27a6 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -150,6 +150,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), + }, + }, { } }; @@ -620,7 +626,7 @@ static bool button_array_present(struct platform_device *device) static int intel_hid_probe(struct platform_device *device) { acpi_handle handle = ACPI_HANDLE(&device->dev); - unsigned long long mode; + unsigned long long mode, dummy; struct intel_hid_priv *priv; acpi_status status; int err; @@ -692,18 +698,15 @@ static int intel_hid_probe(struct platform_device *device) if (err) goto err_remove_notify; - if (priv->array) { - unsigned long long dummy; + intel_button_array_enable(&device->dev, true); - intel_button_array_enable(&device->dev, true); - - /* Call button load method to enable HID power button */ - if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, - &dummy)) { - dev_warn(&device->dev, - "failed to enable HID power button\n"); - } - } + /* + * Call button load method to enable HID power button + * Always do this since it activates events on some devices without + * a button array too. + */ + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) + dev_warn(&device->dev, "failed to enable HID power button\n"); device_init_wakeup(&device->dev, true); /* diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c index 61aeca804ba2..ef4b3141efcd 100644 --- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c +++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c @@ -260,7 +260,7 @@ static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) == * This DMI table contains the name of the second sensor. This is used to add * entries for the second sensor to the supply_map. */ -const struct dmi_system_id skl_int3472_regulator_second_sensor[] = { +static const struct dmi_system_id skl_int3472_regulator_second_sensor[] = { { /* Lenovo Miix 510-12IKB */ .matches = { diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c index 1f59ac55c5f7..a95004e3d80b 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c @@ -335,8 +335,8 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn node = dev_to_node(&_pci_dev->dev); if (node == NUMA_NO_NODE) { - pr_info("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n", - cpu, bus_no, dev, fn); + pr_info_once("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n", + cpu, bus_no, dev, fn); continue; } diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index c205a5c8b9db..0a95736d97e4 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -723,9 +723,7 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) if (!pfs_start) pfs_start = res_start; - pfs->pfs_header.cap_offset *= TPMI_CAP_OFFSET_UNIT; - - pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset; + pfs->vsec_offset = pfs_start + pfs->pfs_header.cap_offset * TPMI_CAP_OFFSET_UNIT; /* * Process TPMI_INFO to get PCI device to CPU package ID. diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c index 41676188b373..e1fbc35504d4 100644 --- a/drivers/platform/x86/lenovo-ymc.c +++ b/drivers/platform/x86/lenovo-ymc.c @@ -24,6 +24,10 @@ static bool ec_trigger __read_mostly; module_param(ec_trigger, bool, 0444); MODULE_PARM_DESC(ec_trigger, "Enable EC triggering work-around to force emitting tablet mode events"); +static bool force; +module_param(force, bool, 0444); +MODULE_PARM_DESC(force, "Force loading on boards without a convertible DMI chassis-type"); + static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = { { /* Lenovo Yoga 7 14ARB7 */ @@ -32,6 +36,27 @@ static const struct dmi_system_id ec_trigger_quirk_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), }, }, + { + /* Lenovo Yoga 7 14ACN6 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82N7"), + }, + }, + { } +}; + +static const struct dmi_system_id allowed_chasis_types_dmi_table[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */), + }, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */), + }, + }, { } }; @@ -111,6 +136,13 @@ static int lenovo_ymc_probe(struct wmi_device *wdev, const void *ctx) struct input_dev *input_dev; int err; + if (!dmi_check_system(allowed_chasis_types_dmi_table)) { + if (force) + dev_info(&wdev->dev, "Force loading Lenovo YMC support\n"); + else + return -ENODEV; + } + ec_trigger |= dmi_check_system(ec_trigger_quirk_dmi_table); priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c index 67367f010139..7d33977d9c60 100644 --- a/drivers/platform/x86/mlx-platform.c +++ b/drivers/platform/x86/mlx-platform.c @@ -62,10 +62,6 @@ #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b -#define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0x3c -#define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0x3d -#define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0x3e -#define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0x3f #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET 0x42 @@ -126,6 +122,10 @@ #define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET 0xaa #define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET 0xab #define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON 0xb2 +#define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0xb6 +#define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0xb7 +#define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0xb8 +#define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0xb9 #define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET 0xc2 #define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT 0xc3 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7 @@ -222,7 +222,7 @@ MLXPLAT_CPLD_AGGR_MASK_LC_SDWN) #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1 #define MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2 BIT(2) -#define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT BIT(4) +#define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT GENMASK(5, 4) #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C BIT(6) #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0) #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0) @@ -237,7 +237,7 @@ #define MLXPLAT_CPLD_GWP_MASK GENMASK(0, 0) #define MLXPLAT_CPLD_EROT_MASK GENMASK(1, 0) #define MLXPLAT_CPLD_PWR_BUTTON_MASK BIT(0) -#define MLXPLAT_CPLD_LATCH_RST_MASK BIT(5) +#define MLXPLAT_CPLD_LATCH_RST_MASK BIT(6) #define MLXPLAT_CPLD_THERMAL1_PDB_MASK BIT(3) #define MLXPLAT_CPLD_THERMAL2_PDB_MASK BIT(4) #define MLXPLAT_CPLD_INTRUSION_MASK BIT(6) @@ -2356,7 +2356,7 @@ mlxplat_mlxcpld_l1_switch_pwr_events_handler(void *handle, enum mlxreg_hotplug_k u8 action) { dev_info(&mlxplat_dev->dev, "System shutdown due to short press of power button"); - kernel_halt(); + kernel_power_off(); return 0; } @@ -2475,7 +2475,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = { .reg = MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET, .mask = MLXPLAT_CPLD_PWR_BUTTON_MASK, .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_pwr_events_items_data), - .inversed = 0, + .inversed = 1, .health = false, }, { @@ -2484,7 +2484,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = { .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET, .mask = MLXPLAT_CPLD_L1_CHA_HEALTH_MASK, .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_health_events_items_data), - .inversed = 0, + .inversed = 1, .health = false, .ind = 8, }, @@ -3677,7 +3677,7 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { { .label = "latch_reset", .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, - .mask = GENMASK(7, 0) & ~BIT(5), + .mask = GENMASK(7, 0) & ~BIT(6), .mode = 0200, }, { @@ -6238,8 +6238,6 @@ static void mlxplat_i2c_mux_topolgy_exit(struct mlxplat_priv *priv) if (priv->pdev_mux[i]) platform_device_unregister(priv->pdev_mux[i]); } - - mlxplat_post_exit(); } static int mlxplat_i2c_main_complition_notify(void *handle, int id) @@ -6369,6 +6367,7 @@ static void __exit mlxplat_exit(void) pm_power_off = NULL; mlxplat_pre_exit(priv); mlxplat_i2c_main_exit(priv); + mlxplat_post_exit(); } module_exit(mlxplat_exit); diff --git a/drivers/platform/x86/msi-ec.c b/drivers/platform/x86/msi-ec.c index ff93986e3d35..f26a3121092f 100644 --- a/drivers/platform/x86/msi-ec.c +++ b/drivers/platform/x86/msi-ec.c @@ -27,15 +27,15 @@ #include <linux/seq_file.h> #include <linux/string.h> -static const char *const SM_ECO_NAME = "eco"; -static const char *const SM_COMFORT_NAME = "comfort"; -static const char *const SM_SPORT_NAME = "sport"; -static const char *const SM_TURBO_NAME = "turbo"; - -static const char *const FM_AUTO_NAME = "auto"; -static const char *const FM_SILENT_NAME = "silent"; -static const char *const FM_BASIC_NAME = "basic"; -static const char *const FM_ADVANCED_NAME = "advanced"; +#define SM_ECO_NAME "eco" +#define SM_COMFORT_NAME "comfort" +#define SM_SPORT_NAME "sport" +#define SM_TURBO_NAME "turbo" + +#define FM_AUTO_NAME "auto" +#define FM_SILENT_NAME "silent" +#define FM_BASIC_NAME "basic" +#define FM_ADVANCED_NAME "advanced" static const char * const ALLOWED_FW_0[] __initconst = { "14C1EMS1.012", diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 6b18ec543ac3..f4c6c36e05a5 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -208,7 +208,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask) return -EINVAL; if (quirks->ec_read_only) - return -EOPNOTSUPP; + return 0; /* read current device state */ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); @@ -838,15 +838,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, static void msi_init_rfkill(struct work_struct *ignored) { if (rfk_wlan) { - rfkill_set_sw_state(rfk_wlan, !wlan_s); + msi_rfkill_set_state(rfk_wlan, !wlan_s); rfkill_wlan_set(NULL, !wlan_s); } if (rfk_bluetooth) { - rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); + msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); rfkill_bluetooth_set(NULL, !bluetooth_s); } if (rfk_threeg) { - rfkill_set_sw_state(rfk_threeg, !threeg_s); + msi_rfkill_set_state(rfk_threeg, !threeg_s); rfkill_threeg_set(NULL, !threeg_s); } } diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c index f3dcbdd72fec..8158e3cf5d6d 100644 --- a/drivers/platform/x86/serial-multi-instantiate.c +++ b/drivers/platform/x86/serial-multi-instantiate.c @@ -21,6 +21,7 @@ #define IRQ_RESOURCE_NONE 0 #define IRQ_RESOURCE_GPIO 1 #define IRQ_RESOURCE_APIC 2 +#define IRQ_RESOURCE_AUTO 3 enum smi_bus_type { SMI_I2C, @@ -52,6 +53,18 @@ static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, int ret; switch (inst->flags & IRQ_RESOURCE_TYPE) { + case IRQ_RESOURCE_AUTO: + ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using gpio irq\n"); + break; + } + ret = platform_get_irq(pdev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using platform irq\n"); + break; + } + break; case IRQ_RESOURCE_GPIO: ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); break; @@ -307,10 +320,23 @@ static const struct smi_node int3515_data = { static const struct smi_node cs35l41_hda = { .instances = { - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + {} + }, + .bus_type = SMI_AUTO_DETECT, +}; + +static const struct smi_node cs35l56_hda = { + .instances = { + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, + /* a 5th entry is an alias address, not a real device */ + { "cs35l56-hda_dummy_dev" }, {} }, .bus_type = SMI_AUTO_DETECT, @@ -324,6 +350,7 @@ static const struct acpi_device_id smi_acpi_ids[] = { { "BSG1160", (unsigned long)&bsg1160_data }, { "BSG2150", (unsigned long)&bsg2150_data }, { "CSC3551", (unsigned long)&cs35l41_hda }, + { "CSC3556", (unsigned long)&cs35l56_hda }, { "INT3515", (unsigned long)&int3515_data }, /* Non-conforming _HID for Cirrus Logic already released */ { "CLSA0100", (unsigned long)&cs35l41_hda }, diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 52d1ce8dfe44..79346881cadb 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -719,12 +719,12 @@ static ssize_t cert_to_password_store(struct kobject *kobj, /* Format: 'Password,Signature' */ auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature); if (!auth_str) { - kfree(passwd); + kfree_sensitive(passwd); return -ENOMEM; } ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str); kfree(auth_str); - kfree(passwd); + kfree_sensitive(passwd); return ret ?: count; } diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 34b8b3fb5444..d70c89d32534 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -316,17 +316,12 @@ struct ibm_init_struct { /* DMI Quirks */ struct quirk_entry { bool btusb_bug; - u32 s2idle_bug_mmio; }; static struct quirk_entry quirk_btusb_bug = { .btusb_bug = true, }; -static struct quirk_entry quirk_s2idle_bug = { - .s2idle_bug_mmio = 0xfed80380, -}; - static struct { u32 bluetooth:1; u32 hotkey:1; @@ -4423,136 +4418,9 @@ static const struct dmi_system_id fwbug_list[] __initconst = { DMI_MATCH(DMI_BOARD_NAME, "20MV"), }, }, - { - .ident = "L14 Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), - } - }, - { - .ident = "T14s Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), - } - }, - { - .ident = "X13 Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), - } - }, - { - .ident = "T14 Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), - } - }, - { - .ident = "T14 Gen1 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), - } - }, - { - .ident = "T14 Gen1 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), - } - }, - { - .ident = "T14s Gen1 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), - } - }, - { - .ident = "T14s Gen1 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"), - } - }, - { - .ident = "P14s Gen1 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), - } - }, - { - .ident = "P14s Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), - } - }, - { - .ident = "P14s Gen2 AMD", - .driver_data = &quirk_s2idle_bug, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), - } - }, {} }; -#ifdef CONFIG_SUSPEND -/* - * Lenovo laptops from a variety of generations run a SMI handler during the D3->D0 - * transition that occurs specifically when exiting suspend to idle which can cause - * large delays during resume when the IOMMU translation layer is enabled (the default - * behavior) for NVME devices: - * - * To avoid this firmware problem, skip the SMI handler on these machines before the - * D0 transition occurs. - */ -static void thinkpad_acpi_amd_s2idle_restore(void) -{ - struct resource *res; - void __iomem *addr; - u8 val; - - res = request_mem_region_muxed(tp_features.quirks->s2idle_bug_mmio, 1, - "thinkpad_acpi_pm80"); - if (!res) - return; - - addr = ioremap(tp_features.quirks->s2idle_bug_mmio, 1); - if (!addr) - goto cleanup_resource; - - val = ioread8(addr); - iowrite8(val & ~BIT(0), addr); - - iounmap(addr); -cleanup_resource: - release_resource(res); - kfree(res); -} - -static struct acpi_s2idle_dev_ops thinkpad_acpi_s2idle_dev_ops = { - .restore = thinkpad_acpi_amd_s2idle_restore, -}; -#endif - static const struct pci_device_id fwbug_cards_ids[] __initconst = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) }, @@ -11672,10 +11540,6 @@ static void thinkpad_acpi_module_exit(void) tpacpi_lifecycle = TPACPI_LIFE_EXITING; -#ifdef CONFIG_SUSPEND - if (tp_features.quirks && tp_features.quirks->s2idle_bug_mmio) - acpi_unregister_lps0_dev(&thinkpad_acpi_s2idle_dev_ops); -#endif if (tpacpi_hwmon) hwmon_device_unregister(tpacpi_hwmon); if (tp_features.sensors_pdrv_registered) @@ -11865,13 +11729,6 @@ static int __init thinkpad_acpi_module_init(void) tp_features.input_device_registered = 1; } -#ifdef CONFIG_SUSPEND - if (tp_features.quirks && tp_features.quirks->s2idle_bug_mmio) { - if (!acpi_register_lps0_dev(&thinkpad_acpi_s2idle_dev_ops)) - pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", - (dmi_id && dmi_id->ident) ? dmi_id->ident : ""); - } -#endif return 0; } diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index 68e66b60445c..f9301a9382e7 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -26,6 +26,22 @@ struct ts_dmi_data { /* NOTE: Please keep all entries sorted alphabetically */ +static const struct property_entry archos_101_cesium_educ_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"), + { } +}; + +static const struct ts_dmi_data archos_101_cesium_educ_data = { + .acpi_name = "MSSL1680:00", + .properties = archos_101_cesium_educ_props, +}; + static const struct property_entry chuwi_hi8_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 1665), PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), @@ -1048,6 +1064,13 @@ static const struct ts_dmi_data vinga_twizzle_j116_data = { /* NOTE: Please keep this table sorted alphabetically */ const struct dmi_system_id touchscreen_dmi_table[] = { { + /* Archos 101 Cesium Educ */ + .driver_data = (void *)&archos_101_cesium_educ_data, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "ARCHOS 101 Cesium Educ"), + }, + }, + { /* Chuwi Hi8 */ .driver_data = (void *)&chuwi_hi8_data, .matches = { diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 5b95d7aa5c2f..a78ddd83cda0 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -136,6 +136,16 @@ static acpi_status find_guid(const char *guid_string, struct wmi_block **out) return AE_NOT_FOUND; } +static bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + + if (guid_parse(string, &guid_input)) + return false; + + return guid_equal(&guid_input, guid); +} + static const void *find_guid_context(struct wmi_block *wblock, struct wmi_driver *wdriver) { @@ -146,11 +156,7 @@ static const void *find_guid_context(struct wmi_block *wblock, return NULL; while (*id->guid_string) { - guid_t guid_input; - - if (guid_parse(id->guid_string, &guid_input)) - continue; - if (guid_equal(&wblock->gblock.guid, &guid_input)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return id->context; id++; } @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) return 0; while (*id->guid_string) { - guid_t driver_guid; - - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) - continue; - if (guid_equal(&driver_guid, &wblock->gblock.guid)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return 1; id++; @@ -1239,11 +1241,7 @@ static bool guid_already_parsed_for_legacy(struct acpi_device *device, const gui list_for_each_entry(wblock, &wmi_block_list, list) { /* skip warning and register if we know the driver will use struct wmi_driver */ for (int i = 0; allow_duplicates[i] != NULL; i++) { - guid_t tmp; - - if (guid_parse(allow_duplicates[i], &tmp)) - continue; - if (guid_equal(&tmp, guid)) + if (guid_parse_and_compare(allow_duplicates[i], guid)) return false; } if (guid_equal(&wblock->gblock.guid, guid)) { |