diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 3c9ef826551d..e835779b6f5f 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1618,6 +1618,8 @@ static DEVICE_ATTR_RW(charge_control_end_threshold); static int asus_wmi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) { + int ret, rv; + /* The WMI method does not provide a way to specific a battery, so we * just assume it is the first battery. * Note: On some newer ASUS laptops (Zenbook UM431DA), the primary/first @@ -1635,12 +1637,30 @@ static int asus_wmi_battery_add(struct power_supply *battery, struct acpi_batter /* The charge threshold is only reset when the system is power cycled, * and we can't read the current threshold, however the majority of - * platforms retains it, therefore signal the threshold as unknown - * until user explicitly sets it to a new value. + * platforms retains it. + * + * Setting a negative value would signal the threshold as unknown + * until user explicitly sets it to a new value, however to avoid + * regressing userspace, we initialize it to a value of 100. */ - charge_end_threshold = -1; + charge_end_threshold = 100; + ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, charge_end_threshold, &rv); + if (ret) { + pr_err("Failed to reset battery charge threshold\n"); + goto asus_wmi_battery_add_err; + } + + if (rv != 1) { + pr_err("Error in battery charge threshold reset\n"); + ret = -EIO; + goto asus_wmi_battery_add_err; + } return 0; +asus_wmi_battery_add_err: + device_remove_file(&battery->dev, + &dev_attr_charge_control_end_threshold); + return ret; } static int asus_wmi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c index 3ae4557b32b4..5ab2215fdd7f 100644 --- a/drivers/platform/x86/intel/vsec.c +++ b/drivers/platform/x86/intel/vsec.c @@ -103,6 +103,12 @@ static void intel_vsec_remove_aux(void *data) auxiliary_device_uninit(data); } +static void intel_vsec_dev_free(struct intel_vsec_device *intel_vsec_dev) +{ + kfree(intel_vsec_dev->acpi_disc); + kfree(intel_vsec_dev); +} + static void intel_vsec_dev_release(struct device *dev) { struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); @@ -111,8 +117,7 @@ static void intel_vsec_dev_release(struct device *dev) ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); - kfree(intel_vsec_dev->acpi_disc); - kfree(intel_vsec_dev); + intel_vsec_dev_free(intel_vsec_dev); } static const struct vsec_feature_dependency * @@ -218,20 +223,22 @@ int intel_vsec_add_aux(struct device *parent, struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; int ret, id; - if (!parent) + if (!parent) { + intel_vsec_dev_free(intel_vsec_dev); return -EINVAL; + } ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, PMT_XA_LIMIT, GFP_KERNEL); if (ret < 0) { - kfree(intel_vsec_dev); + intel_vsec_dev_free(intel_vsec_dev); return ret; } id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); if (id < 0) { xa_erase(&auxdev_array, intel_vsec_dev->id); - kfree(intel_vsec_dev); + intel_vsec_dev_free(intel_vsec_dev); return id; }