Loading drivers/acpi/video.c +50 −26 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ struct acpi_video_device { struct acpi_device *dev; struct acpi_video_device_brightness *brightness; struct backlight_device *backlight; struct thermal_cooling_device *cdev; struct thermal_cooling_device *cooling_dev; struct output_device *output_dev; }; Loading Loading @@ -389,20 +389,20 @@ static struct output_properties acpi_output_properties = { /* thermal cooling device callbacks */ static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); *state = video->brightness->count - 3; return 0; } static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); unsigned long long level; int offset; Loading @@ -419,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned } static int video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); int level; Loading Loading @@ -605,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long long *level) { acpi_status status = AE_OK; int i; if (device->cap._BQC || device->cap._BCQ) { char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; Loading @@ -620,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, } *level += bqc_offset_aml_bug_workaround; for (i = 2; i < device->brightness->count; i++) if (device->brightness->levels[i] == *level) { device->brightness->curr = *level; return 0; } /* BQC returned an invalid level. Stop using it. */ ACPI_WARNING((AE_INFO, "%s returned an invalid level", buf)); device->cap._BQC = device->cap._BCQ = 0; } else { /* Fixme: * should we return an error or ignore this failure? Loading Loading @@ -872,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->flags._BCM_use_index = br->flags._BCL_use_index; /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ br->curr = level_old = max_level; br->curr = level = max_level; if (!device->cap._BQC) goto set_level; Loading @@ -894,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->flags._BQC_use_index = (level == max_level ? 0 : 1); if (!br->flags._BQC_use_index) if (!br->flags._BQC_use_index) { /* * Set the backlight to the initial state. * On some buggy laptops, _BQC returns an uninitialized value * when invoked for the first time, i.e. level_old is invalid. * set the backlight to max_level in this case */ for (i = 2; i < br->count; i++) if (level_old == br->levels[i]) level = level_old; goto set_level; } if (br->flags._BCL_reversed) level_old = (br->count - 1) - level_old; level_old = br->levels[level_old]; level = br->levels[level_old]; set_level: result = acpi_video_device_lcd_set_level(device, level_old); result = acpi_video_device_lcd_set_level(device, level); if (result) goto out_free_levels; Loading Loading @@ -936,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) { acpi_handle h_dummy1; memset(&device->cap, 0, sizeof(device->cap)); if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { device->cap._ADR = 1; } Loading Loading @@ -992,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); device->cdev = thermal_cooling_device_register("LCD", device->cooling_dev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); if (IS_ERR(device->cdev)) if (IS_ERR(device->cooling_dev)) { /* * Set cooling_dev to NULL so we don't crash trying to * free it. * Also, why the hell we are returning early and * not attempt to register video output if cooling * device registration failed? * -- dtor */ device->cooling_dev = NULL; return; } dev_info(&device->dev->dev, "registered as cooling_device%d\n", device->cdev->id); device->cooling_dev->id); result = sysfs_create_link(&device->dev->dev.kobj, &device->cdev->device.kobj, &device->cooling_dev->device.kobj, "thermal_cooling"); if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); result = sysfs_create_link(&device->cdev->device.kobj, result = sysfs_create_link(&device->cooling_dev->device.kobj, &device->dev->dev.kobj, "device"); if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); Loading Loading @@ -1041,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) { acpi_handle h_dummy1; memset(&video->cap, 0, sizeof(video->cap)); if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { video->cap._DOS = 1; } Loading Loading @@ -2011,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) backlight_device_unregister(device->backlight); device->backlight = NULL; } if (device->cdev) { if (device->cooling_dev) { sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->cdev->device.kobj, sysfs_remove_link(&device->cooling_dev->device.kobj, "device"); thermal_cooling_device_unregister(device->cdev); device->cdev = NULL; thermal_cooling_device_unregister(device->cooling_dev); device->cooling_dev = NULL; } video_output_unregister(device->output_dev); Loading Loading
drivers/acpi/video.c +50 −26 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ struct acpi_video_device { struct acpi_device *dev; struct acpi_video_device_brightness *brightness; struct backlight_device *backlight; struct thermal_cooling_device *cdev; struct thermal_cooling_device *cooling_dev; struct output_device *output_dev; }; Loading Loading @@ -389,20 +389,20 @@ static struct output_properties acpi_output_properties = { /* thermal cooling device callbacks */ static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); *state = video->brightness->count - 3; return 0; } static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); unsigned long long level; int offset; Loading @@ -419,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned } static int video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) { struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata; struct acpi_video_device *video = acpi_driver_data(device); int level; Loading Loading @@ -605,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long long *level) { acpi_status status = AE_OK; int i; if (device->cap._BQC || device->cap._BCQ) { char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; Loading @@ -620,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, } *level += bqc_offset_aml_bug_workaround; for (i = 2; i < device->brightness->count; i++) if (device->brightness->levels[i] == *level) { device->brightness->curr = *level; return 0; } /* BQC returned an invalid level. Stop using it. */ ACPI_WARNING((AE_INFO, "%s returned an invalid level", buf)); device->cap._BQC = device->cap._BCQ = 0; } else { /* Fixme: * should we return an error or ignore this failure? Loading Loading @@ -872,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->flags._BCM_use_index = br->flags._BCL_use_index; /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ br->curr = level_old = max_level; br->curr = level = max_level; if (!device->cap._BQC) goto set_level; Loading @@ -894,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->flags._BQC_use_index = (level == max_level ? 0 : 1); if (!br->flags._BQC_use_index) if (!br->flags._BQC_use_index) { /* * Set the backlight to the initial state. * On some buggy laptops, _BQC returns an uninitialized value * when invoked for the first time, i.e. level_old is invalid. * set the backlight to max_level in this case */ for (i = 2; i < br->count; i++) if (level_old == br->levels[i]) level = level_old; goto set_level; } if (br->flags._BCL_reversed) level_old = (br->count - 1) - level_old; level_old = br->levels[level_old]; level = br->levels[level_old]; set_level: result = acpi_video_device_lcd_set_level(device, level_old); result = acpi_video_device_lcd_set_level(device, level); if (result) goto out_free_levels; Loading Loading @@ -936,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) { acpi_handle h_dummy1; memset(&device->cap, 0, sizeof(device->cap)); if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { device->cap._ADR = 1; } Loading Loading @@ -992,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); device->cdev = thermal_cooling_device_register("LCD", device->cooling_dev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); if (IS_ERR(device->cdev)) if (IS_ERR(device->cooling_dev)) { /* * Set cooling_dev to NULL so we don't crash trying to * free it. * Also, why the hell we are returning early and * not attempt to register video output if cooling * device registration failed? * -- dtor */ device->cooling_dev = NULL; return; } dev_info(&device->dev->dev, "registered as cooling_device%d\n", device->cdev->id); device->cooling_dev->id); result = sysfs_create_link(&device->dev->dev.kobj, &device->cdev->device.kobj, &device->cooling_dev->device.kobj, "thermal_cooling"); if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); result = sysfs_create_link(&device->cdev->device.kobj, result = sysfs_create_link(&device->cooling_dev->device.kobj, &device->dev->dev.kobj, "device"); if (result) printk(KERN_ERR PREFIX "Create sysfs link\n"); Loading Loading @@ -1041,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) { acpi_handle h_dummy1; memset(&video->cap, 0, sizeof(video->cap)); if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { video->cap._DOS = 1; } Loading Loading @@ -2011,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) backlight_device_unregister(device->backlight); device->backlight = NULL; } if (device->cdev) { if (device->cooling_dev) { sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->cdev->device.kobj, sysfs_remove_link(&device->cooling_dev->device.kobj, "device"); thermal_cooling_device_unregister(device->cdev); device->cdev = NULL; thermal_cooling_device_unregister(device->cooling_dev); device->cooling_dev = NULL; } video_output_unregister(device->output_dev); Loading