Commit ad062195 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'platform-drivers-x86-v5.4-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform-drivers updates from Andy Shevchenko:

 - ASUS WMI driver got a couple of updates, i.e. support of FAN is fixed
   for recent products and the charge threshold support has been added

 - Two uknown key events for Dell laptops are being ignored now to avoid
   spamming users with harmless messages

 - HP ZBook 17 G5 and ASUS Zenbook UX430UNR got accelerometer support.

 - Intel CherryTrail platforms had a regression with wake up. Now it's
   fixed

 - Intel PMC driver got fixed in order to work nicely in Xen
   environment

 - Intel Speed Select driver provides bucket vs core count relationship.
   Besides that the tools has been updated for better output

 - The PrivacyGuard is enabled on Lenovo ThinkPad laptops

 - Three tablets - Trekstor Primebook C11B 2-in-1, Irbis TW90 and Chuwi
   Surbook Mini - got touchscreen support

* tag 'platform-drivers-x86-v5.4-1' of git://git.infradead.org/linux-platform-drivers-x86: (53 commits)
  MAINTAINERS: Switch PDx86 subsystem status to Odd Fixes
  platform/x86: asus-wmi: Refactor charge threshold to use the battery hooking API
  platform/x86: asus-wmi: Rename CHARGE_THRESHOLD to RSOC
  platform/x86: asus-wmi: Reorder ASUS_WMI_CHARGE_THRESHOLD
  tools/power/x86/intel-speed-select: Display core count for bucket
  platform/x86: ISST: Allow additional TRL MSRs
  tools/power/x86/intel-speed-select: Fix memory leak
  tools/power/x86/intel-speed-select: Output success/failed for command output
  tools/power/x86/intel-speed-select: Output human readable CPU list
  tools/power/x86/intel-speed-select: Change turbo ratio output to maximum turbo frequency
  tools/power/x86/intel-speed-select: Switch output to MHz
  tools/power/x86/intel-speed-select: Simplify output for turbo-freq and base-freq
  tools/power/x86/intel-speed-select: Fix cpu-count output
  tools/power/x86/intel-speed-select: Fix help option typo
  tools/power/x86/intel-speed-select: Fix package typo
  tools/power/x86/intel-speed-select: Fix a read overflow in isst_set_tdp_level_msr()
  platform/x86: intel_int0002_vgpio: Use device_init_wakeup
  platform/x86: intel_int0002_vgpio: Fix wakeups not working on Cherry Trail
  platform/x86: compal-laptop: Initialize "value" in ec_read_u8()
  platform/x86: touchscreen_dmi: Add info for the Trekstor Primebook C11B 2-in-1
  ...
parents 7ac63f6b f690790c
......@@ -49,6 +49,7 @@ detailed description):
- Fan control and monitoring: fan speed, fan enable/disable
- WAN enable and disable
- UWB enable and disable
- LCD Shadow (PrivacyGuard) enable and disable
A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
......@@ -1409,6 +1410,28 @@ Sysfs notes
Documentation/driver-api/rfkill.rst for details.
LCD Shadow control
------------------
procfs: /proc/acpi/ibm/lcdshadow
Some newer T480s and T490s ThinkPads provide a feature called
PrivacyGuard. By turning this feature on, the usable vertical and
horizontal viewing angles of the LCD can be limited (as if some privacy
screen was applied manually in front of the display).
procfs notes
^^^^^^^^^^^^
The available commands are::
echo '0' >/proc/acpi/ibm/lcdshadow
echo '1' >/proc/acpi/ibm/lcdshadow
The first command ensures the best viewing angle and the latter one turns
on the feature, restricting the viewing angles.
EXPERIMENTAL: UWB
-----------------
......
......@@ -17512,7 +17512,7 @@ M: Darren Hart <dvhart@infradead.org>
M: Andy Shevchenko <andy@infradead.org>
L: platform-driver-x86@vger.kernel.org
T: git git://git.infradead.org/linux-platform-drivers-x86.git
S: Maintained
S: Odd Fixes
F: drivers/platform/x86/
F: drivers/platform/olpc/
......
......@@ -642,11 +642,8 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
priv->irq = pdata->irq;
} else {
priv->irq = platform_get_irq(pdev, 0);
if (priv->irq < 0) {
dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
priv->irq);
if (priv->irq < 0)
return priv->irq;
}
}
priv->regmap = pdata->regmap;
......
......@@ -1881,52 +1881,17 @@ static int __init acer_wmi_enable_rf_button(void)
return status;
}
#define ACER_WMID_ACCEL_HID "BST0001"
static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
void *ctx, void **retval)
{
struct acpi_device *dev;
if (!strcmp(ctx, "SENR")) {
if (acpi_bus_get_device(ah, &dev))
return AE_OK;
if (strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev)))
return AE_OK;
} else
return AE_OK;
*(acpi_handle *)retval = ah;
return AE_CTRL_TERMINATE;
}
static int __init acer_wmi_get_handle(const char *name, const char *prop,
acpi_handle *ah)
{
acpi_status status;
acpi_handle handle;
BUG_ON(!name || !ah);
handle = NULL;
status = acpi_get_devices(prop, acer_wmi_get_handle_cb,
(void *)name, &handle);
if (ACPI_SUCCESS(status) && handle) {
*ah = handle;
return 0;
} else {
return -ENODEV;
}
}
static int __init acer_wmi_accel_setup(void)
{
struct acpi_device *adev;
int err;
err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle);
if (err)
return err;
adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
if (!adev)
return -ENODEV;
gsensor_handle = acpi_device_handle(adev);
acpi_dev_put(adev);
interface->capability |= ACER_CAP_ACCEL;
......
......@@ -402,6 +402,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_asus_forceals,
},
{
.callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. UX430UNR",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"),
},
.driver_data = &quirk_asus_forceals,
},
{},
};
......
This diff is collapsed.
......@@ -226,7 +226,7 @@ static const unsigned char pwm_lookup_table[256] = {
/* General access */
static u8 ec_read_u8(u8 addr)
{
u8 value;
u8 value = 0;
ec_read(addr, &value);
return value;
}
......
......@@ -311,11 +311,13 @@ static const struct key_entry dell_wmi_keymap_type_0011[] = {
{ KE_IGNORE, 0xfff1, { KEY_RESERVED } },
/* Keyboard backlight level changed */
{ KE_IGNORE, 0x01e1, { KEY_RESERVED } },
{ KE_IGNORE, 0x02ea, { KEY_RESERVED } },
{ KE_IGNORE, 0x02eb, { KEY_RESERVED } },
{ KE_IGNORE, 0x02ec, { KEY_RESERVED } },
{ KE_IGNORE, 0x02f6, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_OFF_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_ON_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_AUTO_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_AUTO_25_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_AUTO_50_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_AUTO_75_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, KBD_LED_AUTO_100_TOKEN, { KEY_RESERVED } },
};
static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
......
......@@ -240,6 +240,7 @@ static const struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap),
AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted),
AXIS_DMI_MATCH("HPZBook17G5", "HP ZBook 17 G5", x_inverted),
AXIS_DMI_MATCH("HPZBook17", "HP ZBook 17", xy_swap_yz_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
......
......@@ -81,9 +81,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
multi = devm_kmalloc(dev,
offsetof(struct i2c_multi_inst_data, clients[ret]),
GFP_KERNEL);
multi = devm_kmalloc(dev, struct_size(multi, clients, ret), GFP_KERNEL);
if (!multi)
return -ENOMEM;
......
......@@ -60,11 +60,8 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
wctmu->regmap = pmic->regmap;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "invalid irq %d\n", irq);
if (irq < 0)
return irq;
}
regmap_irq_chip = pmic->irq_chip_data_tmu;
virq = regmap_irq_get_virq(regmap_irq_chip, irq);
......
......@@ -122,7 +122,7 @@ static irqreturn_t int0002_irq(int irq, void *data)
generic_handle_irq(irq_find_mapping(chip->irq.domain,
GPE0A_PME_B0_VIRT_GPIO_PIN));
pm_system_wakeup();
pm_wakeup_hard_event(chip->parent);
return IRQ_HANDLED;
}
......@@ -144,6 +144,7 @@ static struct irq_chip int0002_cht_irqchip = {
* No set_wake, on CHT the IRQ is typically shared with the ACPI SCI
* and we don't want to mess with the ACPI SCI irq settings.
*/
.flags = IRQCHIP_SKIP_SET_WAKE,
};
static const struct x86_cpu_id int0002_cpu_ids[] = {
......@@ -173,10 +174,8 @@ static int int0002_probe(struct platform_device *pdev)
return -ENODEV;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "Error getting IRQ: %d\n", irq);
if (irq < 0)
return irq;
}
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
......@@ -221,6 +220,13 @@ static int int0002_probe(struct platform_device *pdev)
gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL);
device_init_wakeup(dev, true);
return 0;
}
static int int0002_remove(struct platform_device *pdev)
{
device_init_wakeup(&pdev->dev, false);
return 0;
}
......@@ -236,6 +242,7 @@ static struct platform_driver int0002_driver = {
.acpi_match_table = int0002_acpi_ids,
},
.probe = int0002_probe,
.remove = int0002_remove,
};
module_platform_driver(int0002_driver);
......
......@@ -878,10 +878,14 @@ static int pmc_core_probe(struct platform_device *pdev)
if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids))
pmcdev->map = &cnp_reg_map;
if (lpit_read_residency_count_address(&slp_s0_addr))
if (lpit_read_residency_count_address(&slp_s0_addr)) {
pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT;
else
if (page_is_ram(PHYS_PFN(pmcdev->base_addr)))
return -ENODEV;
} else {
pmcdev->base_addr = slp_s0_addr - pmcdev->map->slp_s0_offset;
}
pmcdev->regbase = ioremap(pmcdev->base_addr,
pmcdev->map->regmap_length);
......
......@@ -18,8 +18,16 @@
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
static void intel_pmc_core_release(struct device *dev)
{
/* Nothing to do. */
}
static struct platform_device pmc_core_device = {
.name = "intel_pmc_core",
.dev = {
.release = intel_pmc_core_release,
},
};
/*
......
......@@ -936,10 +936,8 @@ static int ipc_plat_probe(struct platform_device *pdev)
spin_lock_init(&ipcdev.gcr_lock);
ipcdev.irq = platform_get_irq(pdev, 0);
if (ipcdev.irq < 0) {
dev_err(&pdev->dev, "Failed to get irq\n");
if (ipcdev.irq < 0)
return -EINVAL;
}
ret = ipc_plat_get_res(pdev);
if (ret) {
......
......@@ -29,6 +29,8 @@ static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];
static int punit_msr_white_list[] = {
MSR_TURBO_RATIO_LIMIT,
MSR_CONFIG_TDP_CONTROL,
MSR_TURBO_RATIO_LIMIT1,
MSR_TURBO_RATIO_LIMIT2,
};
struct isst_valid_cmd_ranges {
......
......@@ -132,11 +132,9 @@ static void isst_if_remove(struct pci_dev *pdev)
static int __maybe_unused isst_if_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct isst_if_device *punit_dev;
struct isst_if_device *punit_dev = dev_get_drvdata(device);
int i;
punit_dev = pci_get_drvdata(pdev);
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
punit_dev->range_0[i] = readl(punit_dev->punit_mmio +
mmio_range[0].beg + 4 * i);
......@@ -149,11 +147,9 @@ static int __maybe_unused isst_if_suspend(struct device *device)
static int __maybe_unused isst_if_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct isst_if_device *punit_dev;
struct isst_if_device *punit_dev = dev_get_drvdata(device);
int i;
punit_dev = pci_get_drvdata(pdev);
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
writel(punit_dev->range_0[i], punit_dev->punit_mmio +
mmio_range[0].beg + 4 * i);
......
......@@ -32,6 +32,8 @@
#define APU2_GPIO_REG_LED3 AMD_FCH_GPIO_REG_GPIO59_DEVSLP1
#define APU2_GPIO_REG_MODESW AMD_FCH_GPIO_REG_GPIO32_GE1
#define APU2_GPIO_REG_SIMSWAP AMD_FCH_GPIO_REG_GPIO33_GE2
#define APU2_GPIO_REG_MPCIE2 AMD_FCH_GPIO_REG_GPIO59_DEVSLP0
#define APU2_GPIO_REG_MPCIE3 AMD_FCH_GPIO_REG_GPIO51
/* order in which the gpio lines are defined in the register list */
#define APU2_GPIO_LINE_LED1 0
......@@ -39,6 +41,8 @@
#define APU2_GPIO_LINE_LED3 2
#define APU2_GPIO_LINE_MODESW 3
#define APU2_GPIO_LINE_SIMSWAP 4
#define APU2_GPIO_LINE_MPCIE2 5
#define APU2_GPIO_LINE_MPCIE3 6
/* gpio device */
......@@ -48,6 +52,8 @@ static int apu2_gpio_regs[] = {
[APU2_GPIO_LINE_LED3] = APU2_GPIO_REG_LED3,
[APU2_GPIO_LINE_MODESW] = APU2_GPIO_REG_MODESW,
[APU2_GPIO_LINE_SIMSWAP] = APU2_GPIO_REG_SIMSWAP,
[APU2_GPIO_LINE_MPCIE2] = APU2_GPIO_REG_MPCIE2,
[APU2_GPIO_LINE_MPCIE3] = APU2_GPIO_REG_MPCIE3,
};
static const char * const apu2_gpio_names[] = {
......@@ -56,6 +62,8 @@ static const char * const apu2_gpio_names[] = {
[APU2_GPIO_LINE_LED3] = "front-led3",
[APU2_GPIO_LINE_MODESW] = "front-button",
[APU2_GPIO_LINE_SIMSWAP] = "simswap",
[APU2_GPIO_LINE_MPCIE2] = "mpcie2_reset",
[APU2_GPIO_LINE_MPCIE3] = "mpcie3_reset",
};
static const struct amd_fch_gpio_pdata board_apu2 = {
......@@ -69,7 +77,8 @@ static const struct amd_fch_gpio_pdata board_apu2 = {
static const struct gpio_led apu2_leds[] = {
{ .name = "apu:green:1" },
{ .name = "apu:green:2" },
{ .name = "apu:green:3" }
{ .name = "apu:green:3" },
{ .name = "apu:simswap" },
};
static const struct gpio_led_platform_data apu2_leds_pdata = {
......@@ -86,6 +95,8 @@ static struct gpiod_lookup_table gpios_led_table = {
NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3,
NULL, 2, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_REG_SIMSWAP,
NULL, 3, GPIO_ACTIVE_LOW),
}
};
......
......@@ -415,6 +415,13 @@ static const struct dmi_system_id critclk_systems[] = {
DMI_MATCH(DMI_BOARD_NAME, "CB6363"),
},
},
{
.ident = "SIMATIC IPC227E",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
DMI_MATCH(DMI_PRODUCT_VERSION, "6ES7647-8B"),
},
},
{ /*sentinel*/ }
};
......
......@@ -3647,22 +3647,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit;
/* Set up key map */
hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
GFP_KERNEL);
if (!hotkey_keycode_map) {
pr_err("failed to allocate memory for key map\n");
res = -ENOMEM;
goto err_exit;
}
keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
ARRAY_SIZE(tpacpi_keymap_qtable));
BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using keymap number %lu\n", keymap_id);
memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
TPACPI_HOTKEY_MAP_SIZE);
hotkey_keycode_map = kmemdup(&tpacpi_keymaps[keymap_id],
TPACPI_HOTKEY_MAP_SIZE, GFP_KERNEL);
if (!hotkey_keycode_map) {
pr_err("failed to allocate memory for key map\n");
res = -ENOMEM;
goto err_exit;
}
input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
......@@ -9714,6 +9711,107 @@ static struct ibm_struct battery_driver_data = {
.exit = tpacpi_battery_exit,
};
/*************************************************************************
* LCD Shadow subdriver, for the Lenovo PrivacyGuard feature
*/
static int lcdshadow_state;
static int lcdshadow_on_off(bool state)
{
acpi_handle set_shadow_handle;
int output;
if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSSS", &set_shadow_handle))) {
pr_warn("Thinkpad ACPI has no %s interface.\n", "SSSS");
return -EIO;
}
if (!acpi_evalf(set_shadow_handle, &output, NULL, "dd", (int)state))
return -EIO;
lcdshadow_state = state;
return 0;
}
static int lcdshadow_set(bool on)
{
if (lcdshadow_state < 0)
return lcdshadow_state;
if (lcdshadow_state == on)
return 0;
return lcdshadow_on_off(on);
}
static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm)
{
acpi_handle get_shadow_handle;
int output;
if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSSS", &get_shadow_handle))) {
lcdshadow_state = -ENODEV;
return 0;
}
if (!acpi_evalf(get_shadow_handle, &output, NULL, "dd", 0)) {
lcdshadow_state = -EIO;
return -EIO;
}
if (!(output & 0x10000)) {
lcdshadow_state = -ENODEV;
return 0;
}
lcdshadow_state = output & 0x1;
return 0;
}
static void lcdshadow_resume(void)
{
if (lcdshadow_state >= 0)
lcdshadow_on_off(lcdshadow_state);
}
static int lcdshadow_read(struct seq_file *m)
{
if (lcdshadow_state < 0) {
seq_puts(m, "status:\t\tnot supported\n");
} else {
seq_printf(m, "status:\t\t%d\n", lcdshadow_state);
seq_puts(m, "commands:\t0, 1\n");
}
return 0;
}
static int lcdshadow_write(char *buf)
{
char *cmd;
int state = -1;
if (lcdshadow_state < 0)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "0") == 0)
state = 0;
else if (strlencmp(cmd, "1") == 0)
state = 1;
}
if (state == -1)
return -EINVAL;
return lcdshadow_set(state);
}
static struct ibm_struct lcdshadow_driver_data = {
.name = "lcdshadow",
.resume = lcdshadow_resume,
.read = lcdshadow_read,
.write = lcdshadow_write,
};
/****************************************************************************
****************************************************************************
*
......@@ -10195,6 +10293,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
.init = tpacpi_battery_init,
.data = &battery_driver_data,
},
{
.init = tpacpi_lcdshadow_init,
.data = &lcdshadow_driver_data,
},
};
static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment