History

Merge branch 'fixes' into for-next

Resolve conflicts in dell/alienware-wmi-wmax and asus-wmi, and enable applying a few amd/hsmp patches that depend on changes in the fixes branch.

Ilpo Järvinen committed 1 year ago

Commit 593ee932 parents f94ffc3 bfcfe6d25 files · +366 −113Browse files

Unified · Split

25 files
  1. Documentation/wmi/devices/msi-wmi-platform.rst +4 −0
  2. drivers/platform/mellanox/mlxbf-bootctl.c +2 −2
  3. drivers/platform/x86/amd/hsmp/acpi.c +1 −2
  4. drivers/platform/x86/amd/hsmp/hsmp.h +1 −0
  5. drivers/platform/x86/amd/hsmp/plat.c +5 −1
  6. drivers/platform/x86/amd/pmc/pmc-quirks.c +7 −0
  7. drivers/platform/x86/amd/pmc/pmc.c +3 −4
  8. drivers/platform/x86/amd/pmf/auto-mode.c +2 −2
  9. drivers/platform/x86/amd/pmf/cnqf.c +4 −4
  10. drivers/platform/x86/amd/pmf/core.c +14 −0
  11. drivers/platform/x86/amd/pmf/pmf.h +1 −0
  12. drivers/platform/x86/amd/pmf/sps.c +8 −4
  13. drivers/platform/x86/amd/pmf/tee-if.c +26 −3
  14. drivers/platform/x86/asus-laptop.c +6 −3
  15. drivers/platform/x86/asus-wmi.c +12 −2
  16. drivers/platform/x86/dell/alienware-wmi-wmax.c +58 −2
  17. drivers/platform/x86/ideapad-laptop.c +16 −0
  18. drivers/platform/x86/intel/hid.c +11 −10
  19. drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +9 −4
  20. drivers/platform/x86/msi-wmi-platform.c +63 −36
  21. drivers/platform/x86/thinkpad_acpi.c +2 −0
  22. drivers/platform/x86/x86-android-tablets/dmi.c +13 −1
  23. drivers/platform/x86/x86-android-tablets/other.c +92 −32
  24. drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +2 −1
  25. include/linux/platform_data/x86/intel_pmc_ipc.h +4 −0
Documentation/wmi/devices/msi-wmi-platform.rst+4−0
@@ -138,6 +138,10 @@ input data, the meaning of which depends on the subfeature being accessed. · 137 unmodified lines
138The output buffer contains a single byte which signals success or failure (``0x00`` on failure)138The output buffer contains a single byte which signals success or failure (``0x00`` on failure)
139and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.139and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.
140 140
141.. note::
142 The ACPI control method responsible for handling the WMI method calls is not thread-safe.
143 This is a firmware bug that needs to be handled inside the driver itself.
144
141WMI method Get_EC()145WMI method Get_EC()
142-------------------146-------------------
143 147
drivers/platform/mellanox/mlxbf-bootctl.c+2−2
@@ -333,9 +333,9 @@ static ssize_t secure_boot_fuse_state_show(struct device *dev, · 332 unmodified lines
333 else333 else
334 status = valid ? "Invalid" : "Free";334 status = valid ? "Invalid" : "Free";
335 }335 }
336 buf_len += sysfs_emit(buf + buf_len, "%d:%s ", key, status);336 buf_len += sysfs_emit_at(buf, buf_len, "%d:%s ", key, status);
337 }337 }
338 buf_len += sysfs_emit(buf + buf_len, "\n");338 buf_len += sysfs_emit_at(buf, buf_len, "\n");
339 339
340 return buf_len;340 return buf_len;
341}341}
drivers/platform/x86/amd/hsmp/acpi.c+1−2
@@ -27,9 +27,8 @@ · 26 unmodified lines
27 27
28#include "hsmp.h"28#include "hsmp.h"
29 29
30#define DRIVER_NAME "amd_hsmp"30#define DRIVER_NAME "hsmp_acpi"
31#define DRIVER_VERSION "2.3"31#define DRIVER_VERSION "2.3"
32#define ACPI_HSMP_DEVICE_HID "AMDI0097"
33 32
34/* These are the strings specified in ACPI table */33/* These are the strings specified in ACPI table */
35#define MSG_IDOFF_STR "MsgIdOffset"34#define MSG_IDOFF_STR "MsgIdOffset"
drivers/platform/x86/amd/hsmp/hsmp.h+1−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
23 23
24#define HSMP_CDEV_NAME "hsmp_cdev"24#define HSMP_CDEV_NAME "hsmp_cdev"
25#define HSMP_DEVNODE_NAME "hsmp"25#define HSMP_DEVNODE_NAME "hsmp"
26#define ACPI_HSMP_DEVICE_HID "AMDI0097"
26 27
27struct hsmp_mbaddr_info {28struct hsmp_mbaddr_info {
28 u32 base_addr;29 u32 base_addr;
drivers/platform/x86/amd/hsmp/plat.c+5−1
@@ -11,6 +11,7 @@ · 10 unmodified lines
11 11
12#include <asm/amd_hsmp.h>12#include <asm/amd_hsmp.h>
13 13
14#include <linux/acpi.h>
14#include <linux/build_bug.h>15#include <linux/build_bug.h>
15#include <linux/device.h>16#include <linux/device.h>
16#include <linux/module.h>17#include <linux/module.h>
@@ -266,7 +267,7 @@ static bool legacy_hsmp_support(void) · 249 unmodified lines
266 }267 }
267 case 0x1A:268 case 0x1A:
268 switch (boot_cpu_data.x86_model) {269 switch (boot_cpu_data.x86_model) {
269 case 0x00 ... 0x1F:270 case 0x00 ... 0x0F:
270 return true;271 return true;
271 default:272 default:
272 return false;273 return false;
@@ -288,6 +289,9 @@ static int __init hsmp_plt_init(void) · 15 unmodified lines
288 return ret;289 return ret;
289 }290 }
290 291
292 if (acpi_dev_present(ACPI_HSMP_DEVICE_HID, NULL, -1))
293 return -ENODEV;
294
291 hsmp_pdev = get_hsmp_pdev();295 hsmp_pdev = get_hsmp_pdev();
292 if (!hsmp_pdev)296 if (!hsmp_pdev)
293 return -ENOMEM;297 return -ENOMEM;
drivers/platform/x86/amd/pmc/pmc-quirks.c+7−0
@@ -217,6 +217,13 @@ static const struct dmi_system_id fwbug_list[] = { · 216 unmodified lines
217 DMI_MATCH(DMI_BIOS_VERSION, "03.05"),217 DMI_MATCH(DMI_BIOS_VERSION, "03.05"),
218 }218 }
219 },219 },
220 {
221 .ident = "MECHREVO Wujie 14X (GX4HRXL)",
222 .driver_data = &quirk_spurious_8042,
223 .matches = {
224 DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"),
225 }
226 },
220 {}227 {}
221};228};
222 229
drivers/platform/x86/amd/pmc/pmc.c+3−4
@@ -644,10 +644,9 @@ static void amd_pmc_s2idle_check(void) · 643 unmodified lines
644 struct smu_metrics table;644 struct smu_metrics table;
645 int rc;645 int rc;
646 646
647 /* CZN: Ensure that future s0i3 entry attempts at least 10ms passed */647 /* Avoid triggering OVP */
648 if (pdev->cpu_id == AMD_CPU_ID_CZN && !get_metrics_table(pdev, &table) &&648 if (!get_metrics_table(pdev, &table) && table.s0i3_last_entry_status)
649 table.s0i3_last_entry_status)649 msleep(2500);
650 usleep_range(10000, 20000);
651 650
652 /* Dump the IdleMask before we add to the STB */651 /* Dump the IdleMask before we add to the STB */
653 amd_pmc_idlemask_read(pdev, pdev->dev, NULL);652 amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
drivers/platform/x86/amd/pmf/auto-mode.c+2−2
@@ -120,9 +120,9 @@ static void amd_pmf_set_automode(struct amd_pmf_dev *dev, int idx, · 119 unmodified lines
120 amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pwr_ctrl->sppt_apu_only, NULL);120 amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pwr_ctrl->sppt_apu_only, NULL);
121 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pwr_ctrl->stt_min, NULL);121 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pwr_ctrl->stt_min, NULL);
122 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,122 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
123 pwr_ctrl->stt_skin_temp[STT_TEMP_APU], NULL);123 fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_APU]), NULL);
124 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,124 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
125 pwr_ctrl->stt_skin_temp[STT_TEMP_HS2], NULL);125 fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_HS2]), NULL);
126 126
127 if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))127 if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
128 apmf_update_fan_idx(dev, config_store.mode_set[idx].fan_control.manual,128 apmf_update_fan_idx(dev, config_store.mode_set[idx].fan_control.manual,
drivers/platform/x86/amd/pmf/cnqf.c+4−4
@@ -81,10 +81,10 @@ static int amd_pmf_set_cnqf(struct amd_pmf_dev *dev, int src, int idx, · 80 unmodified lines
81 amd_pmf_send_cmd(dev, SET_SPPT, false, pc->sppt, NULL);81 amd_pmf_send_cmd(dev, SET_SPPT, false, pc->sppt, NULL);
82 amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pc->sppt_apu_only, NULL);82 amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pc->sppt_apu_only, NULL);
83 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pc->stt_min, NULL);83 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pc->stt_min, NULL);
84 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, pc->stt_skin_temp[STT_TEMP_APU],84 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
85 NULL);85 fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_APU]), NULL);
86 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, pc->stt_skin_temp[STT_TEMP_HS2],86 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
87 NULL);87 fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_HS2]), NULL);
88 88
89 if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))89 if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
90 apmf_update_fan_idx(dev,90 apmf_update_fan_idx(dev,
drivers/platform/x86/amd/pmf/core.c+14−0
@@ -176,6 +176,20 @@ static void __maybe_unused amd_pmf_dump_registers(struct amd_pmf_dev *dev) · 175 unmodified lines
176 dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value);176 dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value);
177}177}
178 178
179/**
180 * fixp_q88_fromint: Convert integer to Q8.8
181 * @val: input value
182 *
183 * Converts an integer into binary fixed point format where 8 bits
184 * are used for integer and 8 bits are used for the decimal.
185 *
186 * Return: unsigned integer converted to Q8.8 format
187 */
188u32 fixp_q88_fromint(u32 val)
189{
190 return val << 8;
191}
192
179int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data)193int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data)
180{194{
181 int rc;195 int rc;
drivers/platform/x86/amd/pmf/pmf.h+1−0
@@ -777,6 +777,7 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev); · 776 unmodified lines
777int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);777int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
778int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer);778int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer);
779int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag);779int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag);
780u32 fixp_q88_fromint(u32 val);
780 781
781/* SPS Layer */782/* SPS Layer */
782int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);783int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
drivers/platform/x86/amd/pmf/sps.c+8−4
@@ -198,9 +198,11 @@ static void amd_pmf_update_slider_v2(struct amd_pmf_dev *dev, int idx) · 197 unmodified lines
198 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,198 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
199 apts_config_store.val[idx].stt_min_limit, NULL);199 apts_config_store.val[idx].stt_min_limit, NULL);
200 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,200 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
201 apts_config_store.val[idx].stt_skin_temp_limit_apu, NULL);201 fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_apu),
202 NULL);
202 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,203 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
203 apts_config_store.val[idx].stt_skin_temp_limit_hs2, NULL);204 fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_hs2),
205 NULL);
204}206}
205 207
206void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,208void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
@@ -217,9 +219,11 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, · 10 unmodified lines
217 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,219 amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
218 config_store.prop[src][idx].stt_min, NULL);220 config_store.prop[src][idx].stt_min, NULL);
219 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,221 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
220 config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU], NULL);222 fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU]),
223 NULL);
221 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,224 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
222 config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2], NULL);225 fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2]),
226 NULL);
223 } else if (op == SLIDER_OP_GET) {227 } else if (op == SLIDER_OP_GET) {
224 amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl);228 amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl);
225 amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt);229 amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt);
drivers/platform/x86/amd/pmf/tee-if.c+26−3
@@ -123,7 +123,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_ · 122 unmodified lines
123 123
124 case PMF_POLICY_STT_SKINTEMP_APU:124 case PMF_POLICY_STT_SKINTEMP_APU:
125 if (dev->prev_data->stt_skintemp_apu != val) {125 if (dev->prev_data->stt_skintemp_apu != val) {
126 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, val, NULL);126 amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
127 fixp_q88_fromint(val), NULL);
127 dev_dbg(dev->dev, "update STT_SKINTEMP_APU: %u\n", val);128 dev_dbg(dev->dev, "update STT_SKINTEMP_APU: %u\n", val);
128 dev->prev_data->stt_skintemp_apu = val;129 dev->prev_data->stt_skintemp_apu = val;
129 }130 }
@@ -131,7 +132,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_ · 1 unmodified line
131 132
132 case PMF_POLICY_STT_SKINTEMP_HS2:133 case PMF_POLICY_STT_SKINTEMP_HS2:
133 if (dev->prev_data->stt_skintemp_hs2 != val) {134 if (dev->prev_data->stt_skintemp_hs2 != val) {
134 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, val, NULL);135 amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
136 fixp_q88_fromint(val), NULL);
135 dev_dbg(dev->dev, "update STT_SKINTEMP_HS2: %u\n", val);137 dev_dbg(dev->dev, "update STT_SKINTEMP_HS2: %u\n", val);
136 dev->prev_data->stt_skintemp_hs2 = val;138 dev->prev_data->stt_skintemp_hs2 = val;
137 }139 }
@@ -332,6 +334,11 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev) · 194 unmodified lines
332 return 0;334 return 0;
333}335}
334 336
337static inline bool amd_pmf_pb_valid(struct amd_pmf_dev *dev)
338{
339 return memchr_inv(dev->policy_buf, 0xff, dev->policy_sz);
340}
341
335#ifdef CONFIG_AMD_PMF_DEBUG342#ifdef CONFIG_AMD_PMF_DEBUG
336static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)343static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)
337{344{
@@ -359,12 +366,22 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf, · 21 unmodified lines
359 dev->policy_buf = new_policy_buf;366 dev->policy_buf = new_policy_buf;
360 dev->policy_sz = length;367 dev->policy_sz = length;
361 368
369 if (!amd_pmf_pb_valid(dev)) {
370 ret = -EINVAL;
371 goto cleanup;
372 }
373
362 amd_pmf_hex_dump_pb(dev);374 amd_pmf_hex_dump_pb(dev);
363 ret = amd_pmf_start_policy_engine(dev);375 ret = amd_pmf_start_policy_engine(dev);
364 if (ret < 0)376 if (ret < 0)
365 return ret;377 goto cleanup;
366 378
367 return length;379 return length;
380
381cleanup:
382 kfree(dev->policy_buf);
383 dev->policy_buf = NULL;
384 return ret;
368}385}
369 386
370static const struct file_operations pb_fops = {387static const struct file_operations pb_fops = {
@@ -526,6 +543,12 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev) · 155 unmodified lines
526 543
527 memcpy_fromio(dev->policy_buf, dev->policy_base, dev->policy_sz);544 memcpy_fromio(dev->policy_buf, dev->policy_base, dev->policy_sz);
528 545
546 if (!amd_pmf_pb_valid(dev)) {
547 dev_info(dev->dev, "No Smart PC policy present\n");
548 ret = -EINVAL;
549 goto err_free_policy;
550 }
551
529 amd_pmf_hex_dump_pb(dev);552 amd_pmf_hex_dump_pb(dev);
530 553
531 dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL);554 dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL);
drivers/platform/x86/asus-laptop.c+6−3
@@ -426,11 +426,14 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable) · 425 unmodified lines
426 426
427static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)427static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
428{428{
429 unsigned long long val = (unsigned long long)curr;
430 acpi_status status;
429 int i, delta;431 int i, delta;
430 unsigned long long val;
431 for (i = 0; i < PEGA_ACC_RETRIES; i++) {
432 acpi_evaluate_integer(asus->handle, method, NULL, &val);
433 432
433 for (i = 0; i < PEGA_ACC_RETRIES; i++) {
434 status = acpi_evaluate_integer(asus->handle, method, NULL, &val);
435 if (ACPI_FAILURE(status))
436 continue;
434 /* The output is noisy. From reading the ASL437 /* The output is noisy. From reading the ASL
435 * dissassembly, timeout errors are returned with 1's438 * dissassembly, timeout errors are returned with 1's
436 * in the high word, and the lack of locking around439 * in the high word, and the lack of locking around
drivers/platform/x86/asus-wmi.c+12−2
@@ -305,6 +305,7 @@ struct asus_wmi { · 304 unmodified lines
305 305
306 u32 kbd_rgb_dev;306 u32 kbd_rgb_dev;
307 bool kbd_rgb_state_available;307 bool kbd_rgb_state_available;
308 bool oobe_state_available;
308 309
309 u8 throttle_thermal_policy_mode;310 u8 throttle_thermal_policy_mode;
310 u32 throttle_thermal_policy_dev;311 u32 throttle_thermal_policy_dev;
@@ -1868,7 +1869,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) · 1557 unmodified lines
1868 goto error;1869 goto error;
1869 }1870 }
1870 1871
1871 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE)) {1872 if (asus->oobe_state_available) {
1872 /*1873 /*
1873 * Disable OOBE state, so that e.g. the keyboard backlight1874 * Disable OOBE state, so that e.g. the keyboard backlight
1874 * works.1875 * works.
@@ -4780,6 +4781,7 @@ static int asus_wmi_add(struct platform_device *pdev) · 2905 unmodified lines
4780 asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);4781 asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
4781 asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);4782 asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
4782 asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);4783 asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
4784 asus->oobe_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE);
4783 4785
4784 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))4786 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))
4785 asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;4787 asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
@@ -4832,7 +4834,8 @@ static int asus_wmi_add(struct platform_device *pdev) · 46 unmodified lines
4832 goto fail_leds;4834 goto fail_leds;
4833 4835
4834 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);4836 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
4835 if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))4837 if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
4838 (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
4836 asus->driver->wlan_ctrl_by_user = 1;4839 asus->driver->wlan_ctrl_by_user = 1;
4837 4840
4838 if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {4841 if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
@@ -4997,6 +5000,13 @@ static int asus_hotk_restore(struct device *device) · 158 unmodified lines
4997 }5000 }
4998 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))5001 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
4999 kbd_led_update(asus);5002 kbd_led_update(asus);
5003 if (asus->oobe_state_available) {
5004 /*
5005 * Disable OOBE state, so that e.g. the keyboard backlight
5006 * works.
5007 */
5008 asus_wmi_set_devstate(ASUS_WMI_DEVID_OOBE, 1, NULL);
5009 }
5000 5010
5001 if (asus_wmi_has_fnlock_key(asus))5011 if (asus_wmi_has_fnlock_key(asus))
5002 asus_wmi_fnlock_update(asus);5012 asus_wmi_fnlock_update(asus);
drivers/platform/x86/dell/alienware-wmi-wmax.c+58−2
@@ -89,12 +89,44 @@ static struct awcc_quirks generic_quirks = { · 88 unmodified lines
89static struct awcc_quirks empty_quirks;89static struct awcc_quirks empty_quirks;
90 90
91static const struct dmi_system_id awcc_dmi_table[] __initconst = {91static const struct dmi_system_id awcc_dmi_table[] __initconst = {
92 {
93 .ident = "Alienware Area-51m R2",
94 .matches = {
95 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
96 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"),
97 },
98 .driver_data = &generic_quirks,
99 },
100 {
101 .ident = "Alienware m15 R7",
102 .matches = {
103 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
104 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7"),
105 },
106 .driver_data = &generic_quirks,
107 },
108 {
109 .ident = "Alienware m16 R1",
110 .matches = {
111 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
112 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1"),
113 },
114 .driver_data = &g_series_quirks,
115 },
92 {116 {
93 .ident = "Alienware m16 R1 AMD",117 .ident = "Alienware m16 R1 AMD",
94 .matches = {118 .matches = {
95 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),119 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
96 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),120 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),
97 },121 },
122 .driver_data = &g_series_quirks,
123 },
124 {
125 .ident = "Alienware m16 R2",
126 .matches = {
127 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
128 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R2"),
129 },
98 .driver_data = &generic_quirks,130 .driver_data = &generic_quirks,
99 },131 },
100 {132 {
@@ -121,6 +153,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { · 20 unmodified lines
121 },153 },
122 .driver_data = &generic_quirks,154 .driver_data = &generic_quirks,
123 },155 },
156 {
157 .ident = "Alienware x15 R2",
158 .matches = {
159 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
160 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"),
161 },
162 .driver_data = &generic_quirks,
163 },
124 {164 {
125 .ident = "Alienware x17 R2",165 .ident = "Alienware x17 R2",
126 .matches = {166 .matches = {
@@ -153,6 +193,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { · 26 unmodified lines
153 },193 },
154 .driver_data = &g_series_quirks,194 .driver_data = &g_series_quirks,
155 },195 },
196 {
197 .ident = "Dell Inc. G16 7630",
198 .matches = {
199 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
200 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"),
201 },
202 .driver_data = &g_series_quirks,
203 },
156 {204 {
157 .ident = "Dell Inc. G3 3500",205 .ident = "Dell Inc. G3 3500",
158 .matches = {206 .matches = {
@@ -177,6 +225,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { · 18 unmodified lines
177 },225 },
178 .driver_data = &g_series_quirks,226 .driver_data = &g_series_quirks,
179 },227 },
228 {
229 .ident = "Dell Inc. G5 5505",
230 .matches = {
231 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
232 DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"),
233 },
234 .driver_data = &g_series_quirks,
235 },
180};236};
181 237
182enum AWCC_GET_FAN_SENSORS_OPERATIONS {238enum AWCC_GET_FAN_SENSORS_OPERATIONS {
@@ -1241,14 +1297,14 @@ static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices) · 1058 unmodified lines
1241 1297
1242 for (unsigned int i = 0; i < priv->profile_count; i++) {1298 for (unsigned int i = 0; i < priv->profile_count; i++) {
1243 ret = awcc_op_get_resource_id(priv->wdev, i + offset, &id);1299 ret = awcc_op_get_resource_id(priv->wdev, i + offset, &id);
1244 if (ret == -EIO)
1245 return ret;
1246 /*1300 /*
1247 * Some devices report an incorrect number of thermal profiles1301 * Some devices report an incorrect number of thermal profiles
1248 * so the resource ID list may end prematurely1302 * so the resource ID list may end prematurely
1249 */1303 */
1250 if (ret == -EBADRQC)1304 if (ret == -EBADRQC)
1251 break;1305 break;
1306 if (ret)
1307 return ret;
1252 1308
1253 if (!is_awcc_thermal_profile_id(id)) {1309 if (!is_awcc_thermal_profile_id(id)) {
1254 dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id);1310 dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id);
drivers/platform/x86/ideapad-laptop.c+16−0
@@ -1294,6 +1294,16 @@ static const struct key_entry ideapad_keymap[] = { · 1293 unmodified lines
1294 /* Specific to some newer models */1294 /* Specific to some newer models */
1295 { KE_KEY, 0x3e | IDEAPAD_WMI_KEY, { KEY_MICMUTE } },1295 { KE_KEY, 0x3e | IDEAPAD_WMI_KEY, { KEY_MICMUTE } },
1296 { KE_KEY, 0x3f | IDEAPAD_WMI_KEY, { KEY_RFKILL } },1296 { KE_KEY, 0x3f | IDEAPAD_WMI_KEY, { KEY_RFKILL } },
1297 /* Star- (User Assignable Key) */
1298 { KE_KEY, 0x44 | IDEAPAD_WMI_KEY, { KEY_PROG1 } },
1299 /* Eye */
1300 { KE_KEY, 0x45 | IDEAPAD_WMI_KEY, { KEY_PROG3 } },
1301 /* Performance toggle also Fn+Q, handled inside ideapad_wmi_notify() */
1302 { KE_KEY, 0x3d | IDEAPAD_WMI_KEY, { KEY_PROG4 } },
1303 /* shift + prtsc */
1304 { KE_KEY, 0x2d | IDEAPAD_WMI_KEY, { KEY_CUT } },
1305 { KE_KEY, 0x29 | IDEAPAD_WMI_KEY, { KEY_TOUCHPAD_TOGGLE } },
1306 { KE_KEY, 0x2a | IDEAPAD_WMI_KEY, { KEY_ROOT_MENU } },
1297 1307
1298 { KE_END },1308 { KE_END },
1299};1309};
@@ -2080,6 +2090,12 @@ static void ideapad_wmi_notify(struct wmi_device *wdev, union acpi_object *data) · 780 unmodified lines
2080 dev_dbg(&wdev->dev, "WMI fn-key event: 0x%llx\n",2090 dev_dbg(&wdev->dev, "WMI fn-key event: 0x%llx\n",
2081 data->integer.value);2091 data->integer.value);
2082 2092
2093 /* performance button triggered by 0x3d */
2094 if (data->integer.value == 0x3d && priv->dytc) {
2095 platform_profile_cycle();
2096 break;
2097 }
2098
2083 /* 0x02 FnLock, 0x03 Esc */2099 /* 0x02 FnLock, 0x03 Esc */
2084 if (data->integer.value == 0x02 || data->integer.value == 0x03)2100 if (data->integer.value == 0x02 || data->integer.value == 0x03)
2085 ideapad_fn_lock_led_notify(priv, data->integer.value == 0x02);2101 ideapad_fn_lock_led_notify(priv, data->integer.value == 0x02);
drivers/platform/x86/intel/hid.c+11−10
@@ -44,16 +44,17 @@ MODULE_LICENSE("GPL"); · 43 unmodified lines
44MODULE_AUTHOR("Alex Hung");44MODULE_AUTHOR("Alex Hung");
45 45
46static const struct acpi_device_id intel_hid_ids[] = {46static const struct acpi_device_id intel_hid_ids[] = {
47 {"INT33D5", 0},47 { "INT33D5" },
48 {"INTC1051", 0},48 { "INTC1051" },
49 {"INTC1054", 0},49 { "INTC1054" },
50 {"INTC1070", 0},50 { "INTC1070" },
51 {"INTC1076", 0},51 { "INTC1076" },
52 {"INTC1077", 0},52 { "INTC1077" },
53 {"INTC1078", 0},53 { "INTC1078" },
54 {"INTC107B", 0},54 { "INTC107B" },
55 {"INTC10CB", 0},55 { "INTC10CB" },
56 {"", 0},56 { "INTC10CC" },
57 { }
57};58};
58MODULE_DEVICE_TABLE(acpi, intel_hid_ids);59MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
59 60
drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c+9−4
@@ -146,15 +146,13 @@ static int uncore_event_cpu_online(unsigned int cpu) · 145 unmodified lines
146{146{
147 struct uncore_data *data;147 struct uncore_data *data;
148 int target;148 int target;
149 int ret;
149 150
150 /* Check if there is an online cpu in the package for uncore MSR */151 /* Check if there is an online cpu in the package for uncore MSR */
151 target = cpumask_any_and(&uncore_cpu_mask, topology_die_cpumask(cpu));152 target = cpumask_any_and(&uncore_cpu_mask, topology_die_cpumask(cpu));
152 if (target < nr_cpu_ids)153 if (target < nr_cpu_ids)
153 return 0;154 return 0;
154 155
155 /* Use this CPU on this die as a control CPU */
156 cpumask_set_cpu(cpu, &uncore_cpu_mask);
157
158 data = uncore_get_instance(cpu);156 data = uncore_get_instance(cpu);
159 if (!data)157 if (!data)
160 return 0;158 return 0;
@@ -163,7 +161,14 @@ static int uncore_event_cpu_online(unsigned int cpu) · 2 unmodified lines
163 data->die_id = topology_die_id(cpu);161 data->die_id = topology_die_id(cpu);
164 data->domain_id = UNCORE_DOMAIN_ID_INVALID;162 data->domain_id = UNCORE_DOMAIN_ID_INVALID;
165 163
166 return uncore_freq_add_entry(data, cpu);164 ret = uncore_freq_add_entry(data, cpu);
165 if (ret)
166 return ret;
167
168 /* Use this CPU on this die as a control CPU */
169 cpumask_set_cpu(cpu, &uncore_cpu_mask);
170
171 return 0;
167}172}
168 173
169static int uncore_event_cpu_offline(unsigned int cpu)174static int uncore_event_cpu_offline(unsigned int cpu)
drivers/platform/x86/msi-wmi-platform.c+63−36
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/acpi.h>10#include <linux/acpi.h>
11#include <linux/bits.h>11#include <linux/bits.h>
12#include <linux/bitfield.h>12#include <linux/bitfield.h>
13#include <linux/cleanup.h>
13#include <linux/debugfs.h>14#include <linux/debugfs.h>
14#include <linux/device.h>15#include <linux/device.h>
15#include <linux/device/driver.h>16#include <linux/device/driver.h>
@@ -17,6 +18,7 @@ · 1 unmodified line
17#include <linux/hwmon.h>18#include <linux/hwmon.h>
18#include <linux/kernel.h>19#include <linux/kernel.h>
19#include <linux/module.h>20#include <linux/module.h>
21#include <linux/mutex.h>
20#include <linux/printk.h>22#include <linux/printk.h>
21#include <linux/rwsem.h>23#include <linux/rwsem.h>
22#include <linux/types.h>24#include <linux/types.h>
@@ -76,8 +78,13 @@ enum msi_wmi_platform_method { · 53 unmodified lines
76 MSI_PLATFORM_GET_WMI = 0x1d,78 MSI_PLATFORM_GET_WMI = 0x1d,
77};79};
78 80
79struct msi_wmi_platform_debugfs_data {81struct msi_wmi_platform_data {
80 struct wmi_device *wdev;82 struct wmi_device *wdev;
83 struct mutex wmi_lock; /* Necessary when calling WMI methods */
84};
85
86struct msi_wmi_platform_debugfs_data {
87 struct msi_wmi_platform_data *data;
81 enum msi_wmi_platform_method method;88 enum msi_wmi_platform_method method;
82 struct rw_semaphore buffer_lock; /* Protects debugfs buffer */89 struct rw_semaphore buffer_lock; /* Protects debugfs buffer */
83 size_t length;90 size_t length;
@@ -132,8 +139,9 @@ static int msi_wmi_platform_parse_buffer(union acpi_object *obj, u8 *output, siz · 48 unmodified lines
132 return 0;139 return 0;
133}140}
134 141
135static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform_method method,142static int msi_wmi_platform_query(struct msi_wmi_platform_data *data,
136 u8 *input, size_t input_length, u8 *output, size_t output_length)143 enum msi_wmi_platform_method method, u8 *input,
144 size_t input_length, u8 *output, size_t output_length)
137{145{
138 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };146 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
139 struct acpi_buffer in = {147 struct acpi_buffer in = {
@@ -147,9 +155,15 @@ static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform · 7 unmodified lines
147 if (!input_length || !output_length)155 if (!input_length || !output_length)
148 return -EINVAL;156 return -EINVAL;
149 157
150 status = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);158 /*
151 if (ACPI_FAILURE(status))159 * The ACPI control method responsible for handling the WMI method calls
152 return -EIO;160 * is not thread-safe. Because of this we have to do the locking ourself.
161 */
162 scoped_guard(mutex, &data->wmi_lock) {
163 status = wmidev_evaluate_method(data->wdev, 0x0, method, &in, &out);
164 if (ACPI_FAILURE(status))
165 return -EIO;
166 }
153 167
154 obj = out.pointer;168 obj = out.pointer;
155 if (!obj)169 if (!obj)
@@ -170,22 +184,22 @@ static umode_t msi_wmi_platform_is_visible(const void *drvdata, enum hwmon_senso · 14 unmodified lines
170static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,184static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
171 int channel, long *val)185 int channel, long *val)
172{186{
173 struct wmi_device *wdev = dev_get_drvdata(dev);187 struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
174 u8 input[32] = { 0 };188 u8 input[32] = { 0 };
175 u8 output[32];189 u8 output[32];
176 u16 data;190 u16 value;
177 int ret;191 int ret;
178 192
179 ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,193 ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,
180 sizeof(output));194 sizeof(output));
181 if (ret < 0)195 if (ret < 0)
182 return ret;196 return ret;
183 197
184 data = get_unaligned_be16(&output[channel * 2 + 1]);198 value = get_unaligned_be16(&output[channel * 2 + 1]);
185 if (!data)199 if (!value)
186 *val = 0;200 *val = 0;
187 else201 else
188 *val = 480000 / data;202 *val = 480000 / value;
189 203
190 return 0;204 return 0;
191}205}
@@ -231,7 +245,7 @@ static ssize_t msi_wmi_platform_write(struct file *fp, const char __user *input, · 39 unmodified lines
231 return ret;245 return ret;
232 246
233 down_write(&data->buffer_lock);247 down_write(&data->buffer_lock);
234 ret = msi_wmi_platform_query(data->wdev, data->method, payload, data->length, data->buffer,248 ret = msi_wmi_platform_query(data->data, data->method, payload, data->length, data->buffer,
235 data->length);249 data->length);
236 up_write(&data->buffer_lock);250 up_write(&data->buffer_lock);
237 251
@@ -277,17 +291,17 @@ static void msi_wmi_platform_debugfs_remove(void *data) · 39 unmodified lines
277 debugfs_remove_recursive(dir);291 debugfs_remove_recursive(dir);
278}292}
279 293
280static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry *dir,294static void msi_wmi_platform_debugfs_add(struct msi_wmi_platform_data *drvdata, struct dentry *dir,
281 const char *name, enum msi_wmi_platform_method method)295 const char *name, enum msi_wmi_platform_method method)
282{296{
283 struct msi_wmi_platform_debugfs_data *data;297 struct msi_wmi_platform_debugfs_data *data;
284 struct dentry *entry;298 struct dentry *entry;
285 299
286 data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);300 data = devm_kzalloc(&drvdata->wdev->dev, sizeof(*data), GFP_KERNEL);
287 if (!data)301 if (!data)
288 return;302 return;
289 303
290 data->wdev = wdev;304 data->data = drvdata;
291 data->method = method;305 data->method = method;
292 init_rwsem(&data->buffer_lock);306 init_rwsem(&data->buffer_lock);
293 307
@@ -298,82 +312,82 @@ static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry · 4 unmodified lines
298 312
299 entry = debugfs_create_file(name, 0600, dir, data, &msi_wmi_platform_debugfs_fops);313 entry = debugfs_create_file(name, 0600, dir, data, &msi_wmi_platform_debugfs_fops);
300 if (IS_ERR(entry))314 if (IS_ERR(entry))
301 devm_kfree(&wdev->dev, data);315 devm_kfree(&drvdata->wdev->dev, data);
302}316}
303 317
304static void msi_wmi_platform_debugfs_init(struct wmi_device *wdev)318static void msi_wmi_platform_debugfs_init(struct msi_wmi_platform_data *data)
305{319{
306 struct dentry *dir;320 struct dentry *dir;
307 char dir_name[64];321 char dir_name[64];
308 int ret, method;322 int ret, method;
309 323
310 scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));324 scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&data->wdev->dev));
311 325
312 dir = debugfs_create_dir(dir_name, NULL);326 dir = debugfs_create_dir(dir_name, NULL);
313 if (IS_ERR(dir))327 if (IS_ERR(dir))
314 return;328 return;
315 329
316 ret = devm_add_action_or_reset(&wdev->dev, msi_wmi_platform_debugfs_remove, dir);330 ret = devm_add_action_or_reset(&data->wdev->dev, msi_wmi_platform_debugfs_remove, dir);
317 if (ret < 0)331 if (ret < 0)
318 return;332 return;
319 333
320 for (method = MSI_PLATFORM_GET_PACKAGE; method <= MSI_PLATFORM_GET_WMI; method++)334 for (method = MSI_PLATFORM_GET_PACKAGE; method <= MSI_PLATFORM_GET_WMI; method++)
321 msi_wmi_platform_debugfs_add(wdev, dir, msi_wmi_platform_debugfs_names[method - 1],335 msi_wmi_platform_debugfs_add(data, dir, msi_wmi_platform_debugfs_names[method - 1],
322 method);336 method);
323}337}
324 338
325static int msi_wmi_platform_hwmon_init(struct wmi_device *wdev)339static int msi_wmi_platform_hwmon_init(struct msi_wmi_platform_data *data)
326{340{
327 struct device *hdev;341 struct device *hdev;
328 342
329 hdev = devm_hwmon_device_register_with_info(&wdev->dev, "msi_wmi_platform", wdev,343 hdev = devm_hwmon_device_register_with_info(&data->wdev->dev, "msi_wmi_platform", data,
330 &msi_wmi_platform_chip_info, NULL);344 &msi_wmi_platform_chip_info, NULL);
331 345
332 return PTR_ERR_OR_ZERO(hdev);346 return PTR_ERR_OR_ZERO(hdev);
333}347}
334 348
335static int msi_wmi_platform_ec_init(struct wmi_device *wdev)349static int msi_wmi_platform_ec_init(struct msi_wmi_platform_data *data)
336{350{
337 u8 input[32] = { 0 };351 u8 input[32] = { 0 };
338 u8 output[32];352 u8 output[32];
339 u8 flags;353 u8 flags;
340 int ret;354 int ret;
341 355
342 ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_EC, input, sizeof(input), output,356 ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_EC, input, sizeof(input), output,
343 sizeof(output));357 sizeof(output));
344 if (ret < 0)358 if (ret < 0)
345 return ret;359 return ret;
346 360
347 flags = output[MSI_PLATFORM_EC_FLAGS_OFFSET];361 flags = output[MSI_PLATFORM_EC_FLAGS_OFFSET];
348 362
349 dev_dbg(&wdev->dev, "EC RAM version %lu.%lu\n",363 dev_dbg(&data->wdev->dev, "EC RAM version %lu.%lu\n",
350 FIELD_GET(MSI_PLATFORM_EC_MAJOR_MASK, flags),364 FIELD_GET(MSI_PLATFORM_EC_MAJOR_MASK, flags),
351 FIELD_GET(MSI_PLATFORM_EC_MINOR_MASK, flags));365 FIELD_GET(MSI_PLATFORM_EC_MINOR_MASK, flags));
352 dev_dbg(&wdev->dev, "EC firmware version %.28s\n",366 dev_dbg(&data->wdev->dev, "EC firmware version %.28s\n",
353 &output[MSI_PLATFORM_EC_VERSION_OFFSET]);367 &output[MSI_PLATFORM_EC_VERSION_OFFSET]);
354 368
355 if (!(flags & MSI_PLATFORM_EC_IS_TIGERLAKE)) {369 if (!(flags & MSI_PLATFORM_EC_IS_TIGERLAKE)) {
356 if (!force)370 if (!force)
357 return -ENODEV;371 return -ENODEV;
358 372
359 dev_warn(&wdev->dev, "Loading on a non-Tigerlake platform\n");373 dev_warn(&data->wdev->dev, "Loading on a non-Tigerlake platform\n");
360 }374 }
361 375
362 return 0;376 return 0;
363}377}
364 378
365static int msi_wmi_platform_init(struct wmi_device *wdev)379static int msi_wmi_platform_init(struct msi_wmi_platform_data *data)
366{380{
367 u8 input[32] = { 0 };381 u8 input[32] = { 0 };
368 u8 output[32];382 u8 output[32];
369 int ret;383 int ret;
370 384
371 ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,385 ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,
372 sizeof(output));386 sizeof(output));
373 if (ret < 0)387 if (ret < 0)
374 return ret;388 return ret;
375 389
376 dev_dbg(&wdev->dev, "WMI interface version %u.%u\n",390 dev_dbg(&data->wdev->dev, "WMI interface version %u.%u\n",
377 output[MSI_PLATFORM_WMI_MAJOR_OFFSET],391 output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
378 output[MSI_PLATFORM_WMI_MINOR_OFFSET]);392 output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
379 393
@@ -381,7 +395,8 @@ static int msi_wmi_platform_init(struct wmi_device *wdev) · 1 unmodified line
381 if (!force)395 if (!force)
382 return -ENODEV;396 return -ENODEV;
383 397
384 dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u.%u)\n",398 dev_warn(&data->wdev->dev,
399 "Loading despite unsupported WMI interface version (%u.%u)\n",
385 output[MSI_PLATFORM_WMI_MAJOR_OFFSET],400 output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
386 output[MSI_PLATFORM_WMI_MINOR_OFFSET]);401 output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
387 }402 }
@@ -391,19 +406,31 @@ static int msi_wmi_platform_init(struct wmi_device *wdev) · 3 unmodified lines
391 406
392static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context)407static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context)
393{408{
409 struct msi_wmi_platform_data *data;
394 int ret;410 int ret;
395 411
396 ret = msi_wmi_platform_init(wdev);412 data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
413 if (!data)
414 return -ENOMEM;
415
416 data->wdev = wdev;
417 dev_set_drvdata(&wdev->dev, data);
418
419 ret = devm_mutex_init(&wdev->dev, &data->wmi_lock);
420 if (ret < 0)
421 return ret;
422
423 ret = msi_wmi_platform_init(data);
397 if (ret < 0)424 if (ret < 0)
398 return ret;425 return ret;
399 426
400 ret = msi_wmi_platform_ec_init(wdev);427 ret = msi_wmi_platform_ec_init(data);
401 if (ret < 0)428 if (ret < 0)
402 return ret;429 return ret;
403 430
404 msi_wmi_platform_debugfs_init(wdev);431 msi_wmi_platform_debugfs_init(data);
405 432
406 return msi_wmi_platform_hwmon_init(wdev);433 return msi_wmi_platform_hwmon_init(data);
407}434}
408 435
409static const struct wmi_device_id msi_wmi_platform_id_table[] = {436static const struct wmi_device_id msi_wmi_platform_id_table[] = {
drivers/platform/x86/thinkpad_acpi.c+2−0
@@ -11519,6 +11519,8 @@ static int __must_check __init get_thinkpad_model_data( · 11518 unmodified lines
11519 tp->vendor = PCI_VENDOR_ID_IBM;11519 tp->vendor = PCI_VENDOR_ID_IBM;
11520 else if (dmi_name_in_vendors("LENOVO"))11520 else if (dmi_name_in_vendors("LENOVO"))
11521 tp->vendor = PCI_VENDOR_ID_LENOVO;11521 tp->vendor = PCI_VENDOR_ID_LENOVO;
11522 else if (dmi_name_in_vendors("NEC"))
11523 tp->vendor = PCI_VENDOR_ID_LENOVO;
11522 else11524 else
11523 return 0;11525 return 0;
11524 11526
drivers/platform/x86/x86-android-tablets/dmi.c+13−1
@@ -179,6 +179,18 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { · 178 unmodified lines
179 },179 },
180 .driver_data = (void *)&peaq_c1010_info,180 .driver_data = (void *)&peaq_c1010_info,
181 },181 },
182 {
183 /* Vexia Edu Atla 10 tablet 5V version */
184 .matches = {
185 /* Having all 3 of these not set is somewhat unique */
186 DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
187 DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."),
188 DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."),
189 /* Above strings are too generic, also match on BIOS date */
190 DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"),
191 },
192 .driver_data = (void *)&vexia_edu_atla10_5v_info,
193 },
182 {194 {
183 /* Vexia Edu Atla 10 tablet 9V version */195 /* Vexia Edu Atla 10 tablet 9V version */
184 .matches = {196 .matches = {
@@ -187,7 +199,7 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { · 2 unmodified lines
187 /* Above strings are too generic, also match on BIOS date */199 /* Above strings are too generic, also match on BIOS date */
188 DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),200 DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
189 },201 },
190 .driver_data = (void *)&vexia_edu_atla10_info,202 .driver_data = (void *)&vexia_edu_atla10_9v_info,
191 },203 },
192 {204 {
193 /* Whitelabel (sold as various brands) TM800A550L */205 /* Whitelabel (sold as various brands) TM800A550L */
drivers/platform/x86/x86-android-tablets/other.c+92−32
@@ -599,62 +599,122 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { · 598 unmodified lines
599};599};
600 600
601/*601/*
602 * Vexia EDU ATLA 10 tablet, Android 4.2 / 4.4 + Guadalinex Ubuntu tablet602 * Vexia EDU ATLA 10 tablet 5V, Android 4.4 + Guadalinex Ubuntu tablet
603 * distributed to schools in the Spanish Andalucía region.
604 */
605static const struct property_entry vexia_edu_atla10_5v_touchscreen_props[] = {
606 PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),
607 PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
608 { }
609};
610
611static const struct software_node vexia_edu_atla10_5v_touchscreen_node = {
612 .properties = vexia_edu_atla10_5v_touchscreen_props,
613};
614
615static const struct x86_i2c_client_info vexia_edu_atla10_5v_i2c_clients[] __initconst = {
616 {
617 /* kxcjk1013 accelerometer */
618 .board_info = {
619 .type = "kxcjk1013",
620 .addr = 0x0f,
621 .dev_name = "kxcjk1013",
622 },
623 .adapter_path = "\\_SB_.I2C3",
624 }, {
625 /* touchscreen controller */
626 .board_info = {
627 .type = "hid-over-i2c",
628 .addr = 0x38,
629 .dev_name = "FTSC1000",
630 .swnode = &vexia_edu_atla10_5v_touchscreen_node,
631 },
632 .adapter_path = "\\_SB_.I2C4",
633 .irq_data = {
634 .type = X86_ACPI_IRQ_TYPE_APIC,
635 .index = 0x44,
636 .trigger = ACPI_LEVEL_SENSITIVE,
637 .polarity = ACPI_ACTIVE_HIGH,
638 },
639 }
640};
641
642static struct gpiod_lookup_table vexia_edu_atla10_5v_ft5416_gpios = {
643 .dev_id = "i2c-FTSC1000",
644 .table = {
645 GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW),
646 { }
647 },
648};
649
650static struct gpiod_lookup_table * const vexia_edu_atla10_5v_gpios[] = {
651 &vexia_edu_atla10_5v_ft5416_gpios,
652 NULL
653};
654
655const struct x86_dev_info vexia_edu_atla10_5v_info __initconst = {
656 .i2c_client_info = vexia_edu_atla10_5v_i2c_clients,
657 .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_5v_i2c_clients),
658 .gpiod_lookup_tables = vexia_edu_atla10_5v_gpios,
659};
660
661/*
662 * Vexia EDU ATLA 10 tablet 9V, Android 4.2 + Guadalinex Ubuntu tablet
603 * distributed to schools in the Spanish Andalucía region.663 * distributed to schools in the Spanish Andalucía region.
604 */664 */
605static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };665static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };
606 666
607static const struct property_entry vexia_edu_atla10_ulpmc_props[] = {667static const struct property_entry vexia_edu_atla10_9v_ulpmc_props[] = {
608 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy),668 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy),
609 { }669 { }
610};670};
611 671
612static const struct software_node vexia_edu_atla10_ulpmc_node = {672static const struct software_node vexia_edu_atla10_9v_ulpmc_node = {
613 .properties = vexia_edu_atla10_ulpmc_props,673 .properties = vexia_edu_atla10_9v_ulpmc_props,
614};674};
615 675
616static const char * const vexia_edu_atla10_accel_mount_matrix[] = {676static const char * const vexia_edu_atla10_9v_accel_mount_matrix[] = {
617 "0", "-1", "0",677 "0", "-1", "0",
618 "1", "0", "0",678 "1", "0", "0",
619 "0", "0", "1"679 "0", "0", "1"
620};680};
621 681
622static const struct property_entry vexia_edu_atla10_accel_props[] = {682static const struct property_entry vexia_edu_atla10_9v_accel_props[] = {
623 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_accel_mount_matrix),683 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_9v_accel_mount_matrix),
624 { }684 { }
625};685};
626 686
627static const struct software_node vexia_edu_atla10_accel_node = {687static const struct software_node vexia_edu_atla10_9v_accel_node = {
628 .properties = vexia_edu_atla10_accel_props,688 .properties = vexia_edu_atla10_9v_accel_props,
629};689};
630 690
631static const struct property_entry vexia_edu_atla10_touchscreen_props[] = {691static const struct property_entry vexia_edu_atla10_9v_touchscreen_props[] = {
632 PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),692 PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),
633 PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),693 PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
634 { }694 { }
635};695};
636 696
637static const struct software_node vexia_edu_atla10_touchscreen_node = {697static const struct software_node vexia_edu_atla10_9v_touchscreen_node = {
638 .properties = vexia_edu_atla10_touchscreen_props,698 .properties = vexia_edu_atla10_9v_touchscreen_props,
639};699};
640 700
641static const struct property_entry vexia_edu_atla10_pmic_props[] = {701static const struct property_entry vexia_edu_atla10_9v_pmic_props[] = {
642 PROPERTY_ENTRY_BOOL("linux,register-pwrsrc-power_supply"),702 PROPERTY_ENTRY_BOOL("linux,register-pwrsrc-power_supply"),
643 { }703 { }
644};704};
645 705
646static const struct software_node vexia_edu_atla10_pmic_node = {706static const struct software_node vexia_edu_atla10_9v_pmic_node = {
647 .properties = vexia_edu_atla10_pmic_props,707 .properties = vexia_edu_atla10_9v_pmic_props,
648};708};
649 709
650static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initconst = {710static const struct x86_i2c_client_info vexia_edu_atla10_9v_i2c_clients[] __initconst = {
651 {711 {
652 /* I2C attached embedded controller, used to access fuel-gauge */712 /* I2C attached embedded controller, used to access fuel-gauge */
653 .board_info = {713 .board_info = {
654 .type = "vexia_atla10_ec",714 .type = "vexia_atla10_ec",
655 .addr = 0x76,715 .addr = 0x76,
656 .dev_name = "ulpmc",716 .dev_name = "ulpmc",
657 .swnode = &vexia_edu_atla10_ulpmc_node,717 .swnode = &vexia_edu_atla10_9v_ulpmc_node,
658 },718 },
659 .adapter_path = "0000:00:18.1",719 .adapter_path = "0000:00:18.1",
660 }, {720 }, {
@@ -679,7 +739,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon · 18 unmodified lines
679 .type = "kxtj21009",739 .type = "kxtj21009",
680 .addr = 0x0f,740 .addr = 0x0f,
681 .dev_name = "kxtj21009",741 .dev_name = "kxtj21009",
682 .swnode = &vexia_edu_atla10_accel_node,742 .swnode = &vexia_edu_atla10_9v_accel_node,
683 },743 },
684 .adapter_path = "0000:00:18.5",744 .adapter_path = "0000:00:18.5",
685 }, {745 }, {
@@ -688,7 +748,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon · 2 unmodified lines
688 .type = "hid-over-i2c",748 .type = "hid-over-i2c",
689 .addr = 0x38,749 .addr = 0x38,
690 .dev_name = "FTSC1000",750 .dev_name = "FTSC1000",
691 .swnode = &vexia_edu_atla10_touchscreen_node,751 .swnode = &vexia_edu_atla10_9v_touchscreen_node,
692 },752 },
693 .adapter_path = "0000:00:18.6",753 .adapter_path = "0000:00:18.6",
694 .irq_data = {754 .irq_data = {
@@ -703,7 +763,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon · 8 unmodified lines
703 .type = "intel_soc_pmic_crc",763 .type = "intel_soc_pmic_crc",
704 .addr = 0x6e,764 .addr = 0x6e,
705 .dev_name = "intel_soc_pmic_crc",765 .dev_name = "intel_soc_pmic_crc",
706 .swnode = &vexia_edu_atla10_pmic_node,766 .swnode = &vexia_edu_atla10_9v_pmic_node,
707 },767 },
708 .adapter_path = "0000:00:18.7",768 .adapter_path = "0000:00:18.7",
709 .irq_data = {769 .irq_data = {
@@ -715,7 +775,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon · 5 unmodified lines
715 }775 }
716};776};
717 777
718static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = {778static const struct x86_serdev_info vexia_edu_atla10_9v_serdevs[] __initconst = {
719 {779 {
720 .ctrl.pci.devfn = PCI_DEVFN(0x1e, 3),780 .ctrl.pci.devfn = PCI_DEVFN(0x1e, 3),
721 .ctrl_devname = "serial0",781 .ctrl_devname = "serial0",
@@ -723,7 +783,7 @@ static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = { · 1 unmodified line
723 },783 },
724};784};
725 785
726static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = {786static struct gpiod_lookup_table vexia_edu_atla10_9v_ft5416_gpios = {
727 .dev_id = "i2c-FTSC1000",787 .dev_id = "i2c-FTSC1000",
728 .table = {788 .table = {
729 GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW),789 GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW),
@@ -731,12 +791,12 @@ static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = { · 1 unmodified line
731 },791 },
732};792};
733 793
734static struct gpiod_lookup_table * const vexia_edu_atla10_gpios[] = {794static struct gpiod_lookup_table * const vexia_edu_atla10_9v_gpios[] = {
735 &vexia_edu_atla10_ft5416_gpios,795 &vexia_edu_atla10_9v_ft5416_gpios,
736 NULL796 NULL
737};797};
738 798
739static int __init vexia_edu_atla10_init(struct device *dev)799static int __init vexia_edu_atla10_9v_init(struct device *dev)
740{800{
741 struct pci_dev *pdev;801 struct pci_dev *pdev;
742 int ret;802 int ret;
@@ -760,13 +820,13 @@ static int __init vexia_edu_atla10_init(struct device *dev) · 17 unmodified lines
760 return 0;820 return 0;
761}821}
762 822
763const struct x86_dev_info vexia_edu_atla10_info __initconst = {823const struct x86_dev_info vexia_edu_atla10_9v_info __initconst = {
764 .i2c_client_info = vexia_edu_atla10_i2c_clients,824 .i2c_client_info = vexia_edu_atla10_9v_i2c_clients,
765 .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients),825 .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_9v_i2c_clients),
766 .serdev_info = vexia_edu_atla10_serdevs,826 .serdev_info = vexia_edu_atla10_9v_serdevs,
767 .serdev_count = ARRAY_SIZE(vexia_edu_atla10_serdevs),827 .serdev_count = ARRAY_SIZE(vexia_edu_atla10_9v_serdevs),
768 .gpiod_lookup_tables = vexia_edu_atla10_gpios,828 .gpiod_lookup_tables = vexia_edu_atla10_9v_gpios,
769 .init = vexia_edu_atla10_init,829 .init = vexia_edu_atla10_9v_init,
770 .use_pci = true,830 .use_pci = true,
771};831};
772 832
drivers/platform/x86/x86-android-tablets/x86-android-tablets.h+2−1
@@ -127,7 +127,8 @@ extern const struct x86_dev_info nextbook_ares8_info; · 126 unmodified lines
127extern const struct x86_dev_info nextbook_ares8a_info;127extern const struct x86_dev_info nextbook_ares8a_info;
128extern const struct x86_dev_info peaq_c1010_info;128extern const struct x86_dev_info peaq_c1010_info;
129extern const struct x86_dev_info whitelabel_tm800a550l_info;129extern const struct x86_dev_info whitelabel_tm800a550l_info;
130extern const struct x86_dev_info vexia_edu_atla10_info;130extern const struct x86_dev_info vexia_edu_atla10_5v_info;
131extern const struct x86_dev_info vexia_edu_atla10_9v_info;
131extern const struct x86_dev_info xiaomi_mipad2_info;132extern const struct x86_dev_info xiaomi_mipad2_info;
132extern const struct dmi_system_id x86_android_tablet_ids[];133extern const struct dmi_system_id x86_android_tablet_ids[];
133 134
include/linux/platform_data/x86/intel_pmc_ipc.h+4−0
@@ -36,6 +36,7 @@ struct pmc_ipc_rbuf { · 35 unmodified lines
36 */36 */
37static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf)37static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf)
38{38{
39#ifdef CONFIG_ACPI
39 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };40 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
40 union acpi_object params[PMC_IPCS_PARAM_COUNT] = {41 union acpi_object params[PMC_IPCS_PARAM_COUNT] = {
41 {.type = ACPI_TYPE_INTEGER,},42 {.type = ACPI_TYPE_INTEGER,},
@@ -89,6 +90,9 @@ static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf · 47 unmodified lines
89 }90 }
90 91
91 return 0;92 return 0;
93#else
94 return -ENODEV;
95#endif /* CONFIG_ACPI */
92}96}
93 97
94#endif /* INTEL_PMC_IPC_H */98#endif /* INTEL_PMC_IPC_H */