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

Pull x86 platform drivers fixes from Ilpo Järvinen:

- power supply code:
- Add get/set property direct to allow avoiding taking
psy->extensions_sem twice from power supply extensions

- alienware-wmi-wmax:
- Add AWCC support for Alienware Area-51m and m15 R5
- Fix `dmi_system_id` array termination

- arm64: huawei-gaokun-ec: fix OF node leak

- dell-ddv: Fix taking psy->extensions_sem twice

- dell-lis3lv02d: Add Precision 3551 accelerometer support

- firmware_attributes_class: Fix initialization order

- ideapad-laptop: Retain FnLock and kbd backlight across boots

- lenovo-wmi-hotkey: Avoid triggering error -5 due to missing mute LED

- mellanox: mlxbf-pmc: Validate event names and bool input

* tag 'platform-drivers-x86-v6.16-4' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
MAINTAINERS: Update entries for IFS and SBL drivers
platform/x86: dell-lis3lv02d: Add Precision 3551
platform/x86: alieneware-wmi-wmax: Add AWCC support to more laptops
platform/x86: Fix initialization order for firmware_attributes_class
platform: arm64: huawei-gaokun-ec: fix OF node leak
lenovo-wmi-hotkey: Avoid triggering error -5 due to missing mute LED
platform/x86: ideapad-laptop: Fix kbd backlight not remembered among boots
platform/x86: ideapad-laptop: Fix FnLock not remembered among boots
platform/mellanox: mlxbf-pmc: Use kstrtobool() to check 0/1 input
platform/mellanox: mlxbf-pmc: Validate event/enable input
platform/mellanox: mlxbf-pmc: Remove newline char from event name input
platform/x86: dell-ddv: Fix taking the psy->extensions_sem lock twice
power: supply: test-power: Test access to extended power supply
power: supply: core: Add power_supply_get/set_property_direct()
platform/x86: alienware-wmi-wmax: Fix `dmi_system_id` array

+153 -39
+2 -4
MAINTAINERS
··· 12188 12188 F: include/uapi/linux/idxd.h 12189 12189 12190 12190 INTEL IN FIELD SCAN (IFS) DEVICE 12191 - M: Jithu Joseph <jithu.joseph@intel.com> 12191 + M: Tony Luck <tony.luck@intel.com> 12192 12192 R: Ashok Raj <ashok.raj.linux@gmail.com> 12193 - R: Tony Luck <tony.luck@intel.com> 12194 12193 S: Maintained 12195 12194 F: drivers/platform/x86/intel/ifs 12196 12195 F: include/trace/events/intel_ifs.h ··· 12529 12530 F: drivers/net/wireless/intel/iwlwifi/ 12530 12531 12531 12532 INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER 12532 - M: Jithu Joseph <jithu.joseph@intel.com> 12533 - S: Maintained 12533 + S: Orphan 12534 12534 W: https://slimbootloader.github.io/security/firmware-update.html 12535 12535 F: drivers/platform/x86/intel/wmi/sbl-fw-update.c 12536 12536
+2
drivers/platform/arm64/huawei-gaokun-ec.c
··· 662 662 { 663 663 struct auxiliary_device *adev = to_auxiliary_dev(dev); 664 664 665 + of_node_put(dev->of_node); 665 666 kfree(adev); 666 667 } 667 668 ··· 694 693 695 694 ret = auxiliary_device_init(adev); 696 695 if (ret) { 696 + of_node_put(adev->dev.of_node); 697 697 kfree(adev); 698 698 return ret; 699 699 }
+17 -8
drivers/platform/mellanox/mlxbf-pmc.c
··· 15 15 #include <linux/hwmon.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/string.h> 18 + #include <linux/string_helpers.h> 18 19 #include <uapi/linux/psci.h> 19 20 20 21 #define MLXBF_PMC_WRITE_REG_32 0x82000009 ··· 1223 1222 return -ENODEV; 1224 1223 } 1225 1224 1226 - /* Get the event number given the name */ 1225 + /* Get the event name given the number */ 1227 1226 static char *mlxbf_pmc_get_event_name(const char *blk, u32 evt) 1228 1227 { 1229 1228 const struct mlxbf_pmc_events *events; ··· 1785 1784 attr, struct mlxbf_pmc_attribute, dev_attr); 1786 1785 unsigned int blk_num, cnt_num; 1787 1786 bool is_l3 = false; 1787 + char *evt_name; 1788 1788 int evt_num; 1789 1789 int err; 1790 1790 ··· 1793 1791 cnt_num = attr_event->index; 1794 1792 1795 1793 if (isalpha(buf[0])) { 1794 + /* Remove the trailing newline character if present */ 1795 + evt_name = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL); 1796 + if (!evt_name) 1797 + return -ENOMEM; 1798 + 1796 1799 evt_num = mlxbf_pmc_get_event_num(pmc->block_name[blk_num], 1797 - buf); 1800 + evt_name); 1801 + kfree(evt_name); 1798 1802 if (evt_num < 0) 1799 1803 return -EINVAL; 1800 1804 } else { 1801 1805 err = kstrtouint(buf, 0, &evt_num); 1802 1806 if (err < 0) 1803 1807 return err; 1808 + 1809 + if (!mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num)) 1810 + return -EINVAL; 1804 1811 } 1805 1812 1806 1813 if (strstr(pmc->block_name[blk_num], "l3cache")) ··· 1890 1879 { 1891 1880 struct mlxbf_pmc_attribute *attr_enable = container_of( 1892 1881 attr, struct mlxbf_pmc_attribute, dev_attr); 1893 - unsigned int en, blk_num; 1882 + unsigned int blk_num; 1894 1883 u32 word; 1895 1884 int err; 1885 + bool en; 1896 1886 1897 1887 blk_num = attr_enable->nr; 1898 1888 1899 - err = kstrtouint(buf, 0, &en); 1889 + err = kstrtobool(buf, &en); 1900 1890 if (err < 0) 1901 1891 return err; 1902 1892 ··· 1917 1905 MLXBF_PMC_CRSPACE_PERFMON_CTL(pmc->block[blk_num].counters), 1918 1906 MLXBF_PMC_WRITE_REG_32, word); 1919 1907 } else { 1920 - if (en && en != 1) 1921 - return -EINVAL; 1922 - 1923 1908 err = mlxbf_pmc_config_l3_counters(blk_num, false, !!en); 1924 1909 if (err) 1925 1910 return err; 1926 1911 1927 - if (en == 1) { 1912 + if (en) { 1928 1913 err = mlxbf_pmc_config_l3_counters(blk_num, true, false); 1929 1914 if (err) 1930 1915 return err;
+2 -1
drivers/platform/x86/Makefile
··· 58 58 # Hewlett Packard Enterprise 59 59 obj-$(CONFIG_UV_SYSFS) += uv_sysfs.o 60 60 61 + obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o 62 + 61 63 # IBM Thinkpad and Lenovo 62 64 obj-$(CONFIG_IBM_RTL) += ibm_rtl.o 63 65 obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o ··· 130 128 obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o 131 129 132 130 # Platform drivers 133 - obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o 134 131 obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o 135 132 obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o 136 133 obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o
+17
drivers/platform/x86/dell/alienware-wmi-wmax.c
··· 90 90 91 91 static const struct dmi_system_id awcc_dmi_table[] __initconst = { 92 92 { 93 + .ident = "Alienware Area-51m", 94 + .matches = { 95 + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 96 + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m"), 97 + }, 98 + .driver_data = &generic_quirks, 99 + }, 100 + { 93 101 .ident = "Alienware Area-51m R2", 94 102 .matches = { 95 103 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 96 104 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"), 105 + }, 106 + .driver_data = &generic_quirks, 107 + }, 108 + { 109 + .ident = "Alienware m15 R5", 110 + .matches = { 111 + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 112 + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R5"), 97 113 }, 98 114 .driver_data = &generic_quirks, 99 115 }, ··· 249 233 }, 250 234 .driver_data = &g_series_quirks, 251 235 }, 236 + {} 252 237 }; 253 238 254 239 enum AWCC_GET_FAN_SENSORS_OPERATIONS {
+1
drivers/platform/x86/dell/dell-lis3lv02d.c
··· 49 49 DELL_LIS3LV02D_DMI_ENTRY("Latitude E6330", 0x29), 50 50 DELL_LIS3LV02D_DMI_ENTRY("Latitude E6430", 0x29), 51 51 DELL_LIS3LV02D_DMI_ENTRY("Precision 3540", 0x29), 52 + DELL_LIS3LV02D_DMI_ENTRY("Precision 3551", 0x29), 52 53 DELL_LIS3LV02D_DMI_ENTRY("Precision M6800", 0x29), 53 54 DELL_LIS3LV02D_DMI_ENTRY("Vostro V131", 0x1d), 54 55 DELL_LIS3LV02D_DMI_ENTRY("Vostro 5568", 0x29),
+7 -3
drivers/platform/x86/dell/dell-wmi-ddv.c
··· 689 689 690 690 dev_dbg(&data->wdev->dev, "Translation cache miss\n"); 691 691 692 - /* Perform a translation between a ACPI battery and a battery index */ 693 - 694 - ret = power_supply_get_property(battery, POWER_SUPPLY_PROP_SERIAL_NUMBER, &val); 692 + /* 693 + * Perform a translation between a ACPI battery and a battery index. 694 + * We have to use power_supply_get_property_direct() here because this 695 + * function will also get called from the callbacks of the power supply 696 + * extension. 697 + */ 698 + ret = power_supply_get_property_direct(battery, POWER_SUPPLY_PROP_SERIAL_NUMBER, &val); 695 699 if (ret < 0) 696 700 return ret; 697 701
+2 -2
drivers/platform/x86/ideapad-laptop.c
··· 1669 1669 priv->kbd_bl.led.name = "platform::" LED_FUNCTION_KBD_BACKLIGHT; 1670 1670 priv->kbd_bl.led.brightness_get = ideapad_kbd_bl_led_cdev_brightness_get; 1671 1671 priv->kbd_bl.led.brightness_set_blocking = ideapad_kbd_bl_led_cdev_brightness_set; 1672 - priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED; 1672 + priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED | LED_RETAIN_AT_SHUTDOWN; 1673 1673 1674 1674 err = led_classdev_register(&priv->platform_device->dev, &priv->kbd_bl.led); 1675 1675 if (err) ··· 1728 1728 priv->fn_lock.led.name = "platform::" LED_FUNCTION_FNLOCK; 1729 1729 priv->fn_lock.led.brightness_get = ideapad_fn_lock_led_cdev_get; 1730 1730 priv->fn_lock.led.brightness_set_blocking = ideapad_fn_lock_led_cdev_set; 1731 - priv->fn_lock.led.flags = LED_BRIGHT_HW_CHANGED; 1731 + priv->fn_lock.led.flags = LED_BRIGHT_HW_CHANGED | LED_RETAIN_AT_SHUTDOWN; 1732 1732 1733 1733 err = led_classdev_register(&priv->platform_device->dev, &priv->fn_lock.led); 1734 1734 if (err)
+21 -9
drivers/platform/x86/lenovo-wmi-hotkey-utilities.c
··· 122 122 return -EIO; 123 123 124 124 union acpi_object *obj __free(kfree) = output.pointer; 125 - if (obj && obj->type == ACPI_TYPE_INTEGER) 126 - led_version = obj->integer.value; 127 - else 125 + if (!obj || obj->type != ACPI_TYPE_INTEGER) 128 126 return -EIO; 129 127 130 - wpriv->cdev[led_type].max_brightness = LED_ON; 131 - wpriv->cdev[led_type].flags = LED_CORE_SUSPENDRESUME; 128 + led_version = obj->integer.value; 129 + 130 + /* 131 + * Output parameters define: 0 means mute LED is not supported, Non-zero means 132 + * mute LED can be supported. 133 + */ 134 + if (led_version == 0) 135 + return 0; 136 + 132 137 133 138 switch (led_type) { 134 139 case MIC_MUTE: 135 - if (led_version != WMI_LUD_SUPPORT_MICMUTE_LED_VER) 136 - return -EIO; 140 + if (led_version != WMI_LUD_SUPPORT_MICMUTE_LED_VER) { 141 + pr_warn("The MIC_MUTE LED of this device isn't supported.\n"); 142 + return 0; 143 + } 137 144 138 145 wpriv->cdev[led_type].name = "platform::micmute"; 139 146 wpriv->cdev[led_type].brightness_set_blocking = &lsh_wmi_micmute_led_set; 140 147 wpriv->cdev[led_type].default_trigger = "audio-micmute"; 141 148 break; 142 149 case AUDIO_MUTE: 143 - if (led_version != WMI_LUD_SUPPORT_AUDIOMUTE_LED_VER) 144 - return -EIO; 150 + if (led_version != WMI_LUD_SUPPORT_AUDIOMUTE_LED_VER) { 151 + pr_warn("The AUDIO_MUTE LED of this device isn't supported.\n"); 152 + return 0; 153 + } 145 154 146 155 wpriv->cdev[led_type].name = "platform::mute"; 147 156 wpriv->cdev[led_type].brightness_set_blocking = &lsh_wmi_audiomute_led_set; ··· 160 151 dev_err(dev, "Unknown LED type %d\n", led_type); 161 152 return -EINVAL; 162 153 } 154 + 155 + wpriv->cdev[led_type].max_brightness = LED_ON; 156 + wpriv->cdev[led_type].flags = LED_CORE_SUSPENDRESUME; 163 157 164 158 err = devm_led_classdev_register(dev, &wpriv->cdev[led_type]); 165 159 if (err < 0) {
+70 -12
drivers/power/supply/power_supply_core.c
··· 1235 1235 return false; 1236 1236 } 1237 1237 1238 - int power_supply_get_property(struct power_supply *psy, 1239 - enum power_supply_property psp, 1240 - union power_supply_propval *val) 1238 + static int __power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, 1239 + union power_supply_propval *val, bool use_extensions) 1241 1240 { 1242 1241 struct power_supply_ext_registration *reg; 1243 1242 ··· 1246 1247 return -ENODEV; 1247 1248 } 1248 1249 1249 - scoped_guard(rwsem_read, &psy->extensions_sem) { 1250 - power_supply_for_each_extension(reg, psy) { 1251 - if (power_supply_ext_has_property(reg->ext, psp)) 1250 + if (use_extensions) { 1251 + scoped_guard(rwsem_read, &psy->extensions_sem) { 1252 + power_supply_for_each_extension(reg, psy) { 1253 + if (!power_supply_ext_has_property(reg->ext, psp)) 1254 + continue; 1255 + 1252 1256 return reg->ext->get_property(psy, reg->ext, reg->data, psp, val); 1257 + } 1253 1258 } 1254 1259 } 1255 1260 ··· 1264 1261 else 1265 1262 return -EINVAL; 1266 1263 } 1264 + 1265 + int power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, 1266 + union power_supply_propval *val) 1267 + { 1268 + return __power_supply_get_property(psy, psp, val, true); 1269 + } 1267 1270 EXPORT_SYMBOL_GPL(power_supply_get_property); 1268 1271 1269 - int power_supply_set_property(struct power_supply *psy, 1270 - enum power_supply_property psp, 1271 - const union power_supply_propval *val) 1272 + /** 1273 + * power_supply_get_property_direct - Read a power supply property without checking for extensions 1274 + * @psy: The power supply 1275 + * @psp: The power supply property to read 1276 + * @val: The resulting value of the power supply property 1277 + * 1278 + * Read a power supply property without taking into account any power supply extensions registered 1279 + * on the given power supply. This is mostly useful for power supply extensions that want to access 1280 + * their own power supply as using power_supply_get_property() directly will result in a potential 1281 + * deadlock. 1282 + * 1283 + * Return: 0 on success or negative error code on failure. 1284 + */ 1285 + int power_supply_get_property_direct(struct power_supply *psy, enum power_supply_property psp, 1286 + union power_supply_propval *val) 1287 + { 1288 + return __power_supply_get_property(psy, psp, val, false); 1289 + } 1290 + EXPORT_SYMBOL_GPL(power_supply_get_property_direct); 1291 + 1292 + 1293 + static int __power_supply_set_property(struct power_supply *psy, enum power_supply_property psp, 1294 + const union power_supply_propval *val, bool use_extensions) 1272 1295 { 1273 1296 struct power_supply_ext_registration *reg; 1274 1297 1275 1298 if (atomic_read(&psy->use_cnt) <= 0) 1276 1299 return -ENODEV; 1277 1300 1278 - scoped_guard(rwsem_read, &psy->extensions_sem) { 1279 - power_supply_for_each_extension(reg, psy) { 1280 - if (power_supply_ext_has_property(reg->ext, psp)) { 1301 + if (use_extensions) { 1302 + scoped_guard(rwsem_read, &psy->extensions_sem) { 1303 + power_supply_for_each_extension(reg, psy) { 1304 + if (!power_supply_ext_has_property(reg->ext, psp)) 1305 + continue; 1306 + 1281 1307 if (reg->ext->set_property) 1282 1308 return reg->ext->set_property(psy, reg->ext, reg->data, 1283 1309 psp, val); ··· 1321 1289 1322 1290 return psy->desc->set_property(psy, psp, val); 1323 1291 } 1292 + 1293 + int power_supply_set_property(struct power_supply *psy, enum power_supply_property psp, 1294 + const union power_supply_propval *val) 1295 + { 1296 + return __power_supply_set_property(psy, psp, val, true); 1297 + } 1324 1298 EXPORT_SYMBOL_GPL(power_supply_set_property); 1299 + 1300 + /** 1301 + * power_supply_set_property_direct - Write a power supply property without checking for extensions 1302 + * @psy: The power supply 1303 + * @psp: The power supply property to write 1304 + * @val: The value to write to the power supply property 1305 + * 1306 + * Write a power supply property without taking into account any power supply extensions registered 1307 + * on the given power supply. This is mostly useful for power supply extensions that want to access 1308 + * their own power supply as using power_supply_set_property() directly will result in a potential 1309 + * deadlock. 1310 + * 1311 + * Return: 0 on success or negative error code on failure. 1312 + */ 1313 + int power_supply_set_property_direct(struct power_supply *psy, enum power_supply_property psp, 1314 + const union power_supply_propval *val) 1315 + { 1316 + return __power_supply_set_property(psy, psp, val, false); 1317 + } 1318 + EXPORT_SYMBOL_GPL(power_supply_set_property_direct); 1325 1319 1326 1320 int power_supply_property_is_writeable(struct power_supply *psy, 1327 1321 enum power_supply_property psp)
+4
drivers/power/supply/test_power.c
··· 259 259 static int test_power_battery_extmanufacture_year = 1234; 260 260 static int test_power_battery_exttemp_max = 1000; 261 261 static const enum power_supply_property test_power_battery_extprops[] = { 262 + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 262 263 POWER_SUPPLY_PROP_MANUFACTURE_YEAR, 263 264 POWER_SUPPLY_PROP_TEMP_MAX, 264 265 }; ··· 271 270 union power_supply_propval *val) 272 271 { 273 272 switch (psp) { 273 + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 274 + return power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 275 + val); 274 276 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 275 277 val->intval = test_power_battery_extmanufacture_year; 276 278 break;
+8
include/linux/power_supply.h
··· 888 888 extern int power_supply_get_property(struct power_supply *psy, 889 889 enum power_supply_property psp, 890 890 union power_supply_propval *val); 891 + int power_supply_get_property_direct(struct power_supply *psy, enum power_supply_property psp, 892 + union power_supply_propval *val); 891 893 #if IS_ENABLED(CONFIG_POWER_SUPPLY) 892 894 extern int power_supply_set_property(struct power_supply *psy, 893 895 enum power_supply_property psp, 894 896 const union power_supply_propval *val); 897 + int power_supply_set_property_direct(struct power_supply *psy, enum power_supply_property psp, 898 + const union power_supply_propval *val); 895 899 #else 896 900 static inline int power_supply_set_property(struct power_supply *psy, 897 901 enum power_supply_property psp, 898 902 const union power_supply_propval *val) 903 + { return 0; } 904 + static inline int power_supply_set_property_direct(struct power_supply *psy, 905 + enum power_supply_property psp, 906 + const union power_supply_propval *val) 899 907 { return 0; } 900 908 #endif 901 909 extern void power_supply_external_power_changed(struct power_supply *psy);