Merge branch 'bugzilla-13577-video' into release
[sfrench/cifs-2.6.git] / drivers / acpi / video.c
index 05dff631591c943918749aee95d86c474c781c62..b765790b32be1841d652d3e834c6013950700efc 100644 (file)
@@ -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);
@@ -999,8 +1006,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                sprintf(name, "acpi_video%d", count++);
                device->backlight = backlight_device_register(name,
                        NULL, device, &acpi_backlight_ops);
-               device->backlight->props.max_brightness = device->brightness->count-3;
                kfree(name);
+               if (IS_ERR(device->backlight))
+                       return;
+               device->backlight->props.max_brightness = device->brightness->count-3;
 
                result = sysfs_create_link(&device->backlight->dev.kobj,
                                           &device->dev->dev.kobj, "device");
@@ -1979,6 +1988,10 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
        unsigned long long level_current, level_next;
        int result = -EINVAL;
 
+       /* no warning message if acpi_backlight=vendor is used */
+       if (!acpi_video_backlight_support())
+               return 0;
+
        if (!device->brightness)
                goto out;
 
@@ -2233,11 +2246,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)