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.
Unified · Split
| @@ -138,6 +138,10 @@ input data, the meaning of which depends on the subfeature being accessed. · 137 unmodified lines | |||
| 138 | The output buffer contains a single byte which signals success or failure (``0x00`` on failure) | 138 | The output buffer contains a single byte which signals success or failure (``0x00`` on failure) |
| 139 | and 31 bytes of output data, the meaning if which depends on the subfeature being accessed. | 139 | and 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 | |||
| 141 | WMI method Get_EC() | 145 | WMI method Get_EC() |
| 142 | ------------------- | 146 | ------------------- |
| 143 | 147 | ||
| @@ -333,9 +333,9 @@ static ssize_t secure_boot_fuse_state_show(struct device *dev, · 332 unmodified lines | |||
| 333 | else | 333 | 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 | } |
| @@ -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" |
| @@ -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 | ||
| 27 | struct hsmp_mbaddr_info { | 28 | struct hsmp_mbaddr_info { |
| 28 | u32 base_addr; | 29 | u32 base_addr; |
| @@ -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; |
| @@ -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 | ||
| @@ -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); |
| @@ -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, |
| @@ -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, |
| @@ -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 | */ | ||
| 188 | u32 fixp_q88_fromint(u32 val) | ||
| 189 | { | ||
| 190 | return val << 8; | ||
| 191 | } | ||
| 192 | |||
| 179 | int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data) | 193 | int 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; |
| @@ -777,6 +777,7 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev); · 776 unmodified lines | |||
| 777 | int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); | 777 | int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); |
| 778 | int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer); | 778 | int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer); |
| 779 | int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag); | 779 | int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag); |
| 780 | u32 fixp_q88_fromint(u32 val); | ||
| 780 | 781 | ||
| 781 | /* SPS Layer */ | 782 | /* SPS Layer */ |
| 782 | int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); | 783 | int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); |
| @@ -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 | ||
| 206 | void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, | 208 | void 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); |
| @@ -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 | ||
| 337 | static 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_DEBUG | 342 | #ifdef CONFIG_AMD_PMF_DEBUG |
| 336 | static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) | 343 | static 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 | |||
| 381 | cleanup: | ||
| 382 | kfree(dev->policy_buf); | ||
| 383 | dev->policy_buf = NULL; | ||
| 384 | return ret; | ||
| 368 | } | 385 | } |
| 369 | 386 | ||
| 370 | static const struct file_operations pb_fops = { | 387 | static 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); |
| @@ -426,11 +426,14 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable) · 425 unmodified lines | |||
| 426 | 426 | ||
| 427 | static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method) | 427 | static 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 ASL | 437 | /* The output is noisy. From reading the ASL |
| 435 | * dissassembly, timeout errors are returned with 1's | 438 | * dissassembly, timeout errors are returned with 1's |
| 436 | * in the high word, and the lack of locking around | 439 | * in the high word, and the lack of locking around |
| @@ -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 backlight | 1874 | * 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); |
| @@ -89,12 +89,44 @@ static struct awcc_quirks generic_quirks = { · 88 unmodified lines | |||
| 89 | static struct awcc_quirks empty_quirks; | 89 | static struct awcc_quirks empty_quirks; |
| 90 | 90 | ||
| 91 | static const struct dmi_system_id awcc_dmi_table[] __initconst = { | 91 | static 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 | ||
| 182 | enum AWCC_GET_FAN_SENSORS_OPERATIONS { | 238 | enum 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 profiles | 1301 | * Some devices report an incorrect number of thermal profiles |
| 1248 | * so the resource ID list may end prematurely | 1302 | * 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); |
| @@ -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); |
| @@ -44,16 +44,17 @@ MODULE_LICENSE("GPL"); · 43 unmodified lines | |||
| 44 | MODULE_AUTHOR("Alex Hung"); | 44 | MODULE_AUTHOR("Alex Hung"); |
| 45 | 45 | ||
| 46 | static const struct acpi_device_id intel_hid_ids[] = { | 46 | static 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 | }; |
| 58 | MODULE_DEVICE_TABLE(acpi, intel_hid_ids); | 59 | MODULE_DEVICE_TABLE(acpi, intel_hid_ids); |
| 59 | 60 | ||
| @@ -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 | ||
| 169 | static int uncore_event_cpu_offline(unsigned int cpu) | 174 | static int uncore_event_cpu_offline(unsigned int cpu) |
| @@ -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 | ||
| 79 | struct msi_wmi_platform_debugfs_data { | 81 | struct 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 | |||
| 86 | struct 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 | ||
| 135 | static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform_method method, | 142 | static 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 | |||
| 170 | static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, | 184 | static 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 | else | 201 | 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 | ||
| 280 | static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry *dir, | 294 | static 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 | ||
| 304 | static void msi_wmi_platform_debugfs_init(struct wmi_device *wdev) | 318 | static 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 | ||
| 325 | static int msi_wmi_platform_hwmon_init(struct wmi_device *wdev) | 339 | static 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 | ||
| 335 | static int msi_wmi_platform_ec_init(struct wmi_device *wdev) | 349 | static 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 | ||
| 365 | static int msi_wmi_platform_init(struct wmi_device *wdev) | 379 | static 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 | ||
| 392 | static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context) | 407 | static 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 | ||
| 409 | static const struct wmi_device_id msi_wmi_platform_id_table[] = { | 436 | static const struct wmi_device_id msi_wmi_platform_id_table[] = { |
| @@ -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 | else | 11524 | else |
| 11523 | return 0; | 11525 | return 0; |
| 11524 | 11526 | ||
| @@ -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 */ |
| @@ -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 tablet | 602 | * Vexia EDU ATLA 10 tablet 5V, Android 4.4 + Guadalinex Ubuntu tablet |
| 603 | * distributed to schools in the Spanish Andalucía region. | ||
| 604 | */ | ||
| 605 | static 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 | |||
| 611 | static const struct software_node vexia_edu_atla10_5v_touchscreen_node = { | ||
| 612 | .properties = vexia_edu_atla10_5v_touchscreen_props, | ||
| 613 | }; | ||
| 614 | |||
| 615 | static 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 | |||
| 642 | static 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 | |||
| 650 | static struct gpiod_lookup_table * const vexia_edu_atla10_5v_gpios[] = { | ||
| 651 | &vexia_edu_atla10_5v_ft5416_gpios, | ||
| 652 | NULL | ||
| 653 | }; | ||
| 654 | |||
| 655 | const 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 | */ |
| 605 | static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" }; | 665 | static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" }; |
| 606 | 666 | ||
| 607 | static const struct property_entry vexia_edu_atla10_ulpmc_props[] = { | 667 | static 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 | ||
| 612 | static const struct software_node vexia_edu_atla10_ulpmc_node = { | 672 | static 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 | ||
| 616 | static const char * const vexia_edu_atla10_accel_mount_matrix[] = { | 676 | static 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 | ||
| 622 | static const struct property_entry vexia_edu_atla10_accel_props[] = { | 682 | static 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 | ||
| 627 | static const struct software_node vexia_edu_atla10_accel_node = { | 687 | static 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 | ||
| 631 | static const struct property_entry vexia_edu_atla10_touchscreen_props[] = { | 691 | static 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 | ||
| 637 | static const struct software_node vexia_edu_atla10_touchscreen_node = { | 697 | static 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 | ||
| 641 | static const struct property_entry vexia_edu_atla10_pmic_props[] = { | 701 | static 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 | ||
| 646 | static const struct software_node vexia_edu_atla10_pmic_node = { | 706 | static 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 | ||
| 650 | static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initconst = { | 710 | static 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 | ||
| 718 | static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = { | 778 | static 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 | ||
| 726 | static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = { | 786 | static 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 | ||
| 734 | static struct gpiod_lookup_table * const vexia_edu_atla10_gpios[] = { | 794 | static struct gpiod_lookup_table * const vexia_edu_atla10_9v_gpios[] = { |
| 735 | &vexia_edu_atla10_ft5416_gpios, | 795 | &vexia_edu_atla10_9v_ft5416_gpios, |
| 736 | NULL | 796 | NULL |
| 737 | }; | 797 | }; |
| 738 | 798 | ||
| 739 | static int __init vexia_edu_atla10_init(struct device *dev) | 799 | static 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 | ||
| 763 | const struct x86_dev_info vexia_edu_atla10_info __initconst = { | 823 | const 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 | ||
| @@ -127,7 +127,8 @@ extern const struct x86_dev_info nextbook_ares8_info; · 126 unmodified lines | |||
| 127 | extern const struct x86_dev_info nextbook_ares8a_info; | 127 | extern const struct x86_dev_info nextbook_ares8a_info; |
| 128 | extern const struct x86_dev_info peaq_c1010_info; | 128 | extern const struct x86_dev_info peaq_c1010_info; |
| 129 | extern const struct x86_dev_info whitelabel_tm800a550l_info; | 129 | extern const struct x86_dev_info whitelabel_tm800a550l_info; |
| 130 | extern const struct x86_dev_info vexia_edu_atla10_info; | 130 | extern const struct x86_dev_info vexia_edu_atla10_5v_info; |
| 131 | extern const struct x86_dev_info vexia_edu_atla10_9v_info; | ||
| 131 | extern const struct x86_dev_info xiaomi_mipad2_info; | 132 | extern const struct x86_dev_info xiaomi_mipad2_info; |
| 132 | extern const struct dmi_system_id x86_android_tablet_ids[]; | 133 | extern const struct dmi_system_id x86_android_tablet_ids[]; |
| 133 | 134 | ||
| @@ -36,6 +36,7 @@ struct pmc_ipc_rbuf { · 35 unmodified lines | |||
| 36 | */ | 36 | */ |
| 37 | static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf) | 37 | static 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 */ |