mirror of https://github.com/torvalds/linux.git
Merge branches 'acpi-button', 'acpi-video' and 'acpi-fan'
Merge ACPI button, ACPI backlight (video), and ACPI fan driver fixes for 6.18-rc4: - Call input_free_device() on failing input device registration as necessary (and mentioned in the input subsystem documentation) in the ACPI button driver (Kaushlendra Kumar) - Fix use-after-free in acpi_video_switch_brightness() by canceling a delayed work during tear-down (Yuhao Jiang) - Use platform device for devres-related actions in the ACPI fan driver to allow device-managed resources to be cleaned up properly (Armin Wolf) * acpi-button: ACPI: button: Call input_free_device() on failing input device registration * acpi-video: ACPI: video: Fix use-after-free in acpi_video_switch_brightness() * acpi-fan: ACPI: fan: Use platform device for devres-related actions ACPI: fan: Use ACPI handle when retrieving _FST
This commit is contained in:
commit
8907226bed
|
|
@ -1959,8 +1959,10 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)
|
|||
struct acpi_video_device *dev;
|
||||
|
||||
mutex_lock(&video->device_list_lock);
|
||||
list_for_each_entry(dev, &video->video_device_list, entry)
|
||||
list_for_each_entry(dev, &video->video_device_list, entry) {
|
||||
acpi_video_dev_remove_notify_handler(dev);
|
||||
cancel_delayed_work_sync(&dev->switch_brightness_work);
|
||||
}
|
||||
mutex_unlock(&video->device_list_lock);
|
||||
|
||||
acpi_video_bus_stop_devices(video);
|
||||
|
|
|
|||
|
|
@ -619,8 +619,10 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
|
||||
input_set_drvdata(input, device);
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
if (error) {
|
||||
input_free_device(input);
|
||||
goto err_remove_fs;
|
||||
}
|
||||
|
||||
switch (device->device_type) {
|
||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct acpi_fan_fst {
|
|||
};
|
||||
|
||||
struct acpi_fan {
|
||||
acpi_handle handle;
|
||||
bool acpi4;
|
||||
bool has_fst;
|
||||
struct acpi_fan_fif fif;
|
||||
|
|
@ -59,14 +60,14 @@ struct acpi_fan {
|
|||
struct device_attribute fine_grain_control;
|
||||
};
|
||||
|
||||
int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst);
|
||||
int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst);
|
||||
int acpi_fan_create_attributes(struct acpi_device *device);
|
||||
void acpi_fan_delete_attributes(struct acpi_device *device);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
int devm_acpi_fan_create_hwmon(struct acpi_device *device);
|
||||
int devm_acpi_fan_create_hwmon(struct device *dev);
|
||||
#else
|
||||
static inline int devm_acpi_fan_create_hwmon(struct acpi_device *device) { return 0; };
|
||||
static inline int devm_acpi_fan_create_hwmon(struct device *dev) { return 0; };
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr,
|
|||
struct acpi_fan_fst fst;
|
||||
int status;
|
||||
|
||||
status = acpi_fan_get_fst(acpi_dev, &fst);
|
||||
status = acpi_fan_get_fst(acpi_dev->handle, &fst);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,25 +44,30 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
|
|||
return 0;
|
||||
}
|
||||
|
||||
int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst)
|
||||
int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
int ret = 0;
|
||||
|
||||
status = acpi_evaluate_object(device->handle, "_FST", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev, "Get fan state failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
status = acpi_evaluate_object(handle, "_FST", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
obj = buffer.pointer;
|
||||
if (!obj || obj->type != ACPI_TYPE_PACKAGE ||
|
||||
obj->package.count != 3 ||
|
||||
obj->package.elements[1].type != ACPI_TYPE_INTEGER) {
|
||||
dev_err(&device->dev, "Invalid _FST data\n");
|
||||
ret = -EINVAL;
|
||||
if (!obj)
|
||||
return -ENODATA;
|
||||
|
||||
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) {
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
obj->package.elements[1].type != ACPI_TYPE_INTEGER ||
|
||||
obj->package.elements[2].type != ACPI_TYPE_INTEGER) {
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +86,7 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
|
|||
struct acpi_fan_fst fst;
|
||||
int status, i;
|
||||
|
||||
status = acpi_fan_get_fst(device, &fst);
|
||||
status = acpi_fan_get_fst(device->handle, &fst);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
|
@ -311,11 +316,16 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
|
||||
char *name;
|
||||
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
|
||||
fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
|
||||
if (!fan) {
|
||||
dev_err(&device->dev, "No memory for fan\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fan->handle = device->handle;
|
||||
device->driver_data = fan;
|
||||
platform_set_drvdata(pdev, fan);
|
||||
|
||||
|
|
@ -337,7 +347,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (fan->has_fst) {
|
||||
result = devm_acpi_fan_create_hwmon(device);
|
||||
result = devm_acpi_fan_create_hwmon(&pdev->dev);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,13 +93,12 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_
|
|||
static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
|
||||
int channel, long *val)
|
||||
{
|
||||
struct acpi_device *adev = to_acpi_device(dev->parent);
|
||||
struct acpi_fan *fan = dev_get_drvdata(dev);
|
||||
struct acpi_fan_fps *fps;
|
||||
struct acpi_fan_fst fst;
|
||||
int ret;
|
||||
|
||||
ret = acpi_fan_get_fst(adev, &fst);
|
||||
ret = acpi_fan_get_fst(fan->handle, &fst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -167,12 +166,12 @@ static const struct hwmon_chip_info acpi_fan_hwmon_chip_info = {
|
|||
.info = acpi_fan_hwmon_info,
|
||||
};
|
||||
|
||||
int devm_acpi_fan_create_hwmon(struct acpi_device *device)
|
||||
int devm_acpi_fan_create_hwmon(struct device *dev)
|
||||
{
|
||||
struct acpi_fan *fan = acpi_driver_data(device);
|
||||
struct acpi_fan *fan = dev_get_drvdata(dev);
|
||||
struct device *hdev;
|
||||
|
||||
hdev = devm_hwmon_device_register_with_info(&device->dev, "acpi_fan", fan,
|
||||
&acpi_fan_hwmon_chip_info, NULL);
|
||||
hdev = devm_hwmon_device_register_with_info(dev, "acpi_fan", fan, &acpi_fan_hwmon_chip_info,
|
||||
NULL);
|
||||
return PTR_ERR_OR_ZERO(hdev);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue