Commit 193a6dec authored by Len Brown's avatar Len Brown

Merge branch 'video' into release

Conflicts:
	drivers/acpi/video.c
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parents 53de5356 90c53ca4
...@@ -200,7 +200,7 @@ struct acpi_video_device { ...@@ -200,7 +200,7 @@ struct acpi_video_device {
struct acpi_device *dev; struct acpi_device *dev;
struct acpi_video_device_brightness *brightness; struct acpi_video_device_brightness *brightness;
struct backlight_device *backlight; struct backlight_device *backlight;
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cooling_dev;
struct output_device *output_dev; struct output_device *output_dev;
}; };
...@@ -389,20 +389,20 @@ static struct output_properties acpi_output_properties = { ...@@ -389,20 +389,20 @@ static struct output_properties acpi_output_properties = {
/* thermal cooling device callbacks */ /* 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) long *state)
{ {
struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata;
struct acpi_video_device *video = acpi_driver_data(device); struct acpi_video_device *video = acpi_driver_data(device);
*state = video->brightness->count - 3; *state = video->brightness->count - 3;
return 0; 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) long *state)
{ {
struct acpi_device *device = cdev->devdata; struct acpi_device *device = cooling_dev->devdata;
struct acpi_video_device *video = acpi_driver_data(device); struct acpi_video_device *video = acpi_driver_data(device);
unsigned long long level; unsigned long long level;
int offset; int offset;
...@@ -419,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned ...@@ -419,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
} }
static int 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); struct acpi_video_device *video = acpi_driver_data(device);
int level; int level;
...@@ -605,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, ...@@ -605,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level) unsigned long long *level)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
int i;
if (device->cap._BQC || device->cap._BCQ) { if (device->cap._BQC || device->cap._BCQ) {
char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
...@@ -620,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, ...@@ -620,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
} }
*level += bqc_offset_aml_bug_workaround; *level += bqc_offset_aml_bug_workaround;
device->brightness->curr = *level; for (i = 2; i < device->brightness->count; i++)
return 0; 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 { } else {
/* Fixme: /* Fixme:
* should we return an error or ignore this failure? * should we return an error or ignore this failure?
...@@ -872,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -872,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br->flags._BCM_use_index = br->flags._BCL_use_index; br->flags._BCM_use_index = br->flags._BCL_use_index;
/* _BQC uses INDEX while _BCL uses VALUE in some laptops */ /* _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) if (!device->cap._BQC)
goto set_level; goto set_level;
...@@ -894,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -894,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br->flags._BQC_use_index = (level == max_level ? 0 : 1); 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; goto set_level;
}
if (br->flags._BCL_reversed) if (br->flags._BCL_reversed)
level_old = (br->count - 1) - level_old; level_old = (br->count - 1) - level_old;
level_old = br->levels[level_old]; level = br->levels[level_old];
set_level: set_level:
result = acpi_video_device_lcd_set_level(device, level_old); result = acpi_video_device_lcd_set_level(device, level);
if (result) if (result)
goto out_free_levels; goto out_free_levels;
...@@ -936,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) ...@@ -936,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
{ {
acpi_handle h_dummy1; acpi_handle h_dummy1;
memset(&device->cap, 0, sizeof(device->cap));
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
device->cap._ADR = 1; device->cap._ADR = 1;
} }
...@@ -992,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) ...@@ -992,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
if (result) if (result)
printk(KERN_ERR PREFIX "Create sysfs link\n"); 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); 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; return;
}
dev_info(&device->dev->dev, "registered as cooling_device%d\n", 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, result = sysfs_create_link(&device->dev->dev.kobj,
&device->cdev->device.kobj, &device->cooling_dev->device.kobj,
"thermal_cooling"); "thermal_cooling");
if (result) if (result)
printk(KERN_ERR PREFIX "Create sysfs link\n"); 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"); &device->dev->dev.kobj, "device");
if (result) if (result)
printk(KERN_ERR PREFIX "Create sysfs link\n"); printk(KERN_ERR PREFIX "Create sysfs link\n");
...@@ -1041,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) ...@@ -1041,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
{ {
acpi_handle h_dummy1; acpi_handle h_dummy1;
memset(&video->cap, 0, sizeof(video->cap));
if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
video->cap._DOS = 1; video->cap._DOS = 1;
} }
...@@ -2011,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) ...@@ -2011,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
backlight_device_unregister(device->backlight); backlight_device_unregister(device->backlight);
device->backlight = NULL; device->backlight = NULL;
} }
if (device->cdev) { if (device->cooling_dev) {
sysfs_remove_link(&device->dev->dev.kobj, sysfs_remove_link(&device->dev->dev.kobj,
"thermal_cooling"); "thermal_cooling");
sysfs_remove_link(&device->cdev->device.kobj, sysfs_remove_link(&device->cooling_dev->device.kobj,
"device"); "device");
thermal_cooling_device_unregister(device->cdev); thermal_cooling_device_unregister(device->cooling_dev);
device->cdev = NULL; device->cooling_dev = NULL;
} }
video_output_unregister(device->output_dev); video_output_unregister(device->output_dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment