diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-15 16:10:17 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-15 16:10:17 -0800 |
commit | 61f914256c56a39a96dc14eae9f394d35b934812 (patch) | |
tree | d98d26eed780ccd2285f7508047a53db349e9afc /drivers/platform/x86/thinkpad_acpi.c | |
parent | 0f97458173a23c8f218f6041767d0a145a13abe6 (diff) | |
parent | 0cd3f561efa9adce840140720e0581355db3e554 (diff) | |
download | linux-stable-61f914256c56a39a96dc14eae9f394d35b934812.tar.gz linux-stable-61f914256c56a39a96dc14eae9f394d35b934812.tar.bz2 linux-stable-61f914256c56a39a96dc14eae9f394d35b934812.zip |
Merge tag 'platform-drivers-x86-v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform driver updates from Hans de Goede:
"Highlights:
- New driver for changing BIOS settings from within Linux on Dell
devices. This introduces a new generic sysfs API for this. Lenovo
is working on also supporting this API on their devices
- New Intel PMT telemetry and crashlog drivers
- Support for SW_TABLET_MODE reporting for the acer-wmi and intel-hid
drivers
- Preparation work for improving support for Microsoft Surface
hardware
- Various fixes / improvements / quirks for the panasonic-laptop and
others"
* tag 'platform-drivers-x86-v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (81 commits)
platform/x86: ISST: Mark mmio_range_devid_0 and mmio_range_devid_1 with static keyword
platform/x86: intel-hid: add Rocket Lake ACPI device ID
x86/platform: classmate-laptop: add WiFi media button
platform/x86: mlx-platform: Fix item counter assignment for MSN2700/ComEx system
platform/x86: mlx-platform: Fix item counter assignment for MSN2700, MSN24xx systems
tools/power/x86/intel-speed-select: Update version for v5.11
tools/power/x86/intel-speed-select: Account for missing sysfs for die_id
tools/power/x86/intel-speed-select: Read TRL from mailbox
platform/x86: intel-hid: Do not create SW_TABLET_MODE input-dev when a KIOX010A ACPI dev is present
platform/x86: intel-hid: Add alternative method to enable switches
platform/x86: intel-hid: Add support for SW_TABLET_MODE
platform/x86: intel-vbtn: Fix SW_TABLET_MODE always reporting 1 on some HP x360 models
platform/x86: ISST: Change PCI device macros
platform/x86: ISST: Allow configurable offset range
platform/x86: ISST: Check for unaligned mmio address
acer-wireless: send an EV_SYN/SYN_REPORT between state changes
platform/x86: dell-wmi-sysman: work around for BIOS bug
platform/x86: mlx-platform: remove an unused variable
platform/x86: thinkpad_acpi: remove trailing semicolon in macro definition
platform/x86: dell-smbios-base: Fix error return code in dell_smbios_init
...
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 164 |
1 files changed, 104 insertions, 60 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c404706379d9..e03df2881dc6 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -1025,7 +1025,7 @@ static struct attribute_set *create_attr_set(unsigned int max_members, } #define destroy_attr_set(_set) \ - kfree(_set); + kfree(_set) /* not multi-threaded safe, use it in a single thread per set */ static int add_to_attr_set(struct attribute_set *s, struct attribute *attr) @@ -4028,6 +4028,7 @@ static bool hotkey_notify_usrevent(const u32 hkey, } static void thermal_dump_all_sensors(void); +static void palmsensor_refresh(void); static bool hotkey_notify_6xxx(const u32 hkey, bool *send_acpi_ev, @@ -4094,8 +4095,8 @@ static bool hotkey_notify_6xxx(const u32 hkey, case TP_HKEY_EV_PALM_DETECTED: case TP_HKEY_EV_PALM_UNDETECTED: - /* palm detected hovering the keyboard, forward to user-space - * via netlink for consumption */ + /* palm detected - pass on to event handler */ + palmsensor_refresh(); return true; default: @@ -9839,102 +9840,146 @@ static struct ibm_struct lcdshadow_driver_data = { }; /************************************************************************* - * DYTC subdriver, for the Lenovo lapmode feature + * Thinkpad sensor interfaces */ #define DYTC_CMD_GET 2 /* To get current IC function and mode */ #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */ -static bool dytc_lapmode; +#define PALMSENSOR_PRESENT_BIT 0 /* Determine if psensor present */ +#define PALMSENSOR_ON_BIT 1 /* psensor status */ -static void dytc_lapmode_notify_change(void) -{ - sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "dytc_lapmode"); -} +static bool has_palmsensor; +static bool has_lapsensor; +static bool palm_state; +static bool lap_state; -static int dytc_command(int command, int *output) +static int lapsensor_get(bool *present, bool *state) { acpi_handle dytc_handle; + int output; - if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DYTC", &dytc_handle))) { - /* Platform doesn't support DYTC */ + *present = false; + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DYTC", &dytc_handle))) return -ENODEV; - } - if (!acpi_evalf(dytc_handle, output, NULL, "dd", command)) + if (!acpi_evalf(dytc_handle, &output, NULL, "dd", DYTC_CMD_GET)) return -EIO; + + *present = true; /*If we get his far, we have lapmode support*/ + *state = output & BIT(DYTC_GET_LAPMODE_BIT) ? true : false; return 0; } -static int dytc_lapmode_get(bool *state) +static int palmsensor_get(bool *present, bool *state) { - int output, err; + acpi_handle psensor_handle; + int output; - err = dytc_command(DYTC_CMD_GET, &output); - if (err) - return err; - *state = output & BIT(DYTC_GET_LAPMODE_BIT) ? true : false; + *present = false; + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GPSS", &psensor_handle))) + return -ENODEV; + if (!acpi_evalf(psensor_handle, &output, NULL, "d")) + return -EIO; + + *present = output & BIT(PALMSENSOR_PRESENT_BIT) ? true : false; + *state = output & BIT(PALMSENSOR_ON_BIT) ? true : false; return 0; } -static void dytc_lapmode_refresh(void) +static void lapsensor_refresh(void) { - bool new_state; + bool state; int err; - err = dytc_lapmode_get(&new_state); - if (err || (new_state == dytc_lapmode)) - return; + if (has_lapsensor) { + err = lapsensor_get(&has_lapsensor, &state); + if (err) + return; + if (lap_state != state) { + lap_state = state; + sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "dytc_lapmode"); + } + } +} - dytc_lapmode = new_state; - dytc_lapmode_notify_change(); +static void palmsensor_refresh(void) +{ + bool state; + int err; + + if (has_palmsensor) { + err = palmsensor_get(&has_palmsensor, &state); + if (err) + return; + if (palm_state != state) { + palm_state = state; + sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "palmsensor"); + } + } } -/* sysfs lapmode entry */ static ssize_t dytc_lapmode_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", dytc_lapmode); + if (has_lapsensor) + return sysfs_emit(buf, "%d\n", lap_state); + return sysfs_emit(buf, "\n"); } - static DEVICE_ATTR_RO(dytc_lapmode); -static struct attribute *dytc_attributes[] = { - &dev_attr_dytc_lapmode.attr, - NULL, -}; - -static const struct attribute_group dytc_attr_group = { - .attrs = dytc_attributes, -}; +static ssize_t palmsensor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (has_palmsensor) + return sysfs_emit(buf, "%d\n", palm_state); + return sysfs_emit(buf, "\n"); +} +static DEVICE_ATTR_RO(palmsensor); -static int tpacpi_dytc_init(struct ibm_init_struct *iibm) +static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) { - int err; + int palm_err, lap_err, err; - err = dytc_lapmode_get(&dytc_lapmode); - /* If support isn't available (ENODEV) then don't return an error - * but just don't create the sysfs group + palm_err = palmsensor_get(&has_palmsensor, &palm_state); + lap_err = lapsensor_get(&has_lapsensor, &lap_state); + /* + * If support isn't available (ENODEV) for both devices then quit, but + * don't return an error. */ - if (err == -ENODEV) + if ((palm_err == -ENODEV) && (lap_err == -ENODEV)) return 0; - /* For all other errors we can flag the failure */ - if (err) - return err; - - /* Platform supports this feature - create the group */ - err = sysfs_create_group(&tpacpi_pdev->dev.kobj, &dytc_attr_group); - return err; + /* Otherwise, if there was an error return it */ + if (palm_err && (palm_err != ENODEV)) + return palm_err; + if (lap_err && (lap_err != ENODEV)) + return lap_err; + + if (has_palmsensor) { + err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_palmsensor.attr); + if (err) + return err; + } + if (has_lapsensor) { + err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); + if (err) + return err; + } + return 0; } -static void dytc_exit(void) +static void proxsensor_exit(void) { - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &dytc_attr_group); + if (has_lapsensor) + sysfs_remove_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); + if (has_palmsensor) + sysfs_remove_file(&tpacpi_pdev->dev.kobj, &dev_attr_palmsensor.attr); } -static struct ibm_struct dytc_driver_data = { - .name = "dytc", - .exit = dytc_exit, +static struct ibm_struct proxsensor_driver_data = { + .name = "proximity-sensor", + .exit = proxsensor_exit, }; /**************************************************************************** @@ -9986,8 +10031,7 @@ static void tpacpi_driver_event(const unsigned int hkey_event) } if (hkey_event == TP_HKEY_EV_THM_CSM_COMPLETED) - dytc_lapmode_refresh(); - + lapsensor_refresh(); } static void hotkey_driver_event(const unsigned int scancode) @@ -10427,8 +10471,8 @@ static struct ibm_init_struct ibms_init[] __initdata = { .data = &lcdshadow_driver_data, }, { - .init = tpacpi_dytc_init, - .data = &dytc_driver_data, + .init = tpacpi_proxsensor_init, + .data = &proxsensor_driver_data, }, }; |