diff options
author | Zhang Rui <rui.zhang@intel.com> | 2009-12-30 02:59:23 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-30 20:30:04 -0500 |
commit | c504f8cb68eb0d6cde53ba043daff8cb34586493 (patch) | |
tree | 2d4500519867b0ff345c3e895d7fdb90739023a7 /drivers/acpi/video.c | |
parent | 6b7b284958d47b77d06745b36bc7f36dab769d9b (diff) |
ACPI video: Prune dupe video devices, unless "video.allow_duplicates"
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>
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 05dff631591c..45e6a29c8177 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -78,6 +78,13 @@ MODULE_LICENSE("GPL"); | |||
78 | static int brightness_switch_enabled = 1; | 78 | static int brightness_switch_enabled = 1; |
79 | module_param(brightness_switch_enabled, bool, 0644); | 79 | module_param(brightness_switch_enabled, bool, 0644); |
80 | 80 | ||
81 | /* | ||
82 | * By default, we don't allow duplicate ACPI video bus devices | ||
83 | * under the same VGA controller | ||
84 | */ | ||
85 | static int allow_duplicates; | ||
86 | module_param(allow_duplicates, bool, 0644); | ||
87 | |||
81 | static int register_count = 0; | 88 | static int register_count = 0; |
82 | static int acpi_video_bus_add(struct acpi_device *device); | 89 | static int acpi_video_bus_add(struct acpi_device *device); |
83 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 90 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
@@ -2233,11 +2240,47 @@ static int acpi_video_resume(struct acpi_device *device) | |||
2233 | return AE_OK; | 2240 | return AE_OK; |
2234 | } | 2241 | } |
2235 | 2242 | ||
2243 | static acpi_status | ||
2244 | acpi_video_bus_match(acpi_handle handle, u32 level, void *context, | ||
2245 | void **return_value) | ||
2246 | { | ||
2247 | struct acpi_device *device = context; | ||
2248 | struct acpi_device *sibling; | ||
2249 | int result; | ||
2250 | |||
2251 | if (handle == device->handle) | ||
2252 | return AE_CTRL_TERMINATE; | ||
2253 | |||
2254 | result = acpi_bus_get_device(handle, &sibling); | ||
2255 | if (result) | ||
2256 | return AE_OK; | ||
2257 | |||
2258 | if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) | ||
2259 | return AE_ALREADY_EXISTS; | ||
2260 | |||
2261 | return AE_OK; | ||
2262 | } | ||
2263 | |||
2236 | static int acpi_video_bus_add(struct acpi_device *device) | 2264 | static int acpi_video_bus_add(struct acpi_device *device) |
2237 | { | 2265 | { |
2238 | struct acpi_video_bus *video; | 2266 | struct acpi_video_bus *video; |
2239 | struct input_dev *input; | 2267 | struct input_dev *input; |
2240 | int error; | 2268 | int error; |
2269 | acpi_status status; | ||
2270 | |||
2271 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, | ||
2272 | device->parent->handle, 1, | ||
2273 | acpi_video_bus_match, NULL, | ||
2274 | device, NULL); | ||
2275 | if (status == AE_ALREADY_EXISTS) { | ||
2276 | printk(KERN_WARNING FW_BUG | ||
2277 | "Duplicate ACPI video bus devices for the" | ||
2278 | " same VGA controller, please try module " | ||
2279 | "parameter \"video.allow_duplicates=1\"" | ||
2280 | "if the current driver doesn't work.\n"); | ||
2281 | if (!allow_duplicates) | ||
2282 | return -ENODEV; | ||
2283 | } | ||
2241 | 2284 | ||
2242 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); | 2285 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
2243 | if (!video) | 2286 | if (!video) |