Skip to content

Commit

Permalink
ACPI video: Prune dupe video devices, unless "video.allow_duplicates"
Browse files Browse the repository at this point in the history
Some buggy BIOS exports multiple ACPI video bus devices for the same
VGA controller, and multiple backlight control methods as well.
This messes up the ACPI video backlight control.

http://bugzilla.kernel.org/show_bug.cgi?id=13577

With this patch applied, only the FIRST ACPI video bus device
under a PCI device node is bind to ACPI video driver by default.

If the first ACPI video bus device doesn't work well, we can use
video.allow_duplicates=1 to go back to the old behavior.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Zhang Rui authored and Len Brown committed Dec 31, 2009
1 parent 6b7b284 commit c504f8c
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions drivers/acpi/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ MODULE_LICENSE("GPL");
static int brightness_switch_enabled = 1;
module_param(brightness_switch_enabled, bool, 0644);

/*
* By default, we don't allow duplicate ACPI video bus devices
* under the same VGA controller
*/
static int allow_duplicates;
module_param(allow_duplicates, bool, 0644);

static int register_count = 0;
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
Expand Down Expand Up @@ -2233,11 +2240,47 @@ static int acpi_video_resume(struct acpi_device *device)
return AE_OK;
}

static acpi_status
acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
void **return_value)
{
struct acpi_device *device = context;
struct acpi_device *sibling;
int result;

if (handle == device->handle)
return AE_CTRL_TERMINATE;

result = acpi_bus_get_device(handle, &sibling);
if (result)
return AE_OK;

if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
return AE_ALREADY_EXISTS;

return AE_OK;
}

static int acpi_video_bus_add(struct acpi_device *device)
{
struct acpi_video_bus *video;
struct input_dev *input;
int error;
acpi_status status;

status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
device->parent->handle, 1,
acpi_video_bus_match, NULL,
device, NULL);
if (status == AE_ALREADY_EXISTS) {
printk(KERN_WARNING FW_BUG
"Duplicate ACPI video bus devices for the"
" same VGA controller, please try module "
"parameter \"video.allow_duplicates=1\""
"if the current driver doesn't work.\n");
if (!allow_duplicates)
return -ENODEV;
}

video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
if (!video)
Expand Down

0 comments on commit c504f8c

Please sign in to comment.