aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2009-12-30 02:59:23 -0500
committerLen Brown <len.brown@intel.com>2009-12-30 20:30:04 -0500
commitc504f8cb68eb0d6cde53ba043daff8cb34586493 (patch)
tree2d4500519867b0ff345c3e895d7fdb90739023a7 /drivers/acpi
parent6b7b284958d47b77d06745b36bc7f36dab769d9b (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')
-rw-r--r--drivers/acpi/video.c43
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");
78static int brightness_switch_enabled = 1; 78static int brightness_switch_enabled = 1;
79module_param(brightness_switch_enabled, bool, 0644); 79module_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 */
85static int allow_duplicates;
86module_param(allow_duplicates, bool, 0644);
87
81static int register_count = 0; 88static int register_count = 0;
82static int acpi_video_bus_add(struct acpi_device *device); 89static int acpi_video_bus_add(struct acpi_device *device);
83static int acpi_video_bus_remove(struct acpi_device *device, int type); 90static 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
2243static acpi_status
2244acpi_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
2236static int acpi_video_bus_add(struct acpi_device *device) 2264static 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)