From 3b5e634103a5471d74e55d774e53db3df5c7b650 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 6 Aug 2009 15:57:54 -0700 Subject: ACPI: video: remove unneeded memsets device->cap and video->cap are zeroed initially so we don't need to clear them again. Signed-off-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/video.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8851315ce858..a0cd0c7ee9e2 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -934,9 +934,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; } @@ -1039,7 +1036,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; } -- cgit v1.2.1 From 4e231fa4cbd3ff53fcb7d76eccd6fd86a152a95f Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 24 Jun 2009 15:17:36 +0800 Subject: ACPI video: ignore buggy _BQC _BQC doesn't return a value listed in _BCL method. http://bugzilla.kernel.org/show_bug.cgi?id=13511 ingore the buggy _BQC method in this case Signed-off-by: Vladimir Serbinenko Signed-off-by: Scott Howard Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0cd0c7ee9e2..2020907921cc 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -603,6 +603,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"; @@ -618,8 +619,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, } *level += bqc_offset_aml_bug_workaround; - device->brightness->curr = *level; - return 0; + 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? -- cgit v1.2.1 From 4b4fe3b62e8d88068083218d3e42c45223b51d29 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 8 Aug 2009 00:26:25 -0700 Subject: ACPI: video - fix potential crash when unloading thermal_cooling_device_register() returns error encoded in a pointer when it fails in which case we need to explictly set device->cdev to NULL so we don't try to unregister it when unloading. Signed-off-by: Dmitry Torokhov Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 2020907921cc..aab385188599 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -997,8 +997,18 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cdev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); - if (IS_ERR(device->cdev)) + if (IS_ERR(device->cdev)) { + /* + * Set cdev 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->cdev = NULL; return; + } dev_info(&device->dev->dev, "registered as cooling_device%d\n", device->cdev->id); -- cgit v1.2.1 From 4a703a8fe562824f269943d995ddff35077253a9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 29 Aug 2009 23:03:16 -0400 Subject: ACPI: video - rename cdev to cooling_dev -- syntax only Cdev name is normally used for ether class devices or character devices so rename member to avoid confusion for casual reader of the code. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown --- drivers/acpi/video.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index aab385188599..a8432c291f40 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -198,7 +198,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; }; @@ -387,20 +387,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; @@ -417,9 +417,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; @@ -995,29 +995,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 cdev to NULL so we don't crash trying to + * 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->cdev = NULL; + 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"); @@ -2020,13 +2020,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) acpi_video_device_notify); sysfs_remove_link(&device->backlight->dev.kobj, "device"); backlight_device_unregister(device->backlight); - 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); -- cgit v1.2.1 From 90c53ca426cb93d15eefea79dcf6bd15ad3ffeb4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 31 Aug 2009 12:39:54 -0400 Subject: ACPI video: work-around BIOS AML bug in _BQC _BQC on some laptops returns an uninitialized value when it's invoked for the first time. Set the laptop to the maximum backlight level in this case. http://bugzilla.kernel.org/attachment.cgi?id=22675 Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a8432c291f40..097f24c87d82 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -878,7 +878,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; @@ -900,15 +900,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; -- cgit v1.2.1