Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'platform-drivers-x86-v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:

- WMI bus driver fixes

- Second attempt (previously reverted) at P2SB PCI rescan deadlock fix

- AMD PMF driver improvements

- MAINTAINERS updates

- Misc other small fixes and hw-id additions

* tag 'platform-drivers-x86-v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
platform/x86: touchscreen_dmi: Add info for the TECLAST X16 Plus tablet
platform/x86/intel/ifs: Call release_firmware() when handling errors.
platform/x86/amd/pmf: Fix memory leak in amd_pmf_get_pb_data()
platform/x86/amd/pmf: Get ambient light information from AMD SFH driver
platform/x86/amd/pmf: Get Human presence information from AMD SFH driver
platform/mellanox: mlxbf-pmc: Fix offset calculation for crspace events
platform/mellanox: mlxbf-tmfifo: Drop Tx network packet when Tx TmFIFO is full
MAINTAINERS: remove defunct acpi4asus project info from asus notebooks section
MAINTAINERS: add Luke Jones as maintainer for asus notebooks
MAINTAINERS: Remove Perry Yuan as DELL WMI HARDWARE PRIVACY SUPPORT maintainer
platform/x86: silicom-platform: Add missing "Description:" for power_cycle sysfs attr
platform/x86: intel-wmi-sbl-fw-update: Fix function name in error message
platform/x86: p2sb: Use pci_resource_n() in p2sb_read_bar0()
platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe
platform/x86: intel-uncore-freq: Fix types in sysfs callbacks
platform/x86: wmi: Fix wmi_dev_probe()
platform/x86: wmi: Fix notify callback locking
platform/x86: wmi: Decouple legacy WMI notify handlers from wmi_block_list
platform/x86: wmi: Return immediately if an suitable WMI event is found
platform/x86: wmi: Fix error handling in legacy WMI notify handler functions

+472 -189
+1
Documentation/ABI/testing/sysfs-platform-silicom
··· 10 10 Date: November 2023 11 11 KernelVersion: 6.7 12 12 Contact: Henry Shi <henrys@silicom-usa.com> 13 + Description: 13 14 This file allow user to power cycle the platform. 14 15 Default value is 0; when set to 1, it powers down 15 16 the platform, waits 5 seconds, then powers on the
+2 -3
MAINTAINERS
··· 3168 3168 3169 3169 ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS 3170 3170 M: Corentin Chary <corentin.chary@gmail.com> 3171 - L: acpi4asus-user@lists.sourceforge.net 3171 + M: Luke D. Jones <luke@ljones.dev> 3172 3172 L: platform-driver-x86@vger.kernel.org 3173 3173 S: Maintained 3174 - W: http://acpi4asus.sf.net 3174 + W: https://asus-linux.org/ 3175 3175 F: drivers/platform/x86/asus*.c 3176 3176 F: drivers/platform/x86/eeepc*.c 3177 3177 ··· 5958 5958 F: drivers/platform/x86/dell/dell-wmi-descriptor.c 5959 5959 5960 5960 DELL WMI HARDWARE PRIVACY SUPPORT 5961 - M: Perry Yuan <Perry.Yuan@dell.com> 5962 5961 L: Dell.Client.Kernel@dell.com 5963 5962 L: platform-driver-x86@vger.kernel.org 5964 5963 S: Maintained
+2 -2
drivers/platform/mellanox/mlxbf-pmc.c
··· 1170 1170 int ret; 1171 1171 1172 1172 addr = pmc->block[blk_num].mmio_base + 1173 - (rounddown(cnt_num, 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); 1173 + ((cnt_num / 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); 1174 1174 ret = mlxbf_pmc_readl(addr, &word); 1175 1175 if (ret) 1176 1176 return ret; ··· 1413 1413 int ret; 1414 1414 1415 1415 addr = pmc->block[blk_num].mmio_base + 1416 - (rounddown(cnt_num, 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); 1416 + ((cnt_num / 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); 1417 1417 ret = mlxbf_pmc_readl(addr, &word); 1418 1418 if (ret) 1419 1419 return ret;
+67
drivers/platform/mellanox/mlxbf-tmfifo.c
··· 47 47 /* Message with data needs at least two words (for header & data). */ 48 48 #define MLXBF_TMFIFO_DATA_MIN_WORDS 2 49 49 50 + /* Tx timeout in milliseconds. */ 51 + #define TMFIFO_TX_TIMEOUT 2000 52 + 50 53 /* ACPI UID for BlueField-3. */ 51 54 #define TMFIFO_BF3_UID 1 52 55 ··· 65 62 * @drop_desc: dummy desc for packet dropping 66 63 * @cur_len: processed length of the current descriptor 67 64 * @rem_len: remaining length of the pending packet 65 + * @rem_padding: remaining bytes to send as paddings 68 66 * @pkt_len: total length of the pending packet 69 67 * @next_avail: next avail descriptor id 70 68 * @num: vring size (number of descriptors) 71 69 * @align: vring alignment size 72 70 * @index: vring index 73 71 * @vdev_id: vring virtio id (VIRTIO_ID_xxx) 72 + * @tx_timeout: expire time of last tx packet 74 73 * @fifo: pointer to the tmfifo structure 75 74 */ 76 75 struct mlxbf_tmfifo_vring { ··· 84 79 struct vring_desc drop_desc; 85 80 int cur_len; 86 81 int rem_len; 82 + int rem_padding; 87 83 u32 pkt_len; 88 84 u16 next_avail; 89 85 int num; 90 86 int align; 91 87 int index; 92 88 int vdev_id; 89 + unsigned long tx_timeout; 93 90 struct mlxbf_tmfifo *fifo; 94 91 }; 95 92 ··· 826 819 return true; 827 820 } 828 821 822 + static void mlxbf_tmfifo_check_tx_timeout(struct mlxbf_tmfifo_vring *vring) 823 + { 824 + unsigned long flags; 825 + 826 + /* Only handle Tx timeout for network vdev. */ 827 + if (vring->vdev_id != VIRTIO_ID_NET) 828 + return; 829 + 830 + /* Initialize the timeout or return if not expired. */ 831 + if (!vring->tx_timeout) { 832 + /* Initialize the timeout. */ 833 + vring->tx_timeout = jiffies + 834 + msecs_to_jiffies(TMFIFO_TX_TIMEOUT); 835 + return; 836 + } else if (time_before(jiffies, vring->tx_timeout)) { 837 + /* Return if not timeout yet. */ 838 + return; 839 + } 840 + 841 + /* 842 + * Drop the packet after timeout. The outstanding packet is 843 + * released and the remaining bytes will be sent with padding byte 0x00 844 + * as a recovery. On the peer(host) side, the padding bytes 0x00 will be 845 + * either dropped directly, or appended into existing outstanding packet 846 + * thus dropped as corrupted network packet. 847 + */ 848 + vring->rem_padding = round_up(vring->rem_len, sizeof(u64)); 849 + mlxbf_tmfifo_release_pkt(vring); 850 + vring->cur_len = 0; 851 + vring->rem_len = 0; 852 + vring->fifo->vring[0] = NULL; 853 + 854 + /* 855 + * Make sure the load/store are in order before 856 + * returning back to virtio. 857 + */ 858 + virtio_mb(false); 859 + 860 + /* Notify upper layer. */ 861 + spin_lock_irqsave(&vring->fifo->spin_lock[0], flags); 862 + vring_interrupt(0, vring->vq); 863 + spin_unlock_irqrestore(&vring->fifo->spin_lock[0], flags); 864 + } 865 + 829 866 /* Rx & Tx processing of a queue. */ 830 867 static void mlxbf_tmfifo_rxtx(struct mlxbf_tmfifo_vring *vring, bool is_rx) 831 868 { ··· 892 841 return; 893 842 894 843 do { 844 + retry: 895 845 /* Get available FIFO space. */ 896 846 if (avail == 0) { 897 847 if (is_rx) ··· 901 849 avail = mlxbf_tmfifo_get_tx_avail(fifo, devid); 902 850 if (avail <= 0) 903 851 break; 852 + } 853 + 854 + /* Insert paddings for discarded Tx packet. */ 855 + if (!is_rx) { 856 + vring->tx_timeout = 0; 857 + while (vring->rem_padding >= sizeof(u64)) { 858 + writeq(0, vring->fifo->tx.data); 859 + vring->rem_padding -= sizeof(u64); 860 + if (--avail == 0) 861 + goto retry; 862 + } 904 863 } 905 864 906 865 /* Console output always comes from the Tx buffer. */ ··· 923 860 /* Handle one descriptor. */ 924 861 more = mlxbf_tmfifo_rxtx_one_desc(vring, is_rx, &avail); 925 862 } while (more); 863 + 864 + /* Check Tx timeout. */ 865 + if (avail <= 0 && !is_rx) 866 + mlxbf_tmfifo_check_tx_timeout(vring); 926 867 } 927 868 928 869 /* Handle Rx or Tx queues. */
+1
drivers/platform/x86/amd/pmf/Kconfig
··· 10 10 depends on AMD_NB 11 11 select ACPI_PLATFORM_PROFILE 12 12 depends on TEE && AMDTEE 13 + depends on AMD_SFH_HID 13 14 help 14 15 This driver provides support for the AMD Platform Management Framework. 15 16 The goal is to enhance end user experience by making AMD PCs smarter,
+36
drivers/platform/x86/amd/pmf/spc.c
··· 10 10 */ 11 11 12 12 #include <acpi/button.h> 13 + #include <linux/amd-pmf-io.h> 13 14 #include <linux/power_supply.h> 14 15 #include <linux/units.h> 15 16 #include "pmf.h" ··· 45 44 dev_dbg(dev->dev, "Max C0 Residency: %u\n", in->ev_info.max_c0residency); 46 45 dev_dbg(dev->dev, "GFX Busy: %u\n", in->ev_info.gfx_busy); 47 46 dev_dbg(dev->dev, "LID State: %s\n", in->ev_info.lid_state ? "close" : "open"); 47 + dev_dbg(dev->dev, "User Presence: %s\n", in->ev_info.user_present ? "Present" : "Away"); 48 + dev_dbg(dev->dev, "Ambient Light: %d\n", in->ev_info.ambient_light); 48 49 dev_dbg(dev->dev, "==== TA inputs END ====\n"); 49 50 } 50 51 #else ··· 150 147 return 0; 151 148 } 152 149 150 + static int amd_pmf_get_sensor_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) 151 + { 152 + struct amd_sfh_info sfh_info; 153 + int ret; 154 + 155 + /* Get ALS data */ 156 + ret = amd_get_sfh_info(&sfh_info, MT_ALS); 157 + if (!ret) 158 + in->ev_info.ambient_light = sfh_info.ambient_light; 159 + else 160 + return ret; 161 + 162 + /* get HPD data */ 163 + ret = amd_get_sfh_info(&sfh_info, MT_HPD); 164 + if (ret) 165 + return ret; 166 + 167 + switch (sfh_info.user_present) { 168 + case SFH_NOT_DETECTED: 169 + in->ev_info.user_present = 0xff; /* assume no sensors connected */ 170 + break; 171 + case SFH_USER_PRESENT: 172 + in->ev_info.user_present = 1; 173 + break; 174 + case SFH_USER_AWAY: 175 + in->ev_info.user_present = 0; 176 + break; 177 + } 178 + 179 + return 0; 180 + } 181 + 153 182 void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) 154 183 { 155 184 /* TA side lid open is 1 and close is 0, hence the ! here */ ··· 190 155 amd_pmf_get_smu_info(dev, in); 191 156 amd_pmf_get_battery_info(dev, in); 192 157 amd_pmf_get_slider_info(dev, in); 158 + amd_pmf_get_sensor_info(dev, in); 193 159 }
+3 -1
drivers/platform/x86/amd/pmf/tee-if.c
··· 298 298 if (!new_policy_buf) 299 299 return -ENOMEM; 300 300 301 - if (copy_from_user(new_policy_buf, buf, length)) 301 + if (copy_from_user(new_policy_buf, buf, length)) { 302 + kfree(new_policy_buf); 302 303 return -EFAULT; 304 + } 303 305 304 306 kfree(dev->policy_buf); 305 307 dev->policy_buf = new_policy_buf;
+2 -1
drivers/platform/x86/intel/ifs/load.c
··· 399 399 if (fw->size != expected_size) { 400 400 dev_err(dev, "File size mismatch (expected %u, actual %zu). Corrupted IFS image.\n", 401 401 expected_size, fw->size); 402 - return -EINVAL; 402 + ret = -EINVAL; 403 + goto release; 403 404 } 404 405 405 406 ret = image_sanity_check(dev, (struct microcode_header_intel *)fw->data);
+41 -41
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
··· 23 23 static int (*uncore_write)(struct uncore_data *data, unsigned int input, unsigned int min_max); 24 24 static int (*uncore_read_freq)(struct uncore_data *data, unsigned int *freq); 25 25 26 - static ssize_t show_domain_id(struct device *dev, struct device_attribute *attr, char *buf) 26 + static ssize_t show_domain_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 27 27 { 28 - struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_dev_attr); 28 + struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_kobj_attr); 29 29 30 30 return sprintf(buf, "%u\n", data->domain_id); 31 31 } 32 32 33 - static ssize_t show_fabric_cluster_id(struct device *dev, struct device_attribute *attr, char *buf) 33 + static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 34 34 { 35 - struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_dev_attr); 35 + struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_kobj_attr); 36 36 37 37 return sprintf(buf, "%u\n", data->cluster_id); 38 38 } 39 39 40 - static ssize_t show_package_id(struct device *dev, struct device_attribute *attr, char *buf) 40 + static ssize_t show_package_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 41 41 { 42 - struct uncore_data *data = container_of(attr, struct uncore_data, package_id_dev_attr); 42 + struct uncore_data *data = container_of(attr, struct uncore_data, package_id_kobj_attr); 43 43 44 44 return sprintf(buf, "%u\n", data->package_id); 45 45 } ··· 97 97 } 98 98 99 99 #define store_uncore_min_max(name, min_max) \ 100 - static ssize_t store_##name(struct device *dev, \ 101 - struct device_attribute *attr, \ 100 + static ssize_t store_##name(struct kobject *kobj, \ 101 + struct kobj_attribute *attr, \ 102 102 const char *buf, size_t count) \ 103 103 { \ 104 - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ 104 + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ 105 105 \ 106 106 return store_min_max_freq_khz(data, buf, count, \ 107 107 min_max); \ 108 108 } 109 109 110 110 #define show_uncore_min_max(name, min_max) \ 111 - static ssize_t show_##name(struct device *dev, \ 112 - struct device_attribute *attr, char *buf)\ 111 + static ssize_t show_##name(struct kobject *kobj, \ 112 + struct kobj_attribute *attr, char *buf)\ 113 113 { \ 114 - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ 114 + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ 115 115 \ 116 116 return show_min_max_freq_khz(data, buf, min_max); \ 117 117 } 118 118 119 119 #define show_uncore_perf_status(name) \ 120 - static ssize_t show_##name(struct device *dev, \ 121 - struct device_attribute *attr, char *buf)\ 120 + static ssize_t show_##name(struct kobject *kobj, \ 121 + struct kobj_attribute *attr, char *buf)\ 122 122 { \ 123 - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ 123 + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ 124 124 \ 125 125 return show_perf_status_freq_khz(data, buf); \ 126 126 } ··· 134 134 show_uncore_perf_status(current_freq_khz); 135 135 136 136 #define show_uncore_data(member_name) \ 137 - static ssize_t show_##member_name(struct device *dev, \ 138 - struct device_attribute *attr, char *buf)\ 137 + static ssize_t show_##member_name(struct kobject *kobj, \ 138 + struct kobj_attribute *attr, char *buf)\ 139 139 { \ 140 140 struct uncore_data *data = container_of(attr, struct uncore_data,\ 141 - member_name##_dev_attr);\ 141 + member_name##_kobj_attr);\ 142 142 \ 143 143 return sysfs_emit(buf, "%u\n", \ 144 144 data->member_name); \ ··· 149 149 150 150 #define init_attribute_rw(_name) \ 151 151 do { \ 152 - sysfs_attr_init(&data->_name##_dev_attr.attr); \ 153 - data->_name##_dev_attr.show = show_##_name; \ 154 - data->_name##_dev_attr.store = store_##_name; \ 155 - data->_name##_dev_attr.attr.name = #_name; \ 156 - data->_name##_dev_attr.attr.mode = 0644; \ 152 + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ 153 + data->_name##_kobj_attr.show = show_##_name; \ 154 + data->_name##_kobj_attr.store = store_##_name; \ 155 + data->_name##_kobj_attr.attr.name = #_name; \ 156 + data->_name##_kobj_attr.attr.mode = 0644; \ 157 157 } while (0) 158 158 159 159 #define init_attribute_ro(_name) \ 160 160 do { \ 161 - sysfs_attr_init(&data->_name##_dev_attr.attr); \ 162 - data->_name##_dev_attr.show = show_##_name; \ 163 - data->_name##_dev_attr.store = NULL; \ 164 - data->_name##_dev_attr.attr.name = #_name; \ 165 - data->_name##_dev_attr.attr.mode = 0444; \ 161 + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ 162 + data->_name##_kobj_attr.show = show_##_name; \ 163 + data->_name##_kobj_attr.store = NULL; \ 164 + data->_name##_kobj_attr.attr.name = #_name; \ 165 + data->_name##_kobj_attr.attr.mode = 0444; \ 166 166 } while (0) 167 167 168 168 #define init_attribute_root_ro(_name) \ 169 169 do { \ 170 - sysfs_attr_init(&data->_name##_dev_attr.attr); \ 171 - data->_name##_dev_attr.show = show_##_name; \ 172 - data->_name##_dev_attr.store = NULL; \ 173 - data->_name##_dev_attr.attr.name = #_name; \ 174 - data->_name##_dev_attr.attr.mode = 0400; \ 170 + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ 171 + data->_name##_kobj_attr.show = show_##_name; \ 172 + data->_name##_kobj_attr.store = NULL; \ 173 + data->_name##_kobj_attr.attr.name = #_name; \ 174 + data->_name##_kobj_attr.attr.mode = 0400; \ 175 175 } while (0) 176 176 177 177 static int create_attr_group(struct uncore_data *data, char *name) ··· 186 186 187 187 if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) { 188 188 init_attribute_root_ro(domain_id); 189 - data->uncore_attrs[index++] = &data->domain_id_dev_attr.attr; 189 + data->uncore_attrs[index++] = &data->domain_id_kobj_attr.attr; 190 190 init_attribute_root_ro(fabric_cluster_id); 191 - data->uncore_attrs[index++] = &data->fabric_cluster_id_dev_attr.attr; 191 + data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr; 192 192 init_attribute_root_ro(package_id); 193 - data->uncore_attrs[index++] = &data->package_id_dev_attr.attr; 193 + data->uncore_attrs[index++] = &data->package_id_kobj_attr.attr; 194 194 } 195 195 196 - data->uncore_attrs[index++] = &data->max_freq_khz_dev_attr.attr; 197 - data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr; 198 - data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr; 199 - data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr; 196 + data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr; 197 + data->uncore_attrs[index++] = &data->min_freq_khz_kobj_attr.attr; 198 + data->uncore_attrs[index++] = &data->initial_min_freq_khz_kobj_attr.attr; 199 + data->uncore_attrs[index++] = &data->initial_max_freq_khz_kobj_attr.attr; 200 200 201 201 ret = uncore_read_freq(data, &freq); 202 202 if (!ret) 203 - data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; 203 + data->uncore_attrs[index++] = &data->current_freq_khz_kobj_attr.attr; 204 204 205 205 data->uncore_attrs[index] = NULL; 206 206
+16 -16
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
··· 26 26 * @instance_id: Unique instance id to append to directory name 27 27 * @name: Sysfs entry name for this instance 28 28 * @uncore_attr_group: Attribute group storage 29 - * @max_freq_khz_dev_attr: Storage for device attribute max_freq_khz 30 - * @mix_freq_khz_dev_attr: Storage for device attribute min_freq_khz 31 - * @initial_max_freq_khz_dev_attr: Storage for device attribute initial_max_freq_khz 32 - * @initial_min_freq_khz_dev_attr: Storage for device attribute initial_min_freq_khz 33 - * @current_freq_khz_dev_attr: Storage for device attribute current_freq_khz 34 - * @domain_id_dev_attr: Storage for device attribute domain_id 35 - * @fabric_cluster_id_dev_attr: Storage for device attribute fabric_cluster_id 36 - * @package_id_dev_attr: Storage for device attribute package_id 29 + * @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz 30 + * @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz 31 + * @initial_max_freq_khz_kobj_attr: Storage for kobject attribute initial_max_freq_khz 32 + * @initial_min_freq_khz_kobj_attr: Storage for kobject attribute initial_min_freq_khz 33 + * @current_freq_khz_kobj_attr: Storage for kobject attribute current_freq_khz 34 + * @domain_id_kobj_attr: Storage for kobject attribute domain_id 35 + * @fabric_cluster_id_kobj_attr: Storage for kobject attribute fabric_cluster_id 36 + * @package_id_kobj_attr: Storage for kobject attribute package_id 37 37 * @uncore_attrs: Attribute storage for group creation 38 38 * 39 39 * This structure is used to encapsulate all data related to uncore sysfs ··· 53 53 char name[32]; 54 54 55 55 struct attribute_group uncore_attr_group; 56 - struct device_attribute max_freq_khz_dev_attr; 57 - struct device_attribute min_freq_khz_dev_attr; 58 - struct device_attribute initial_max_freq_khz_dev_attr; 59 - struct device_attribute initial_min_freq_khz_dev_attr; 60 - struct device_attribute current_freq_khz_dev_attr; 61 - struct device_attribute domain_id_dev_attr; 62 - struct device_attribute fabric_cluster_id_dev_attr; 63 - struct device_attribute package_id_dev_attr; 56 + struct kobj_attribute max_freq_khz_kobj_attr; 57 + struct kobj_attribute min_freq_khz_kobj_attr; 58 + struct kobj_attribute initial_max_freq_khz_kobj_attr; 59 + struct kobj_attribute initial_min_freq_khz_kobj_attr; 60 + struct kobj_attribute current_freq_khz_kobj_attr; 61 + struct kobj_attribute domain_id_kobj_attr; 62 + struct kobj_attribute fabric_cluster_id_kobj_attr; 63 + struct kobj_attribute package_id_kobj_attr; 64 64 struct attribute *uncore_attrs[9]; 65 65 }; 66 66
+2 -2
drivers/platform/x86/intel/wmi/sbl-fw-update.c
··· 32 32 return -ENODEV; 33 33 34 34 if (obj->type != ACPI_TYPE_INTEGER) { 35 - dev_warn(dev, "wmi_query_block returned invalid value\n"); 35 + dev_warn(dev, "wmidev_block_query returned invalid value\n"); 36 36 kfree(obj); 37 37 return -EINVAL; 38 38 } ··· 55 55 56 56 status = wmidev_block_set(to_wmi_device(dev), 0, &input); 57 57 if (ACPI_FAILURE(status)) { 58 - dev_err(dev, "wmi_set_block failed\n"); 58 + dev_err(dev, "wmidev_block_set failed\n"); 59 59 return -ENODEV; 60 60 } 61 61
+152 -54
drivers/platform/x86/p2sb.c
··· 26 26 {} 27 27 }; 28 28 29 + /* 30 + * Cache BAR0 of P2SB device functions 0 to 7. 31 + * TODO: The constant 8 is the number of functions that PCI specification 32 + * defines. Same definitions exist tree-wide. Unify this definition and 33 + * the other definitions then move to include/uapi/linux/pci.h. 34 + */ 35 + #define NR_P2SB_RES_CACHE 8 36 + 37 + struct p2sb_res_cache { 38 + u32 bus_dev_id; 39 + struct resource res; 40 + }; 41 + 42 + static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; 43 + 29 44 static int p2sb_get_devfn(unsigned int *devfn) 30 45 { 31 46 unsigned int fn = P2SB_DEVFN_DEFAULT; ··· 54 39 return 0; 55 40 } 56 41 57 - /* Copy resource from the first BAR of the device in question */ 58 - static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) 42 + static bool p2sb_valid_resource(struct resource *res) 59 43 { 60 - struct resource *bar0 = &pdev->resource[0]; 44 + if (res->flags) 45 + return true; 46 + 47 + return false; 48 + } 49 + 50 + /* Copy resource from the first BAR of the device in question */ 51 + static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) 52 + { 53 + struct resource *bar0 = pci_resource_n(pdev, 0); 61 54 62 55 /* Make sure we have no dangling pointers in the output */ 63 56 memset(mem, 0, sizeof(*mem)); ··· 79 56 mem->end = bar0->end; 80 57 mem->flags = bar0->flags; 81 58 mem->desc = bar0->desc; 59 + } 60 + 61 + static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) 62 + { 63 + struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)]; 64 + struct pci_dev *pdev; 65 + 66 + pdev = pci_scan_single_device(bus, devfn); 67 + if (!pdev) 68 + return; 69 + 70 + p2sb_read_bar0(pdev, &cache->res); 71 + cache->bus_dev_id = bus->dev.id; 72 + 73 + pci_stop_and_remove_bus_device(pdev); 74 + } 75 + 76 + static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) 77 + { 78 + unsigned int slot, fn; 79 + 80 + if (PCI_FUNC(devfn) == 0) { 81 + /* 82 + * When function number of the P2SB device is zero, scan it and 83 + * other function numbers, and if devices are available, cache 84 + * their BAR0s. 85 + */ 86 + slot = PCI_SLOT(devfn); 87 + for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++) 88 + p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn)); 89 + } else { 90 + /* Scan the P2SB device and cache its BAR0 */ 91 + p2sb_scan_and_cache_devfn(bus, devfn); 92 + } 93 + 94 + if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res)) 95 + return -ENOENT; 82 96 83 97 return 0; 84 98 } 85 99 86 - static int p2sb_scan_and_read(struct pci_bus *bus, unsigned int devfn, struct resource *mem) 100 + static struct pci_bus *p2sb_get_bus(struct pci_bus *bus) 87 101 { 88 - struct pci_dev *pdev; 102 + static struct pci_bus *p2sb_bus; 103 + 104 + bus = bus ?: p2sb_bus; 105 + if (bus) 106 + return bus; 107 + 108 + /* Assume P2SB is on the bus 0 in domain 0 */ 109 + p2sb_bus = pci_find_bus(0, 0); 110 + return p2sb_bus; 111 + } 112 + 113 + static int p2sb_cache_resources(void) 114 + { 115 + unsigned int devfn_p2sb; 116 + u32 value = P2SBC_HIDE; 117 + struct pci_bus *bus; 118 + u16 class; 89 119 int ret; 90 120 91 - pdev = pci_scan_single_device(bus, devfn); 92 - if (!pdev) 121 + /* Get devfn for P2SB device itself */ 122 + ret = p2sb_get_devfn(&devfn_p2sb); 123 + if (ret) 124 + return ret; 125 + 126 + bus = p2sb_get_bus(NULL); 127 + if (!bus) 93 128 return -ENODEV; 94 129 95 - ret = p2sb_read_bar0(pdev, mem); 130 + /* 131 + * When a device with same devfn exists and its device class is not 132 + * PCI_CLASS_MEMORY_OTHER for P2SB, do not touch it. 133 + */ 134 + pci_bus_read_config_word(bus, devfn_p2sb, PCI_CLASS_DEVICE, &class); 135 + if (!PCI_POSSIBLE_ERROR(class) && class != PCI_CLASS_MEMORY_OTHER) 136 + return -ENODEV; 96 137 97 - pci_stop_and_remove_bus_device(pdev); 138 + /* 139 + * Prevent concurrent PCI bus scan from seeing the P2SB device and 140 + * removing via sysfs while it is temporarily exposed. 141 + */ 142 + pci_lock_rescan_remove(); 143 + 144 + /* 145 + * The BIOS prevents the P2SB device from being enumerated by the PCI 146 + * subsystem, so we need to unhide and hide it back to lookup the BAR. 147 + * Unhide the P2SB device here, if needed. 148 + */ 149 + pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); 150 + if (value & P2SBC_HIDE) 151 + pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); 152 + 153 + ret = p2sb_scan_and_cache(bus, devfn_p2sb); 154 + 155 + /* Hide the P2SB device, if it was hidden */ 156 + if (value & P2SBC_HIDE) 157 + pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE); 158 + 159 + pci_unlock_rescan_remove(); 160 + 98 161 return ret; 99 162 } 100 163 ··· 190 81 * @devfn: PCI slot and function to communicate with 191 82 * @mem: memory resource to be filled in 192 83 * 193 - * The BIOS prevents the P2SB device from being enumerated by the PCI 194 - * subsystem, so we need to unhide and hide it back to lookup the BAR. 195 - * 196 - * if @bus is NULL, the bus 0 in domain 0 will be used. 84 + * If @bus is NULL, the bus 0 in domain 0 will be used. 197 85 * If @devfn is 0, it will be replaced by devfn of the P2SB device. 198 86 * 199 87 * Caller must provide a valid pointer to @mem. 200 - * 201 - * Locking is handled by pci_rescan_remove_lock mutex. 202 88 * 203 89 * Return: 204 90 * 0 on success or appropriate errno value on error. 205 91 */ 206 92 int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) 207 93 { 208 - struct pci_dev *pdev_p2sb; 209 - unsigned int devfn_p2sb; 210 - u32 value = P2SBC_HIDE; 94 + struct p2sb_res_cache *cache; 211 95 int ret; 212 96 213 - /* Get devfn for P2SB device itself */ 214 - ret = p2sb_get_devfn(&devfn_p2sb); 215 - if (ret) 216 - return ret; 217 - 218 - /* if @bus is NULL, use bus 0 in domain 0 */ 219 - bus = bus ?: pci_find_bus(0, 0); 220 - 221 - /* 222 - * Prevent concurrent PCI bus scan from seeing the P2SB device and 223 - * removing via sysfs while it is temporarily exposed. 224 - */ 225 - pci_lock_rescan_remove(); 226 - 227 - /* Unhide the P2SB device, if needed */ 228 - pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); 229 - if (value & P2SBC_HIDE) 230 - pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); 231 - 232 - pdev_p2sb = pci_scan_single_device(bus, devfn_p2sb); 233 - if (devfn) 234 - ret = p2sb_scan_and_read(bus, devfn, mem); 235 - else 236 - ret = p2sb_read_bar0(pdev_p2sb, mem); 237 - pci_stop_and_remove_bus_device(pdev_p2sb); 238 - 239 - /* Hide the P2SB device, if it was hidden */ 240 - if (value & P2SBC_HIDE) 241 - pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE); 242 - 243 - pci_unlock_rescan_remove(); 244 - 245 - if (ret) 246 - return ret; 247 - 248 - if (mem->flags == 0) 97 + bus = p2sb_get_bus(bus); 98 + if (!bus) 249 99 return -ENODEV; 250 100 101 + if (!devfn) { 102 + ret = p2sb_get_devfn(&devfn); 103 + if (ret) 104 + return ret; 105 + } 106 + 107 + cache = &p2sb_resources[PCI_FUNC(devfn)]; 108 + if (cache->bus_dev_id != bus->dev.id) 109 + return -ENODEV; 110 + 111 + if (!p2sb_valid_resource(&cache->res)) 112 + return -ENOENT; 113 + 114 + memcpy(mem, &cache->res, sizeof(*mem)); 251 115 return 0; 252 116 } 253 117 EXPORT_SYMBOL_GPL(p2sb_bar); 118 + 119 + static int __init p2sb_fs_init(void) 120 + { 121 + p2sb_cache_resources(); 122 + return 0; 123 + } 124 + 125 + /* 126 + * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can 127 + * not be locked in sysfs pci bus rescan path because of deadlock. To 128 + * avoid the deadlock, access to P2SB devices with the lock at an early 129 + * step in kernel initialization and cache required resources. This 130 + * should happen after subsys_initcall which initializes PCI subsystem 131 + * and before device_initcall which requires P2SB resources. 132 + */ 133 + fs_initcall(p2sb_fs_init);
+35
drivers/platform/x86/touchscreen_dmi.c
··· 944 944 .properties = teclast_tbook11_props, 945 945 }; 946 946 947 + static const struct property_entry teclast_x16_plus_props[] = { 948 + PROPERTY_ENTRY_U32("touchscreen-min-x", 8), 949 + PROPERTY_ENTRY_U32("touchscreen-min-y", 14), 950 + PROPERTY_ENTRY_U32("touchscreen-size-x", 1916), 951 + PROPERTY_ENTRY_U32("touchscreen-size-y", 1264), 952 + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), 953 + PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"), 954 + PROPERTY_ENTRY_U32("silead,max-fingers", 10), 955 + PROPERTY_ENTRY_BOOL("silead,home-button"), 956 + { } 957 + }; 958 + 959 + static const struct ts_dmi_data teclast_x16_plus_data = { 960 + .embedded_fw = { 961 + .name = "silead/gsl3692-teclast-x16-plus.fw", 962 + .prefix = { 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, 963 + .length = 43560, 964 + .sha256 = { 0x9d, 0xb0, 0x3d, 0xf1, 0x00, 0x3c, 0xb5, 0x25, 965 + 0x62, 0x8a, 0xa0, 0x93, 0x4b, 0xe0, 0x4e, 0x75, 966 + 0xd1, 0x27, 0xb1, 0x65, 0x3c, 0xba, 0xa5, 0x0f, 967 + 0xcd, 0xb4, 0xbe, 0x00, 0xbb, 0xf6, 0x43, 0x29 }, 968 + }, 969 + .acpi_name = "MSSL1680:00", 970 + .properties = teclast_x16_plus_props, 971 + }; 972 + 947 973 static const struct property_entry teclast_x3_plus_props[] = { 948 974 PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), 949 975 PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), ··· 1636 1610 DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), 1637 1611 DMI_MATCH(DMI_PRODUCT_NAME, "TbooK 11"), 1638 1612 DMI_MATCH(DMI_PRODUCT_SKU, "E5A6_A1"), 1613 + }, 1614 + }, 1615 + { 1616 + /* Teclast X16 Plus */ 1617 + .driver_data = (void *)&teclast_x16_plus_data, 1618 + .matches = { 1619 + DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), 1620 + DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), 1621 + DMI_MATCH(DMI_PRODUCT_SKU, "D3A5_A1"), 1639 1622 }, 1640 1623 }, 1641 1624 {
+112 -69
drivers/platform/x86/wmi.c
··· 25 25 #include <linux/list.h> 26 26 #include <linux/module.h> 27 27 #include <linux/platform_device.h> 28 + #include <linux/rwsem.h> 28 29 #include <linux/slab.h> 29 30 #include <linux/sysfs.h> 30 31 #include <linux/types.h> ··· 57 56 58 57 enum { /* wmi_block flags */ 59 58 WMI_READ_TAKES_NO_ARGS, 60 - WMI_PROBED, 61 59 }; 62 60 63 61 struct wmi_block { ··· 64 64 struct list_head list; 65 65 struct guid_block gblock; 66 66 struct acpi_device *acpi_device; 67 + struct rw_semaphore notify_lock; /* Protects notify callback add/remove */ 67 68 wmi_notify_handler handler; 68 69 void *handler_data; 70 + bool driver_ready; 69 71 unsigned long flags; 70 72 }; 71 73 ··· 221 219 return 0; 222 220 } 223 221 222 + static int wmidev_match_notify_id(struct device *dev, const void *data) 223 + { 224 + struct wmi_block *wblock = dev_to_wblock(dev); 225 + const u32 *notify_id = data; 226 + 227 + if (wblock->gblock.flags & ACPI_WMI_EVENT && wblock->gblock.notify_id == *notify_id) 228 + return 1; 229 + 230 + return 0; 231 + } 232 + 224 233 static struct bus_type wmi_bus_type; 225 234 226 235 static struct wmi_device *wmi_find_device_by_guid(const char *guid_string) ··· 249 236 return ERR_PTR(-ENODEV); 250 237 251 238 return dev_to_wdev(dev); 239 + } 240 + 241 + static struct wmi_device *wmi_find_event_by_notify_id(const u32 notify_id) 242 + { 243 + struct device *dev; 244 + 245 + dev = bus_find_device(&wmi_bus_type, NULL, &notify_id, wmidev_match_notify_id); 246 + if (!dev) 247 + return ERR_PTR(-ENODEV); 248 + 249 + return to_wmi_device(dev); 252 250 } 253 251 254 252 static void wmi_device_put(struct wmi_device *wdev) ··· 596 572 wmi_notify_handler handler, 597 573 void *data) 598 574 { 599 - struct wmi_block *block; 600 - acpi_status status = AE_NOT_EXIST; 601 - guid_t guid_input; 575 + struct wmi_block *wblock; 576 + struct wmi_device *wdev; 577 + acpi_status status; 602 578 603 - if (!guid || !handler) 604 - return AE_BAD_PARAMETER; 579 + wdev = wmi_find_device_by_guid(guid); 580 + if (IS_ERR(wdev)) 581 + return AE_ERROR; 605 582 606 - if (guid_parse(guid, &guid_input)) 607 - return AE_BAD_PARAMETER; 583 + wblock = container_of(wdev, struct wmi_block, dev); 608 584 609 - list_for_each_entry(block, &wmi_block_list, list) { 610 - acpi_status wmi_status; 585 + down_write(&wblock->notify_lock); 586 + if (wblock->handler) { 587 + status = AE_ALREADY_ACQUIRED; 588 + } else { 589 + wblock->handler = handler; 590 + wblock->handler_data = data; 611 591 612 - if (guid_equal(&block->gblock.guid, &guid_input)) { 613 - if (block->handler) 614 - return AE_ALREADY_ACQUIRED; 592 + if (ACPI_FAILURE(wmi_method_enable(wblock, true))) 593 + dev_warn(&wblock->dev.dev, "Failed to enable device\n"); 615 594 616 - block->handler = handler; 617 - block->handler_data = data; 618 - 619 - wmi_status = wmi_method_enable(block, true); 620 - if ((wmi_status != AE_OK) || 621 - ((wmi_status == AE_OK) && (status == AE_NOT_EXIST))) 622 - status = wmi_status; 623 - } 595 + status = AE_OK; 624 596 } 597 + up_write(&wblock->notify_lock); 598 + 599 + wmi_device_put(wdev); 625 600 626 601 return status; 627 602 } ··· 636 613 */ 637 614 acpi_status wmi_remove_notify_handler(const char *guid) 638 615 { 639 - struct wmi_block *block; 640 - acpi_status status = AE_NOT_EXIST; 641 - guid_t guid_input; 616 + struct wmi_block *wblock; 617 + struct wmi_device *wdev; 618 + acpi_status status; 642 619 643 - if (!guid) 644 - return AE_BAD_PARAMETER; 620 + wdev = wmi_find_device_by_guid(guid); 621 + if (IS_ERR(wdev)) 622 + return AE_ERROR; 645 623 646 - if (guid_parse(guid, &guid_input)) 647 - return AE_BAD_PARAMETER; 624 + wblock = container_of(wdev, struct wmi_block, dev); 648 625 649 - list_for_each_entry(block, &wmi_block_list, list) { 650 - acpi_status wmi_status; 626 + down_write(&wblock->notify_lock); 627 + if (!wblock->handler) { 628 + status = AE_NULL_ENTRY; 629 + } else { 630 + if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 631 + dev_warn(&wblock->dev.dev, "Failed to disable device\n"); 651 632 652 - if (guid_equal(&block->gblock.guid, &guid_input)) { 653 - if (!block->handler) 654 - return AE_NULL_ENTRY; 633 + wblock->handler = NULL; 634 + wblock->handler_data = NULL; 655 635 656 - wmi_status = wmi_method_enable(block, false); 657 - block->handler = NULL; 658 - block->handler_data = NULL; 659 - if (wmi_status != AE_OK || (wmi_status == AE_OK && status == AE_NOT_EXIST)) 660 - status = wmi_status; 661 - } 636 + status = AE_OK; 662 637 } 638 + up_write(&wblock->notify_lock); 639 + 640 + wmi_device_put(wdev); 663 641 664 642 return status; 665 643 } ··· 679 655 acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out) 680 656 { 681 657 struct wmi_block *wblock; 658 + struct wmi_device *wdev; 659 + acpi_status status; 682 660 683 - list_for_each_entry(wblock, &wmi_block_list, list) { 684 - struct guid_block *gblock = &wblock->gblock; 661 + wdev = wmi_find_event_by_notify_id(event); 662 + if (IS_ERR(wdev)) 663 + return AE_NOT_FOUND; 685 664 686 - if ((gblock->flags & ACPI_WMI_EVENT) && gblock->notify_id == event) 687 - return get_event_data(wblock, out); 688 - } 665 + wblock = container_of(wdev, struct wmi_block, dev); 666 + status = get_event_data(wblock, out); 689 667 690 - return AE_NOT_FOUND; 668 + wmi_device_put(wdev); 669 + 670 + return status; 691 671 } 692 672 EXPORT_SYMBOL_GPL(wmi_get_event_data); 693 673 ··· 896 868 if (wdriver->probe) { 897 869 ret = wdriver->probe(dev_to_wdev(dev), 898 870 find_guid_context(wblock, wdriver)); 899 - if (!ret) { 871 + if (ret) { 900 872 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 901 873 dev_warn(dev, "Failed to disable device\n"); 902 874 ··· 904 876 } 905 877 } 906 878 907 - set_bit(WMI_PROBED, &wblock->flags); 879 + down_write(&wblock->notify_lock); 880 + wblock->driver_ready = true; 881 + up_write(&wblock->notify_lock); 908 882 909 883 return 0; 910 884 } ··· 916 886 struct wmi_block *wblock = dev_to_wblock(dev); 917 887 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); 918 888 919 - clear_bit(WMI_PROBED, &wblock->flags); 889 + down_write(&wblock->notify_lock); 890 + wblock->driver_ready = false; 891 + up_write(&wblock->notify_lock); 920 892 921 893 if (wdriver->remove) 922 894 wdriver->remove(dev_to_wdev(dev)); ··· 1031 999 wblock->dev.setable = true; 1032 1000 1033 1001 out_init: 1002 + init_rwsem(&wblock->notify_lock); 1003 + wblock->driver_ready = false; 1034 1004 wblock->dev.dev.bus = &wmi_bus_type; 1035 1005 wblock->dev.dev.parent = wmi_bus_dev; 1036 1006 ··· 1205 1171 } 1206 1172 } 1207 1173 1174 + static void wmi_notify_driver(struct wmi_block *wblock) 1175 + { 1176 + struct wmi_driver *driver = drv_to_wdrv(wblock->dev.dev.driver); 1177 + struct acpi_buffer data = { ACPI_ALLOCATE_BUFFER, NULL }; 1178 + acpi_status status; 1179 + 1180 + if (!driver->no_notify_data) { 1181 + status = get_event_data(wblock, &data); 1182 + if (ACPI_FAILURE(status)) { 1183 + dev_warn(&wblock->dev.dev, "Failed to get event data\n"); 1184 + return; 1185 + } 1186 + } 1187 + 1188 + if (driver->notify) 1189 + driver->notify(&wblock->dev, data.pointer); 1190 + 1191 + kfree(data.pointer); 1192 + } 1193 + 1208 1194 static int wmi_notify_device(struct device *dev, void *data) 1209 1195 { 1210 1196 struct wmi_block *wblock = dev_to_wblock(dev); ··· 1233 1179 if (!(wblock->gblock.flags & ACPI_WMI_EVENT && wblock->gblock.notify_id == *event)) 1234 1180 return 0; 1235 1181 1236 - /* If a driver is bound, then notify the driver. */ 1237 - if (test_bit(WMI_PROBED, &wblock->flags) && wblock->dev.dev.driver) { 1238 - struct wmi_driver *driver = drv_to_wdrv(wblock->dev.dev.driver); 1239 - struct acpi_buffer evdata = { ACPI_ALLOCATE_BUFFER, NULL }; 1240 - acpi_status status; 1241 - 1242 - if (!driver->no_notify_data) { 1243 - status = get_event_data(wblock, &evdata); 1244 - if (ACPI_FAILURE(status)) { 1245 - dev_warn(&wblock->dev.dev, "failed to get event data\n"); 1246 - return -EIO; 1247 - } 1248 - } 1249 - 1250 - if (driver->notify) 1251 - driver->notify(&wblock->dev, evdata.pointer); 1252 - 1253 - kfree(evdata.pointer); 1254 - } else if (wblock->handler) { 1255 - /* Legacy handler */ 1256 - wblock->handler(*event, wblock->handler_data); 1182 + down_read(&wblock->notify_lock); 1183 + /* The WMI driver notify handler conflicts with the legacy WMI handler. 1184 + * Because of this the WMI driver notify handler takes precedence. 1185 + */ 1186 + if (wblock->dev.dev.driver && wblock->driver_ready) { 1187 + wmi_notify_driver(wblock); 1188 + } else { 1189 + if (wblock->handler) 1190 + wblock->handler(*event, wblock->handler_data); 1257 1191 } 1192 + up_read(&wblock->notify_lock); 1258 1193 1259 1194 acpi_bus_generate_netlink_event(wblock->acpi_device->pnp.device_class, 1260 1195 dev_name(&wblock->dev.dev), *event, 0);