diff options
author | Danny Kukawka <dkukawka@suse.de> | 2007-07-03 01:33:53 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-07-03 01:33:53 -0400 |
commit | f70ac0e9651aa8c07dffe72a44872f92054d42c3 (patch) | |
tree | c748973de21f228021e270cb5764029641d4d501 /drivers/acpi | |
parent | 23b0f015bf2c050b8b5399430ca64e1b3398cf76 (diff) |
ACPI video: Don't export sysfs backlight interface if query _BCL fail
Currently the acpi video module export the backlight interface to sysfs
also if acpi_video_device_lcd_query_levels() fails to read _BLC method
(e.g. because the method is not available). In this case the userspace
don't know which brightness level are supported and can't set a brightness
level (echo return with: "write error: Invalid Argument"). This happend
e.g. on a ASUS RF1 (correct supported by the asus-laptop module).
The video module should not export the backlight interface if query _BLC fail,
because you can't set anything from userspace and this make it useless.
http://bugzilla.kernel.org/show_bug.cgi?id=8375
Signed-off-by: Danny Kukawka <dkukawka@suse.de>
Acked-by: Luming Yu <luming.yu@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/video.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 39273dae7004..5f014d3764c8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -559,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | |||
559 | 559 | ||
560 | static void acpi_video_device_find_cap(struct acpi_video_device *device) | 560 | static void acpi_video_device_find_cap(struct acpi_video_device *device) |
561 | { | 561 | { |
562 | acpi_integer status; | ||
563 | acpi_handle h_dummy1; | 562 | acpi_handle h_dummy1; |
564 | int i; | 563 | int i; |
565 | u32 max_level = 0; | 564 | u32 max_level = 0; |
@@ -593,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
593 | device->cap._DSS = 1; | 592 | device->cap._DSS = 1; |
594 | } | 593 | } |
595 | 594 | ||
596 | status = acpi_video_device_lcd_query_levels(device, &obj); | 595 | if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
597 | 596 | ||
598 | if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { | 597 | if (obj->package.count >= 2) { |
599 | int count = 0; | 598 | int count = 0; |
600 | union acpi_object *o; | 599 | union acpi_object *o; |
601 | 600 | ||
602 | br = kzalloc(sizeof(*br), GFP_KERNEL); | 601 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
603 | if (!br) { | 602 | if (!br) { |
604 | printk(KERN_ERR "can't allocate memory\n"); | 603 | printk(KERN_ERR "can't allocate memory\n"); |
605 | } else { | ||
606 | br->levels = kmalloc(obj->package.count * | ||
607 | sizeof *(br->levels), GFP_KERNEL); | ||
608 | if (!br->levels) | ||
609 | goto out; | ||
610 | |||
611 | for (i = 0; i < obj->package.count; i++) { | ||
612 | o = (union acpi_object *)&obj->package. | ||
613 | elements[i]; | ||
614 | if (o->type != ACPI_TYPE_INTEGER) { | ||
615 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
616 | continue; | ||
617 | } | ||
618 | br->levels[count] = (u32) o->integer.value; | ||
619 | if (br->levels[count] > max_level) | ||
620 | max_level = br->levels[count]; | ||
621 | count++; | ||
622 | } | ||
623 | out: | ||
624 | if (count < 2) { | ||
625 | kfree(br->levels); | ||
626 | kfree(br); | ||
627 | } else { | 604 | } else { |
628 | br->count = count; | 605 | br->levels = kmalloc(obj->package.count * |
629 | device->brightness = br; | 606 | sizeof *(br->levels), GFP_KERNEL); |
630 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 607 | if (!br->levels) |
631 | "found %d brightness levels\n", | 608 | goto out; |
632 | count)); | 609 | |
610 | for (i = 0; i < obj->package.count; i++) { | ||
611 | o = (union acpi_object *)&obj->package. | ||
612 | elements[i]; | ||
613 | if (o->type != ACPI_TYPE_INTEGER) { | ||
614 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
615 | continue; | ||
616 | } | ||
617 | br->levels[count] = (u32) o->integer.value; | ||
618 | |||
619 | if (br->levels[count] > max_level) | ||
620 | max_level = br->levels[count]; | ||
621 | count++; | ||
622 | } | ||
623 | out: | ||
624 | if (count < 2) { | ||
625 | kfree(br->levels); | ||
626 | kfree(br); | ||
627 | } else { | ||
628 | br->count = count; | ||
629 | device->brightness = br; | ||
630 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
631 | "found %d brightness levels\n", | ||
632 | count)); | ||
633 | } | ||
633 | } | 634 | } |
634 | } | 635 | } |
636 | |||
637 | } else { | ||
638 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); | ||
635 | } | 639 | } |
636 | 640 | ||
637 | kfree(obj); | 641 | kfree(obj); |
638 | 642 | ||
639 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ | 643 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ |
640 | unsigned long tmp; | 644 | unsigned long tmp; |
641 | static int count = 0; | 645 | static int count = 0; |
642 | char *name; | 646 | char *name; |