diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/chrome/chromeos_laptop.c | 7 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_lpc.c | 36 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_typec.c | 10 | ||||
-rw-r--r-- | drivers/platform/cznic/Kconfig | 2 | ||||
-rw-r--r-- | drivers/platform/cznic/turris-omnia-mcu-trng.c | 4 | ||||
-rw-r--r-- | drivers/platform/olpc/olpc-xo175-ec.c | 4 | ||||
-rw-r--r-- | drivers/platform/x86/acerhdf.c | 33 | ||||
-rw-r--r-- | drivers/platform/x86/amd/pmf/pmf-quirks.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/asus-wmi.c | 10 | ||||
-rw-r--r-- | drivers/platform/x86/dell/dell-smbios-base.c | 5 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/adl.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/cnp.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/core.c | 45 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/core.h | 8 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/icl.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/mtl.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/spt.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/intel/pmc/tgl.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/panasonic-laptop.c | 58 |
19 files changed, 178 insertions, 58 deletions
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index a2cdbfbaeae6..3ab668764383 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -749,10 +749,9 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, if (!src->num_i2c_peripherals) return 0; - i2c_peripherals = kmemdup(src->i2c_peripherals, - src->num_i2c_peripherals * - sizeof(*src->i2c_peripherals), - GFP_KERNEL); + i2c_peripherals = kmemdup_array(src->i2c_peripherals, + src->num_i2c_peripherals, + sizeof(*i2c_peripherals), GFP_KERNEL); if (!i2c_peripherals) return -ENOMEM; diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index f0470248b109..c784119ab5dc 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -631,12 +631,12 @@ static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, cros_ec_lpc_acpi_device_ids); -static const struct lpc_driver_data framework_laptop_amd_lpc_driver_data __initconst = { +static const struct lpc_driver_data framework_laptop_npcx_lpc_driver_data __initconst = { .quirks = CROS_EC_LPC_QUIRK_REMAP_MEMORY, .quirk_mmio_memory_base = 0xE00, }; -static const struct lpc_driver_data framework_laptop_11_lpc_driver_data __initconst = { +static const struct lpc_driver_data framework_laptop_mec_lpc_driver_data __initconst = { .quirks = CROS_EC_LPC_QUIRK_ACPI_ID|CROS_EC_LPC_QUIRK_AML_MUTEX, .quirk_acpi_id = "PNP0C09", .quirk_aml_mutex_name = "ECMT", @@ -696,21 +696,39 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = { }, /* A small number of non-Chromebook/box machines also use the ChromeOS EC */ { - /* the Framework Laptop 13 (AMD Ryzen) and 16 (AMD Ryzen) */ + /* Framework Laptop (11th Gen Intel Core) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMD Ryzen"), - DMI_MATCH(DMI_PRODUCT_FAMILY, "Laptop"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop"), + }, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, + }, + { + /* Framework Laptop (12th Gen Intel Core) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Framework"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "12th Gen Intel Core"), + }, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, + }, + { + /* Framework Laptop (13th Gen Intel Core) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Framework"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "13th Gen Intel Core"), }, - .driver_data = (void *)&framework_laptop_amd_lpc_driver_data, + .driver_data = (void *)&framework_laptop_mec_lpc_driver_data, }, { - /* the Framework Laptop (Intel 11th, 12th, 13th Generation) */ + /* + * All remaining Framework Laptop models (13 AMD Ryzen, 16 AMD + * Ryzen, Intel Core Ultra) + */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Framework"), - DMI_MATCH(DMI_PRODUCT_NAME, "Laptop"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Laptop"), }, - .driver_data = (void *)&framework_laptop_11_lpc_driver_data, + .driver_data = (void *)&framework_laptop_npcx_lpc_driver_data, }, { /* sentinel */ } }; diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 4d305876ec08..c7781aea0b88 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -1285,6 +1285,15 @@ unregister_ports: return ret; } +static void cros_typec_remove(struct platform_device *pdev) +{ + struct cros_typec_data *typec = platform_get_drvdata(pdev); + + cros_usbpd_unregister_notify(&typec->nb); + cancel_work_sync(&typec->port_work); + cros_unregister_ports(typec); +} + static int __maybe_unused cros_typec_suspend(struct device *dev) { struct cros_typec_data *typec = dev_get_drvdata(dev); @@ -1316,6 +1325,7 @@ static struct platform_driver cros_typec_driver = { .pm = &cros_typec_pm_ops, }, .probe = cros_typec_probe, + .remove_new = cros_typec_remove, }; module_platform_driver(cros_typec_driver); diff --git a/drivers/platform/cznic/Kconfig b/drivers/platform/cznic/Kconfig index a111eca8ff57..49c383eb6785 100644 --- a/drivers/platform/cznic/Kconfig +++ b/drivers/platform/cznic/Kconfig @@ -70,7 +70,7 @@ config TURRIS_OMNIA_MCU_TRNG bool "Turris Omnia MCU true random number generator" default y depends on TURRIS_OMNIA_MCU_GPIO - depends on HW_RANDOM + depends on HW_RANDOM=y || HW_RANDOM=TURRIS_OMNIA_MCU help Say Y here to add support for the true random number generator provided by CZ.NIC's Turris Omnia MCU. diff --git a/drivers/platform/cznic/turris-omnia-mcu-trng.c b/drivers/platform/cznic/turris-omnia-mcu-trng.c index ad953fb3c37a..9a1d9292dc9a 100644 --- a/drivers/platform/cznic/turris-omnia-mcu-trng.c +++ b/drivers/platform/cznic/turris-omnia-mcu-trng.c @@ -70,8 +70,8 @@ int omnia_mcu_register_trng(struct omnia_mcu *mcu) irq_idx = omnia_int_to_gpio_idx[__bf_shf(OMNIA_INT_TRNG)]; irq = gpiod_to_irq(gpio_device_get_desc(mcu->gc.gpiodev, irq_idx)); - if (!irq) - return dev_err_probe(dev, -ENXIO, "Cannot get TRNG IRQ\n"); + if (irq < 0) + return dev_err_probe(dev, irq, "Cannot get TRNG IRQ\n"); /* * If someone else cleared the TRNG interrupt but did not read the diff --git a/drivers/platform/olpc/olpc-xo175-ec.c b/drivers/platform/olpc/olpc-xo175-ec.c index 62ccbcb15c74..fa7b3bda688a 100644 --- a/drivers/platform/olpc/olpc-xo175-ec.c +++ b/drivers/platform/olpc/olpc-xo175-ec.c @@ -536,7 +536,7 @@ static int olpc_xo175_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *resp, dev_err(dev, "EC cmd error: timeout in STATE %d\n", priv->cmd_state); gpiod_set_value_cansleep(priv->gpio_cmd, 0); - spi_slave_abort(priv->spi); + spi_target_abort(priv->spi); olpc_xo175_ec_read_packet(priv); return -ETIMEDOUT; } @@ -653,7 +653,7 @@ static void olpc_xo175_ec_remove(struct spi_device *spi) if (pm_power_off == olpc_xo175_ec_power_off) pm_power_off = NULL; - spi_slave_abort(spi); + spi_target_abort(spi); platform_device_unregister(olpc_ec); olpc_ec = NULL; diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 018c48429616..4c3bb68e8fe4 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -378,33 +378,13 @@ static int acerhdf_get_ec_temp(struct thermal_zone_device *thermal, int *t) return 0; } -static int acerhdf_bind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) +static bool acerhdf_should_bind(struct thermal_zone_device *thermal, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev, + struct cooling_spec *c) { /* if the cooling device is the one from acerhdf bind it */ - if (cdev != cl_dev) - return 0; - - if (thermal_zone_bind_cooling_device(thermal, 0, cdev, - THERMAL_NO_LIMIT, THERMAL_NO_LIMIT, - THERMAL_WEIGHT_DEFAULT)) { - pr_err("error binding cooling dev\n"); - return -EINVAL; - } - return 0; -} - -static int acerhdf_unbind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) -{ - if (cdev != cl_dev) - return 0; - - if (thermal_zone_unbind_cooling_device(thermal, 0, cdev)) { - pr_err("error unbinding cooling dev\n"); - return -EINVAL; - } - return 0; + return cdev == cl_dev && trip->type == THERMAL_TRIP_ACTIVE; } static inline void acerhdf_revert_to_bios_mode(void) @@ -447,8 +427,7 @@ static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal, /* bind callback functions to thermalzone */ static struct thermal_zone_device_ops acerhdf_dev_ops = { - .bind = acerhdf_bind, - .unbind = acerhdf_unbind, + .should_bind = acerhdf_should_bind, .get_temp = acerhdf_get_ec_temp, .change_mode = acerhdf_change_mode, .get_crit_temp = acerhdf_get_crit_temp, diff --git a/drivers/platform/x86/amd/pmf/pmf-quirks.c b/drivers/platform/x86/amd/pmf/pmf-quirks.c index 6ee219a81537..7cde5733b9ca 100644 --- a/drivers/platform/x86/amd/pmf/pmf-quirks.c +++ b/drivers/platform/x86/amd/pmf/pmf-quirks.c @@ -25,7 +25,7 @@ static const struct dmi_system_id fwbug_list[] = { .ident = "ROG Zephyrus G14", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA403UV"), + DMI_MATCH(DMI_PRODUCT_NAME, "GA403U"), }, .driver_data = &quirk_no_sps_bug, }, diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 6ae282088408..7a48220b4f5a 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1826,6 +1826,16 @@ static int asus_wmi_led_init(struct asus_wmi *asus) goto error; } + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE)) { + /* + * Disable OOBE state, so that e.g. the keyboard backlight + * works. + */ + rv = asus_wmi_set_devstate(ASUS_WMI_DEVID_OOBE, 1, NULL); + if (rv) + goto error; + } + error: if (rv) asus_wmi_led_exit(asus); diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c index 6565fac24cde..73e41eb69cb5 100644 --- a/drivers/platform/x86/dell/dell-smbios-base.c +++ b/drivers/platform/x86/dell/dell-smbios-base.c @@ -622,7 +622,10 @@ static int __init dell_smbios_init(void) return 0; fail_sysfs: - free_group(platform_device); + if (!wmi) + exit_dell_smbios_wmi(); + if (!smm) + exit_dell_smbios_smm(); fail_create_group: platform_device_del(platform_device); diff --git a/drivers/platform/x86/intel/pmc/adl.c b/drivers/platform/x86/intel/pmc/adl.c index e7878558fd90..9d9c07f44ff6 100644 --- a/drivers/platform/x86/intel/pmc/adl.c +++ b/drivers/platform/x86/intel/pmc/adl.c @@ -295,6 +295,8 @@ const struct pmc_reg_map adl_reg_map = { .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, .lpm_num_modes = ADL_LPM_NUM_MODES, .lpm_num_maps = ADL_LPM_NUM_MAPS, diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c index dd72974bf71e..513c02670c5a 100644 --- a/drivers/platform/x86/intel/pmc/cnp.c +++ b/drivers/platform/x86/intel/pmc/cnp.c @@ -200,6 +200,8 @@ const struct pmc_reg_map cnp_reg_map = { .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, .etr3_offset = ETR3_OFFSET, }; diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index d6c0f88f8c7b..ecb47f8b4f83 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -11,6 +11,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/acpi_pmtmr.h> #include <linux/bitfield.h> #include <linux/debugfs.h> #include <linux/delay.h> @@ -1257,6 +1258,38 @@ static bool pmc_core_is_pson_residency_enabled(struct pmc_dev *pmcdev) return val == 1; } +/* + * Enable or disable ACPI PM Timer + * + * This function is intended to be a callback for ACPI PM suspend/resume event. + * The ACPI PM Timer is enabled on resume only if it was enabled during suspend. + */ +static void pmc_core_acpi_pm_timer_suspend_resume(void *data, bool suspend) +{ + struct pmc_dev *pmcdev = data; + struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; + const struct pmc_reg_map *map = pmc->map; + bool enabled; + u32 reg; + + if (!map->acpi_pm_tmr_ctl_offset) + return; + + guard(mutex)(&pmcdev->lock); + + if (!suspend && !pmcdev->enable_acpi_pm_timer_on_resume) + return; + + reg = pmc_core_reg_read(pmc, map->acpi_pm_tmr_ctl_offset); + enabled = !(reg & map->acpi_pm_tmr_disable_bit); + if (suspend) + reg |= map->acpi_pm_tmr_disable_bit; + else + reg &= ~map->acpi_pm_tmr_disable_bit; + pmc_core_reg_write(pmc, map->acpi_pm_tmr_ctl_offset, reg); + + pmcdev->enable_acpi_pm_timer_on_resume = suspend && enabled; +} static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) { @@ -1453,6 +1486,7 @@ static int pmc_core_probe(struct platform_device *pdev) struct pmc_dev *pmcdev; const struct x86_cpu_id *cpu_id; int (*core_init)(struct pmc_dev *pmcdev); + const struct pmc_reg_map *map; struct pmc *primary_pmc; int ret; @@ -1511,6 +1545,11 @@ static int pmc_core_probe(struct platform_device *pdev) pm_report_max_hw_sleep(FIELD_MAX(SLP_S0_RES_COUNTER_MASK) * pmc_core_adjust_slp_s0_step(primary_pmc, 1)); + map = primary_pmc->map; + if (map->acpi_pm_tmr_ctl_offset) + acpi_pmtmr_register_suspend_resume_callback(pmc_core_acpi_pm_timer_suspend_resume, + pmcdev); + device_initialized = true; dev_info(&pdev->dev, " initialized\n"); @@ -1520,6 +1559,12 @@ static int pmc_core_probe(struct platform_device *pdev) static void pmc_core_remove(struct platform_device *pdev) { struct pmc_dev *pmcdev = platform_get_drvdata(pdev); + const struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; + const struct pmc_reg_map *map = pmc->map; + + if (map->acpi_pm_tmr_ctl_offset) + acpi_pmtmr_unregister_suspend_resume_callback(); + pmc_core_dbgfs_unregister(pmcdev); pmc_core_clean_structure(pdev); } diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index b9d3291d0bf2..75fd593a7b0f 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -68,6 +68,8 @@ struct telem_endpoint; #define SPT_PMC_LTR_SCC 0x3A0 #define SPT_PMC_LTR_ISH 0x3A4 +#define SPT_PMC_ACPI_PM_TMR_CTL_OFFSET 0x18FC + /* Sunrise Point: PGD PFET Enable Ack Status Registers */ enum ppfear_regs { SPT_PMC_XRAM_PPFEAR0A = 0x590, @@ -148,6 +150,8 @@ enum ppfear_regs { #define SPT_PMC_VRIC1_SLPS0LVEN BIT(13) #define SPT_PMC_VRIC1_XTALSDQDIS BIT(22) +#define SPT_PMC_BIT_ACPI_PM_TMR_DISABLE BIT(1) + /* Cannonlake Power Management Controller register offsets */ #define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4 #define CNP_PMC_PM_CFG_OFFSET 0x1818 @@ -351,6 +355,8 @@ struct pmc_reg_map { const u8 *lpm_reg_index; const u32 pson_residency_offset; const u32 pson_residency_counter_step; + const u32 acpi_pm_tmr_ctl_offset; + const u32 acpi_pm_tmr_disable_bit; }; /** @@ -426,6 +432,8 @@ struct pmc_dev { u32 die_c6_offset; struct telem_endpoint *punit_ep; struct pmc_info *regmap_list; + + bool enable_acpi_pm_timer_on_resume; }; enum pmc_index { diff --git a/drivers/platform/x86/intel/pmc/icl.c b/drivers/platform/x86/intel/pmc/icl.c index 71b0fd6cb7d8..cbbd44054468 100644 --- a/drivers/platform/x86/intel/pmc/icl.c +++ b/drivers/platform/x86/intel/pmc/icl.c @@ -46,6 +46,8 @@ const struct pmc_reg_map icl_reg_map = { .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, .etr3_offset = ETR3_OFFSET, }; diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index c7d15d864039..91f2fa728f5c 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -462,6 +462,8 @@ const struct pmc_reg_map mtl_socm_reg_map = { .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .lpm_num_maps = ADL_LPM_NUM_MAPS, .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED, .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c index ab993a69e33e..2cd2b3c68e46 100644 --- a/drivers/platform/x86/intel/pmc/spt.c +++ b/drivers/platform/x86/intel/pmc/spt.c @@ -130,6 +130,8 @@ const struct pmc_reg_map spt_reg_map = { .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index e0580de18077..371b4e30f142 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -197,6 +197,8 @@ const struct pmc_reg_map tgl_reg_map = { .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, + .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, + .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, .lpm_num_maps = TGL_LPM_NUM_MAPS, .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 1c88636649a1..2bf94d0ab324 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -349,7 +349,8 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc) } if (pcc->num_sifr < hkey->package.count) { - pr_err("SQTY reports bad SINF length\n"); + pr_err("SQTY reports bad SINF length SQTY: %lu SINF-pkg-count: %u\n", + pcc->num_sifr, hkey->package.count); status = AE_ERROR; goto end; } @@ -785,6 +786,24 @@ static DEVICE_ATTR_RW(dc_brightness); static DEVICE_ATTR_RW(current_brightness); static DEVICE_ATTR_RW(cdpower); +static umode_t pcc_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) +{ + struct device *dev = kobj_to_dev(kobj); + struct acpi_device *acpi = to_acpi_device(dev); + struct pcc_acpi *pcc = acpi_driver_data(acpi); + + if (attr == &dev_attr_mute.attr) + return (pcc->num_sifr > SINF_MUTE) ? attr->mode : 0; + + if (attr == &dev_attr_eco_mode.attr) + return (pcc->num_sifr > SINF_ECO_MODE) ? attr->mode : 0; + + if (attr == &dev_attr_current_brightness.attr) + return (pcc->num_sifr > SINF_CUR_BRIGHT) ? attr->mode : 0; + + return attr->mode; +} + static struct attribute *pcc_sysfs_entries[] = { &dev_attr_numbatt.attr, &dev_attr_lcdtype.attr, @@ -799,8 +818,9 @@ static struct attribute *pcc_sysfs_entries[] = { }; static const struct attribute_group pcc_attr_group = { - .name = NULL, /* put in device directory */ - .attrs = pcc_sysfs_entries, + .name = NULL, /* put in device directory */ + .attrs = pcc_sysfs_entries, + .is_visible = pcc_sysfs_is_visible, }; @@ -953,12 +973,15 @@ static int acpi_pcc_hotkey_resume(struct device *dev) if (!pcc) return -EINVAL; - acpi_pcc_write_sset(pcc, SINF_MUTE, pcc->mute); - acpi_pcc_write_sset(pcc, SINF_ECO_MODE, pcc->eco_mode); + if (pcc->num_sifr > SINF_MUTE) + acpi_pcc_write_sset(pcc, SINF_MUTE, pcc->mute); + if (pcc->num_sifr > SINF_ECO_MODE) + acpi_pcc_write_sset(pcc, SINF_ECO_MODE, pcc->eco_mode); acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_key); acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, pcc->ac_brightness); acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, pcc->dc_brightness); - acpi_pcc_write_sset(pcc, SINF_CUR_BRIGHT, pcc->current_brightness); + if (pcc->num_sifr > SINF_CUR_BRIGHT) + acpi_pcc_write_sset(pcc, SINF_CUR_BRIGHT, pcc->current_brightness); return 0; } @@ -975,11 +998,21 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) num_sifr = acpi_pcc_get_sqty(device); - if (num_sifr < 0 || num_sifr > 255) { - pr_err("num_sifr out of range"); + /* + * pcc->sinf is expected to at least have the AC+DC brightness entries. + * Accesses to higher SINF entries are checked against num_sifr. + */ + if (num_sifr <= SINF_DC_CUR_BRIGHT || num_sifr > 255) { + pr_err("num_sifr %d out of range %d - 255\n", num_sifr, SINF_DC_CUR_BRIGHT + 1); return -ENODEV; } + /* + * Some DSDT-s have an off-by-one bug where the SINF package count is + * one higher than the SQTY reported value, allocate 1 entry extra. + */ + num_sifr++; + pcc = kzalloc(sizeof(struct pcc_acpi), GFP_KERNEL); if (!pcc) { pr_err("Couldn't allocate mem for pcc"); @@ -1032,11 +1065,14 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, 0); pcc->sticky_key = 0; - pcc->eco_mode = pcc->sinf[SINF_ECO_MODE]; - pcc->mute = pcc->sinf[SINF_MUTE]; pcc->ac_brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; pcc->dc_brightness = pcc->sinf[SINF_DC_CUR_BRIGHT]; - pcc->current_brightness = pcc->sinf[SINF_CUR_BRIGHT]; + if (pcc->num_sifr > SINF_MUTE) + pcc->mute = pcc->sinf[SINF_MUTE]; + if (pcc->num_sifr > SINF_ECO_MODE) + pcc->eco_mode = pcc->sinf[SINF_ECO_MODE]; + if (pcc->num_sifr > SINF_CUR_BRIGHT) + pcc->current_brightness = pcc->sinf[SINF_CUR_BRIGHT]; /* add sysfs attributes */ result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group); |