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.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform drivers fixes from Ilpo Järvinen:
"Mostly a few lines fixed here and there except amd/isp4 which improves
swnodes relationships but that is a new driver not in any stable
kernels yet. The think-lmi driver changes also look relatively large
but there are just many fixes to it.

The i2c/piix4 change is a effectively a revert of the commit
7e173eb82ae9 ("i2c: piix4: Make CONFIG_I2C_PIIX4 dependent on
CONFIG_X86") but that required moving the header out from arch/x86
under include/linux/platform_data/

Summary:

- amd/isp4: Improve swnode graph (new driver exception)

- asus-nb-wmi: Use duo keyboard quirk for Zenbook Duo UX8406CA

- dell-lis3lv02d: Add Latitude 5500 accelerometer address

- dell-wmi-sysman: Fix WMI data block retrieval and class dev unreg

- hp-bioscfg: Fix class device unregistration

- i2c: piix4: Re-enable on non-x86 + move FCH header under platform_data/

- intel/hid: Wildcat Lake support

- mellanox:
- mlxbf-pmc: Fix duplicate event ID
- mlxbf-tmfifo: Fix vring_desc.len assignment
- mlxreg-lc: Fix bit-not-set logic check
- nvsw-sn2201: Fix bus number in error message & spelling errors

- portwell-ec: Move watchdog device under correct platform hierarchy

- think-lmi: Error handling fixes (sysfs, kset, kobject, class dev unreg)

- thinkpad_acpi: Handle HKEY 0x1402 event (2025 Thinkpads)

- wmi: Fix WMI event enablement"

* tag 'platform-drivers-x86-v6.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (22 commits)
platform/x86: think-lmi: Fix sysfs group cleanup
platform/x86: think-lmi: Fix kobject cleanup
platform/x86: think-lmi: Create ksets consecutively
platform/mellanox: mlxreg-lc: Fix logic error in power state check
i2c: Re-enable piix4 driver on non-x86
Move FCH header to a location accessible by all archs
platform/x86/intel/hid: Add Wildcat Lake support
platform/x86: dell-wmi-sysman: Fix class device unregistration
platform/x86: think-lmi: Fix class device unregistration
platform/x86: hp-bioscfg: Fix class device unregistration
platform/x86: Update swnode graph for amd isp4
platform/x86: dell-wmi-sysman: Fix WMI data block retrieval in sysfs callbacks
platform/x86: wmi: Update documentation of WCxx/WExx ACPI methods
platform/x86: wmi: Fix WMI event enablement
platform/mellanox: nvsw-sn2201: Fix bus number in adapter error message
platform/mellanox: Fix spelling and comment clarity in Mellanox drivers
platform/mellanox: mlxbf-pmc: Fix duplicate event ID for CACHE_DATA1
platform/x86: thinkpad_acpi: handle HKEY 0x1402 event
platform/x86: asus-nb-wmi: add DMI quirk for ASUS Zenbook Duo UX8406CA
platform/x86: dell-lis3lv02d: Add Latitude 5500
...

+250 -140
+9 -5
Documentation/wmi/acpi-interface.rst
··· 36 36 37 37 The WMI object flags control whether the method or notification ID is used: 38 38 39 - - 0x1: Data block usage is expensive and must be explicitly enabled/disabled. 39 + - 0x1: Data block is expensive to collect. 40 40 - 0x2: Data block contains WMI methods. 41 41 - 0x4: Data block contains ASCIZ string. 42 42 - 0x8: Data block describes a WMI event, use notification ID instead ··· 83 83 of 0 if the WMI event should be disabled, other values will enable 84 84 the WMI event. 85 85 86 + Those ACPI methods are always called even for WMI events not registered as 87 + being expensive to collect to match the behavior of the Windows driver. 88 + 86 89 WCxx ACPI methods 87 90 ----------------- 88 - Similar to the ``WExx`` ACPI methods, except that it controls data collection 89 - instead of events and thus the last two characters of the ACPI method name are 90 - the method ID of the data block to enable/disable. 91 + Similar to the ``WExx`` ACPI methods, except that instead of WMI events it controls 92 + data collection of data blocks registered as being expensive to collect. Thus the 93 + last two characters of the ACPI method name are the method ID of the data block 94 + to enable/disable. 91 95 92 96 Those ACPI methods are also called before setting data blocks to match the 93 - behaviour of the Windows driver. 97 + behavior of the Windows driver. 94 98 95 99 _WED ACPI method 96 100 ----------------
arch/x86/include/asm/amd/fch.h include/linux/platform_data/x86/amd-fch.h
+1 -1
arch/x86/kernel/cpu/amd.c
··· 9 9 #include <linux/sched/clock.h> 10 10 #include <linux/random.h> 11 11 #include <linux/topology.h> 12 - #include <asm/amd/fch.h> 12 + #include <linux/platform_data/x86/amd-fch.h> 13 13 #include <asm/processor.h> 14 14 #include <asm/apic.h> 15 15 #include <asm/cacheinfo.h>
+1 -1
drivers/i2c/busses/Kconfig
··· 200 200 201 201 config I2C_PIIX4 202 202 tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" 203 - depends on PCI && HAS_IOPORT && X86 203 + depends on PCI && HAS_IOPORT 204 204 select I2C_SMBUS 205 205 help 206 206 If you say yes to this option, support will be included for the Intel
+1 -1
drivers/i2c/busses/i2c-piix4.c
··· 34 34 #include <linux/dmi.h> 35 35 #include <linux/acpi.h> 36 36 #include <linux/io.h> 37 - #include <asm/amd/fch.h> 37 + #include <linux/platform_data/x86/amd-fch.h> 38 38 39 39 #include "i2c-piix4.h" 40 40
+1 -1
drivers/platform/mellanox/mlxbf-pmc.c
··· 715 715 {101, "GDC_BANK0_HIT_DCL_PARTIAL"}, 716 716 {102, "GDC_BANK0_EVICT_DCL"}, 717 717 {103, "GDC_BANK0_G_RSE_PIPE_CACHE_DATA0"}, 718 - {103, "GDC_BANK0_G_RSE_PIPE_CACHE_DATA1"}, 718 + {104, "GDC_BANK0_G_RSE_PIPE_CACHE_DATA1"}, 719 719 {105, "GDC_BANK0_ARB_STRB"}, 720 720 {106, "GDC_BANK0_ARB_WAIT"}, 721 721 {107, "GDC_BANK0_GGA_STRB"},
+3 -2
drivers/platform/mellanox/mlxbf-tmfifo.c
··· 281 281 vring->align = SMP_CACHE_BYTES; 282 282 vring->index = i; 283 283 vring->vdev_id = tm_vdev->vdev.id.device; 284 - vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; 284 + vring->drop_desc.len = cpu_to_virtio32(&tm_vdev->vdev, 285 + VRING_DROP_DESC_MAX_LEN); 285 286 dev = &tm_vdev->vdev.dev; 286 287 287 288 size = vring_size(vring->num, vring->align); ··· 1288 1287 ether_addr_copy(mac, mlxbf_tmfifo_net_default_mac); 1289 1288 } 1290 1289 1291 - /* Set TmFifo thresolds which is used to trigger interrupts. */ 1290 + /* Set TmFifo thresholds which is used to trigger interrupts. */ 1292 1291 static void mlxbf_tmfifo_set_threshold(struct mlxbf_tmfifo *fifo) 1293 1292 { 1294 1293 u64 ctl;
+1 -1
drivers/platform/mellanox/mlxreg-dpu.c
··· 483 483 mlxreg_dpu->io_data, 484 484 sizeof(*mlxreg_dpu->io_data)); 485 485 if (IS_ERR(mlxreg_dpu->io_regs)) { 486 - dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n", 486 + dev_err(dev, "Failed to create region for client %s at bus %d at addr 0x%02x\n", 487 487 data->hpdev.brdinfo->type, data->hpdev.nr, 488 488 data->hpdev.brdinfo->addr); 489 489 return PTR_ERR(mlxreg_dpu->io_regs);
+6 -6
drivers/platform/mellanox/mlxreg-lc.c
··· 57 57 * @dev: platform device; 58 58 * @lock: line card lock; 59 59 * @par_regmap: parent device regmap handle; 60 - * @data: pltaform core data; 60 + * @data: platform core data; 61 61 * @io_data: register access platform data; 62 - * @led_data: LED platform data ; 62 + * @led_data: LED platform data; 63 63 * @mux_data: MUX platform data; 64 64 * @led: LED device; 65 65 * @io_regs: register access device; ··· 171 171 0x4e, 0x4f 172 172 }; 173 173 174 - /* Defaul mux configuration. */ 174 + /* Default mux configuration. */ 175 175 static struct mlxcpld_mux_plat_data mlxreg_lc_mux_data[] = { 176 176 { 177 177 .chan_ids = mlxreg_lc_chan, ··· 181 181 }, 182 182 }; 183 183 184 - /* Defaul mux board info. */ 184 + /* Default mux board info. */ 185 185 static struct i2c_board_info mlxreg_lc_mux_brdinfo = { 186 186 I2C_BOARD_INFO("i2c-mux-mlxcpld", 0x32), 187 187 }; ··· 688 688 if (regval & mlxreg_lc->data->mask) { 689 689 mlxreg_lc->state |= MLXREG_LC_SYNCED; 690 690 mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_SYNCED, 1); 691 - if (mlxreg_lc->state & ~MLXREG_LC_POWERED) { 691 + if (!(mlxreg_lc->state & MLXREG_LC_POWERED)) { 692 692 err = mlxreg_lc_power_on_off(mlxreg_lc, 1); 693 693 if (err) 694 694 goto mlxreg_lc_regmap_power_on_off_fail; ··· 758 758 platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0, 759 759 mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data)); 760 760 if (IS_ERR(mlxreg_lc->io_regs)) { 761 - dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n", 761 + dev_err(dev, "Failed to create region for client %s at bus %d at addr 0x%02x\n", 762 762 data->hpdev.brdinfo->type, data->hpdev.nr, 763 763 data->hpdev.brdinfo->addr); 764 764 err = PTR_ERR(mlxreg_lc->io_regs);
+1 -1
drivers/platform/mellanox/nvsw-sn2201.c
··· 1181 1181 if (!nvsw_sn2201->main_mux_devs->adapter) { 1182 1182 err = -ENODEV; 1183 1183 dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", 1184 - nvsw_sn2201->cpld_devs->nr); 1184 + nvsw_sn2201->main_mux_devs->nr); 1185 1185 goto i2c_get_adapter_main_fail; 1186 1186 } 1187 1187
+144 -37
drivers/platform/x86/amd/amd_isp4.c
··· 21 21 #define AMDISP_OV05C10_REMOTE_EP_NAME "ov05c10_isp_4_1_1" 22 22 #define AMD_ISP_PLAT_DRV_NAME "amd-isp4" 23 23 24 + static const struct software_node isp4_mipi1_endpoint_node; 25 + static const struct software_node ov05c10_endpoint_node; 26 + 24 27 /* 25 28 * AMD ISP platform info definition to initialize sensor 26 29 * specific platform configuration to prepare the amdisp ··· 46 43 struct mutex lock; /* protects i2c client creation */ 47 44 }; 48 45 49 - /* Top-level OV05C10 camera node property table */ 46 + /* Root AMD CAMERA SWNODE */ 47 + 48 + /* Root amd camera node definition */ 49 + static const struct software_node amd_camera_node = { 50 + .name = "amd_camera", 51 + }; 52 + 53 + /* ISP4 SWNODE */ 54 + 55 + /* ISP4 OV05C10 camera node definition */ 56 + static const struct software_node isp4_node = { 57 + .name = "isp4", 58 + .parent = &amd_camera_node, 59 + }; 60 + 61 + /* 62 + * ISP4 Ports node definition. No properties defined for 63 + * ports node. 64 + */ 65 + static const struct software_node isp4_ports = { 66 + .name = "ports", 67 + .parent = &isp4_node, 68 + }; 69 + 70 + /* 71 + * ISP4 Port node definition. No properties defined for 72 + * port node. 73 + */ 74 + static const struct software_node isp4_port_node = { 75 + .name = "port@0", 76 + .parent = &isp4_ports, 77 + }; 78 + 79 + /* 80 + * ISP4 MIPI1 remote endpoint points to OV05C10 endpoint 81 + * node. 82 + */ 83 + static const struct software_node_ref_args isp4_refs[] = { 84 + SOFTWARE_NODE_REFERENCE(&ov05c10_endpoint_node), 85 + }; 86 + 87 + /* ISP4 MIPI1 endpoint node properties table */ 88 + static const struct property_entry isp4_mipi1_endpoint_props[] = { 89 + PROPERTY_ENTRY_REF_ARRAY("remote-endpoint", isp4_refs), 90 + { } 91 + }; 92 + 93 + /* ISP4 MIPI1 endpoint node definition */ 94 + static const struct software_node isp4_mipi1_endpoint_node = { 95 + .name = "endpoint", 96 + .parent = &isp4_port_node, 97 + .properties = isp4_mipi1_endpoint_props, 98 + }; 99 + 100 + /* I2C1 SWNODE */ 101 + 102 + /* I2C1 camera node property table */ 103 + static const struct property_entry i2c1_camera_props[] = { 104 + PROPERTY_ENTRY_U32("clock-frequency", 1 * HZ_PER_MHZ), 105 + { } 106 + }; 107 + 108 + /* I2C1 camera node definition */ 109 + static const struct software_node i2c1_node = { 110 + .name = "i2c1", 111 + .parent = &amd_camera_node, 112 + .properties = i2c1_camera_props, 113 + }; 114 + 115 + /* I2C1 camera node property table */ 50 116 static const struct property_entry ov05c10_camera_props[] = { 51 117 PROPERTY_ENTRY_U32("clock-frequency", 24 * HZ_PER_MHZ), 52 118 { } 53 119 }; 54 120 55 - /* Root AMD ISP OV05C10 camera node definition */ 56 - static const struct software_node camera_node = { 121 + /* OV05C10 camera node definition */ 122 + static const struct software_node ov05c10_camera_node = { 57 123 .name = AMDISP_OV05C10_HID, 124 + .parent = &i2c1_node, 58 125 .properties = ov05c10_camera_props, 59 126 }; 60 127 61 128 /* 62 - * AMD ISP OV05C10 Ports node definition. No properties defined for 129 + * OV05C10 Ports node definition. No properties defined for 63 130 * ports node for OV05C10. 64 131 */ 65 - static const struct software_node ports = { 132 + static const struct software_node ov05c10_ports = { 66 133 .name = "ports", 67 - .parent = &camera_node, 134 + .parent = &ov05c10_camera_node, 68 135 }; 69 136 70 137 /* 71 - * AMD ISP OV05C10 Port node definition. No properties defined for 72 - * port node for OV05C10. 138 + * OV05C10 Port node definition. 73 139 */ 74 - static const struct software_node port_node = { 75 - .name = "port@", 76 - .parent = &ports, 140 + static const struct software_node ov05c10_port_node = { 141 + .name = "port@0", 142 + .parent = &ov05c10_ports, 77 143 }; 78 144 79 145 /* 80 - * Remote endpoint AMD ISP node definition. No properties defined for 81 - * remote endpoint node for OV05C10. 82 - */ 83 - static const struct software_node remote_ep_isp_node = { 84 - .name = AMDISP_OV05C10_REMOTE_EP_NAME, 85 - }; 86 - 87 - /* 88 - * Remote endpoint reference for isp node included in the 89 - * OV05C10 endpoint. 146 + * OV05C10 remote endpoint points to ISP4 MIPI1 endpoint 147 + * node. 90 148 */ 91 149 static const struct software_node_ref_args ov05c10_refs[] = { 92 - SOFTWARE_NODE_REFERENCE(&remote_ep_isp_node), 150 + SOFTWARE_NODE_REFERENCE(&isp4_mipi1_endpoint_node), 93 151 }; 94 152 95 153 /* OV05C10 supports one single link frequency */ 96 154 static const u64 ov05c10_link_freqs[] = { 97 - 925 * HZ_PER_MHZ, 155 + 900 * HZ_PER_MHZ, 98 156 }; 99 157 100 158 /* OV05C10 supports only 2-lane configuration */ ··· 175 111 { } 176 112 }; 177 113 178 - /* AMD ISP endpoint node definition */ 179 - static const struct software_node endpoint_node = { 114 + /* OV05C10 endpoint node definition */ 115 + static const struct software_node ov05c10_endpoint_node = { 180 116 .name = "endpoint", 181 - .parent = &port_node, 117 + .parent = &ov05c10_port_node, 182 118 .properties = ov05c10_endpoint_props, 183 119 }; 184 120 185 121 /* 186 - * AMD ISP swnode graph uses 5 nodes and also its relationship is 187 - * fixed to align with the structure that v4l2 expects for successful 188 - * endpoint fwnode parsing. 122 + * AMD Camera swnode graph uses 10 nodes and also its relationship is 123 + * fixed to align with the structure that v4l2 and i2c frameworks expects 124 + * for successful parsing of fwnodes and its properties with standard names. 189 125 * 190 126 * It is only the node property_entries that will vary for each platform 191 127 * supporting different sensor modules. 128 + * 129 + * AMD ISP4 SWNODE GRAPH Structure 130 + * 131 + * amd_camera { 132 + * isp4 { 133 + * ports { 134 + * port@0 { 135 + * isp4_mipi1_ep: endpoint { 136 + * remote-endpoint = &OMNI5C10_ep; 137 + * }; 138 + * }; 139 + * }; 140 + * }; 141 + * 142 + * i2c1 { 143 + * clock-frequency = 1 MHz; 144 + * OMNI5C10 { 145 + * clock-frequency = 24MHz; 146 + * ports { 147 + * port@0 { 148 + * OMNI5C10_ep: endpoint { 149 + * bus-type = 4; 150 + * data-lanes = <1 2>; 151 + * link-frequencies = 900MHz; 152 + * remote-endpoint = &isp4_mipi1; 153 + * }; 154 + * }; 155 + * }; 156 + * }; 157 + * }; 158 + * }; 159 + * 192 160 */ 193 - static const struct software_node *ov05c10_nodes[] = { 194 - &camera_node, 195 - &ports, 196 - &port_node, 197 - &endpoint_node, 198 - &remote_ep_isp_node, 161 + static const struct software_node *amd_isp4_nodes[] = { 162 + &amd_camera_node, 163 + &isp4_node, 164 + &isp4_ports, 165 + &isp4_port_node, 166 + &isp4_mipi1_endpoint_node, 167 + &i2c1_node, 168 + &ov05c10_camera_node, 169 + &ov05c10_ports, 170 + &ov05c10_port_node, 171 + &ov05c10_endpoint_node, 199 172 NULL 200 173 }; 201 174 ··· 242 141 .dev_name = "ov05c10", 243 142 I2C_BOARD_INFO("ov05c10", AMDISP_OV05C10_I2C_ADDR), 244 143 }, 245 - .swnodes = ov05c10_nodes, 144 + .swnodes = amd_isp4_nodes, 246 145 }; 247 146 248 147 static const struct acpi_device_id amdisp_sensor_ids[] = { ··· 334 233 if (ret) 335 234 return ERR_PTR(ret); 336 235 337 - isp4_platform->board_info.swnode = src->swnodes[0]; 236 + /* initialize ov05c10_camera_node */ 237 + isp4_platform->board_info.swnode = src->swnodes[6]; 338 238 339 239 return isp4_platform; 340 240 } ··· 360 258 { 361 259 const struct amdisp_platform_info *pinfo; 362 260 struct amdisp_platform *isp4_platform; 261 + struct acpi_device *adev; 363 262 int ret; 364 263 365 264 pinfo = device_get_match_data(&pdev->dev); ··· 377 274 ret = bus_register_notifier(&i2c_bus_type, &isp4_platform->i2c_nb); 378 275 if (ret) 379 276 goto error_unregister_sw_node; 277 + 278 + adev = ACPI_COMPANION(&pdev->dev); 279 + /* initialize root amd_camera_node */ 280 + adev->driver_data = (void *)pinfo->swnodes[0]; 380 281 381 282 /* check if adapter is already registered and create i2c client instance */ 382 283 i2c_for_each_dev(isp4_platform, try_to_instantiate_i2c_client);
+1 -1
drivers/platform/x86/amd/pmc/pmc-quirks.c
··· 11 11 #include <linux/dmi.h> 12 12 #include <linux/io.h> 13 13 #include <linux/ioport.h> 14 - #include <asm/amd/fch.h> 14 + #include <linux/platform_data/x86/amd-fch.h> 15 15 16 16 #include "pmc.h" 17 17
+9
drivers/platform/x86/asus-nb-wmi.c
··· 530 530 }, 531 531 .driver_data = &quirk_asus_zenbook_duo_kbd, 532 532 }, 533 + { 534 + .callback = dmi_matched, 535 + .ident = "ASUS Zenbook Duo UX8406CA", 536 + .matches = { 537 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 538 + DMI_MATCH(DMI_PRODUCT_NAME, "UX8406CA"), 539 + }, 540 + .driver_data = &quirk_asus_zenbook_duo_kbd, 541 + }, 533 542 {}, 534 543 }; 535 544
+1
drivers/platform/x86/dell/dell-lis3lv02d.c
··· 45 45 * Additional individual entries were added after verification. 46 46 */ 47 47 DELL_LIS3LV02D_DMI_ENTRY("Latitude 5480", 0x29), 48 + DELL_LIS3LV02D_DMI_ENTRY("Latitude 5500", 0x29), 48 49 DELL_LIS3LV02D_DMI_ENTRY("Latitude E6330", 0x29), 49 50 DELL_LIS3LV02D_DMI_ENTRY("Latitude E6430", 0x29), 50 51 DELL_LIS3LV02D_DMI_ENTRY("Precision 3540", 0x29),
+5
drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h
··· 89 89 90 90 enum { ENUM, INT, STR, PO }; 91 91 92 + #define ENUM_MIN_ELEMENTS 8 93 + #define INT_MIN_ELEMENTS 9 94 + #define STR_MIN_ELEMENTS 8 95 + #define PO_MIN_ELEMENTS 4 96 + 92 97 enum { 93 98 ATTR_NAME, 94 99 DISPL_NAME_LANG_CODE,
+3 -2
drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c
··· 23 23 obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); 24 24 if (!obj) 25 25 return -EIO; 26 - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { 26 + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < ENUM_MIN_ELEMENTS || 27 + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { 27 28 kfree(obj); 28 - return -EINVAL; 29 + return -EIO; 29 30 } 30 31 ret = snprintf(buf, PAGE_SIZE, "%s\n", obj->package.elements[CURRENT_VAL].string.pointer); 31 32 kfree(obj);
+3 -2
drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c
··· 25 25 obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); 26 26 if (!obj) 27 27 return -EIO; 28 - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_INTEGER) { 28 + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < INT_MIN_ELEMENTS || 29 + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_INTEGER) { 29 30 kfree(obj); 30 - return -EINVAL; 31 + return -EIO; 31 32 } 32 33 ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[CURRENT_VAL].integer.value); 33 34 kfree(obj);
+3 -2
drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c
··· 26 26 obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); 27 27 if (!obj) 28 28 return -EIO; 29 - if (obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) { 29 + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < PO_MIN_ELEMENTS || 30 + obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) { 30 31 kfree(obj); 31 - return -EINVAL; 32 + return -EIO; 32 33 } 33 34 ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[IS_PASS_SET].integer.value); 34 35 kfree(obj);
+3 -2
drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c
··· 25 25 obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); 26 26 if (!obj) 27 27 return -EIO; 28 - if (obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { 28 + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < STR_MIN_ELEMENTS || 29 + obj->package.elements[CURRENT_VAL].type != ACPI_TYPE_STRING) { 29 30 kfree(obj); 30 - return -EINVAL; 31 + return -EIO; 31 32 } 32 33 ret = snprintf(buf, PAGE_SIZE, "%s\n", obj->package.elements[CURRENT_VAL].string.pointer); 33 34 kfree(obj);
+6 -6
drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
··· 407 407 return retval; 408 408 409 409 switch (attr_type) { 410 - case ENUM: min_elements = 8; break; 411 - case INT: min_elements = 9; break; 412 - case STR: min_elements = 8; break; 413 - case PO: min_elements = 4; break; 410 + case ENUM: min_elements = ENUM_MIN_ELEMENTS; break; 411 + case INT: min_elements = INT_MIN_ELEMENTS; break; 412 + case STR: min_elements = STR_MIN_ELEMENTS; break; 413 + case PO: min_elements = PO_MIN_ELEMENTS; break; 414 414 default: 415 415 pr_err("Error: Unknown attr_type: %d\n", attr_type); 416 416 return -EINVAL; ··· 597 597 release_attributes_data(); 598 598 599 599 err_destroy_classdev: 600 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 600 + device_unregister(wmi_priv.class_dev); 601 601 602 602 err_exit_bios_attr_pass_interface: 603 603 exit_bios_attr_pass_interface(); ··· 611 611 static void __exit sysman_exit(void) 612 612 { 613 613 release_attributes_data(); 614 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 614 + device_unregister(wmi_priv.class_dev); 615 615 exit_bios_attr_set_interface(); 616 616 exit_bios_attr_pass_interface(); 617 617 }
+2 -2
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
··· 1034 1034 release_attributes_data(); 1035 1035 1036 1036 err_destroy_classdev: 1037 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 1037 + device_unregister(bioscfg_drv.class_dev); 1038 1038 1039 1039 err_unregister_class: 1040 1040 hp_exit_attr_set_interface(); ··· 1045 1045 static void __exit hp_exit(void) 1046 1046 { 1047 1047 release_attributes_data(); 1048 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 1048 + device_unregister(bioscfg_drv.class_dev); 1049 1049 1050 1050 hp_exit_attr_set_interface(); 1051 1051 }
+1
drivers/platform/x86/intel/hid.c
··· 54 54 { "INTC107B" }, 55 55 { "INTC10CB" }, 56 56 { "INTC10CC" }, 57 + { "INTC10F1" }, 57 58 { } 58 59 }; 59 60 MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
+1
drivers/platform/x86/portwell-ec.c
··· 236 236 return ret; 237 237 } 238 238 239 + ec_wdt_dev.parent = &pdev->dev; 239 240 ret = devm_watchdog_register_device(&pdev->dev, &ec_wdt_dev); 240 241 if (ret < 0) { 241 242 dev_err(&pdev->dev, "failed to register Portwell EC Watchdog\n");
+32 -62
drivers/platform/x86/think-lmi.c
··· 973 973 .is_visible = auth_attr_is_visible, 974 974 .attrs = auth_attrs, 975 975 }; 976 + __ATTRIBUTE_GROUPS(auth_attr); 976 977 977 978 /* ---- Attributes sysfs --------------------------------------------------------- */ 978 979 static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr, ··· 1189 1188 .is_visible = attr_is_visible, 1190 1189 .attrs = tlmi_attrs, 1191 1190 }; 1191 + __ATTRIBUTE_GROUPS(tlmi_attr); 1192 1192 1193 1193 static void tlmi_attr_setting_release(struct kobject *kobj) 1194 1194 { ··· 1209 1207 static const struct kobj_type tlmi_attr_setting_ktype = { 1210 1208 .release = &tlmi_attr_setting_release, 1211 1209 .sysfs_ops = &kobj_sysfs_ops, 1210 + .default_groups = tlmi_attr_groups, 1212 1211 }; 1213 1212 1214 1213 static const struct kobj_type tlmi_pwd_setting_ktype = { 1215 1214 .release = &tlmi_pwd_setting_release, 1216 1215 .sysfs_ops = &kobj_sysfs_ops, 1216 + .default_groups = auth_attr_groups, 1217 1217 }; 1218 1218 1219 1219 static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, ··· 1384 1380 /* ---- Initialisation --------------------------------------------------------- */ 1385 1381 static void tlmi_release_attr(void) 1386 1382 { 1387 - int i; 1383 + struct kobject *pos, *n; 1388 1384 1389 1385 /* Attribute structures */ 1390 - for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { 1391 - if (tlmi_priv.setting[i]) { 1392 - sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); 1393 - kobject_put(&tlmi_priv.setting[i]->kobj); 1394 - } 1395 - } 1396 1386 sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); 1397 1387 sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &save_settings.attr); 1398 1388 1399 1389 if (tlmi_priv.can_debug_cmd && debug_support) 1400 1390 sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); 1391 + 1392 + list_for_each_entry_safe(pos, n, &tlmi_priv.attribute_kset->list, entry) 1393 + kobject_put(pos); 1401 1394 1402 1395 kset_unregister(tlmi_priv.attribute_kset); 1403 1396 ··· 1403 1402 kfree(tlmi_priv.pwd_admin->save_signature); 1404 1403 1405 1404 /* Authentication structures */ 1406 - sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); 1407 - kobject_put(&tlmi_priv.pwd_admin->kobj); 1408 - sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); 1409 - kobject_put(&tlmi_priv.pwd_power->kobj); 1410 - 1411 - if (tlmi_priv.opcode_support) { 1412 - sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); 1413 - kobject_put(&tlmi_priv.pwd_system->kobj); 1414 - sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); 1415 - kobject_put(&tlmi_priv.pwd_hdd->kobj); 1416 - sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); 1417 - kobject_put(&tlmi_priv.pwd_nvme->kobj); 1418 - } 1405 + list_for_each_entry_safe(pos, n, &tlmi_priv.authentication_kset->list, entry) 1406 + kobject_put(pos); 1419 1407 1420 1408 kset_unregister(tlmi_priv.authentication_kset); 1421 1409 } ··· 1445 1455 goto fail_device_created; 1446 1456 } 1447 1457 1458 + tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, 1459 + &tlmi_priv.class_dev->kobj); 1460 + if (!tlmi_priv.authentication_kset) { 1461 + kset_unregister(tlmi_priv.attribute_kset); 1462 + ret = -ENOMEM; 1463 + goto fail_device_created; 1464 + } 1465 + 1448 1466 for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { 1449 1467 /* Check if index is a valid setting - skip if it isn't */ 1450 1468 if (!tlmi_priv.setting[i]) ··· 1469 1471 1470 1472 /* Build attribute */ 1471 1473 tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset; 1472 - ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL, 1473 - "%s", tlmi_priv.setting[i]->display_name); 1474 - if (ret) 1475 - goto fail_create_attr; 1476 - 1477 - ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); 1474 + ret = kobject_init_and_add(&tlmi_priv.setting[i]->kobj, &tlmi_attr_setting_ktype, 1475 + NULL, "%s", tlmi_priv.setting[i]->display_name); 1478 1476 if (ret) 1479 1477 goto fail_create_attr; 1480 1478 } ··· 1490 1496 } 1491 1497 1492 1498 /* Create authentication entries */ 1493 - tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, 1494 - &tlmi_priv.class_dev->kobj); 1495 - if (!tlmi_priv.authentication_kset) { 1496 - ret = -ENOMEM; 1497 - goto fail_create_attr; 1498 - } 1499 1499 tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; 1500 - ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); 1501 - if (ret) 1502 - goto fail_create_attr; 1503 - 1504 - ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); 1500 + ret = kobject_init_and_add(&tlmi_priv.pwd_admin->kobj, &tlmi_pwd_setting_ktype, 1501 + NULL, "%s", "Admin"); 1505 1502 if (ret) 1506 1503 goto fail_create_attr; 1507 1504 1508 1505 tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; 1509 - ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on"); 1510 - if (ret) 1511 - goto fail_create_attr; 1512 - 1513 - ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); 1506 + ret = kobject_init_and_add(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype, 1507 + NULL, "%s", "Power-on"); 1514 1508 if (ret) 1515 1509 goto fail_create_attr; 1516 1510 1517 1511 if (tlmi_priv.opcode_support) { 1518 1512 tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset; 1519 - ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System"); 1520 - if (ret) 1521 - goto fail_create_attr; 1522 - 1523 - ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); 1513 + ret = kobject_init_and_add(&tlmi_priv.pwd_system->kobj, &tlmi_pwd_setting_ktype, 1514 + NULL, "%s", "System"); 1524 1515 if (ret) 1525 1516 goto fail_create_attr; 1526 1517 1527 1518 tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset; 1528 - ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD"); 1529 - if (ret) 1530 - goto fail_create_attr; 1531 - 1532 - ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); 1519 + ret = kobject_init_and_add(&tlmi_priv.pwd_hdd->kobj, &tlmi_pwd_setting_ktype, 1520 + NULL, "%s", "HDD"); 1533 1521 if (ret) 1534 1522 goto fail_create_attr; 1535 1523 1536 1524 tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset; 1537 - ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe"); 1538 - if (ret) 1539 - goto fail_create_attr; 1540 - 1541 - ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); 1525 + ret = kobject_init_and_add(&tlmi_priv.pwd_nvme->kobj, &tlmi_pwd_setting_ktype, 1526 + NULL, "%s", "NVMe"); 1542 1527 if (ret) 1543 1528 goto fail_create_attr; 1544 1529 } ··· 1527 1554 fail_create_attr: 1528 1555 tlmi_release_attr(); 1529 1556 fail_device_created: 1530 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 1557 + device_unregister(tlmi_priv.class_dev); 1531 1558 fail_class_created: 1532 1559 return ret; 1533 1560 } ··· 1549 1576 new_pwd->minlen = tlmi_priv.pwdcfg.core.min_length; 1550 1577 new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length; 1551 1578 new_pwd->index = 0; 1552 - 1553 - kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype); 1554 1579 1555 1580 return new_pwd; 1556 1581 } ··· 1654 1683 if (setting->possible_values) 1655 1684 strreplace(setting->possible_values, ',', ';'); 1656 1685 1657 - kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); 1658 1686 tlmi_priv.setting[i] = setting; 1659 1687 kfree(item); 1660 1688 } ··· 1751 1781 static void tlmi_remove(struct wmi_device *wdev) 1752 1782 { 1753 1783 tlmi_release_attr(); 1754 - device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 1784 + device_unregister(tlmi_priv.class_dev); 1755 1785 } 1756 1786 1757 1787 static int tlmi_probe(struct wmi_device *wdev, const void *context)
+1
drivers/platform/x86/thinkpad_acpi.c
··· 3295 3295 */ 3296 3296 { KE_KEY, 0x131d, { KEY_VENDOR } }, /* System debug info, similar to old ThinkPad key */ 3297 3297 { KE_KEY, 0x1320, { KEY_LINK_PHONE } }, 3298 + { KE_KEY, 0x1402, { KEY_LINK_PHONE } }, 3298 3299 { KE_KEY, TP_HKEY_EV_TRACK_DOUBLETAP /* 0x8036 */, { KEY_PROG4 } }, 3299 3300 { KE_END } 3300 3301 };
+11 -5
drivers/platform/x86/wmi.c
··· 177 177 acpi_handle handle; 178 178 acpi_status status; 179 179 180 - if (!(wblock->gblock.flags & ACPI_WMI_EXPENSIVE)) 181 - return 0; 182 - 183 180 if (wblock->dev.dev.type == &wmi_type_method) 184 181 return 0; 185 182 186 - if (wblock->dev.dev.type == &wmi_type_event) 183 + if (wblock->dev.dev.type == &wmi_type_event) { 184 + /* 185 + * Windows always enables/disables WMI events, even when they are 186 + * not marked as being expensive. We follow this behavior for 187 + * compatibility reasons. 188 + */ 187 189 snprintf(method, sizeof(method), "WE%02X", wblock->gblock.notify_id); 188 - else 190 + } else { 191 + if (!(wblock->gblock.flags & ACPI_WMI_EXPENSIVE)) 192 + return 0; 193 + 189 194 get_acpi_method_name(wblock, 'C', method); 195 + } 190 196 191 197 /* 192 198 * Not all WMI devices marked as expensive actually implement the