Commit f398778aa336a2919ee04ba45d915007230c6957

Authored by Len Brown

Merge branch 'video' into release

Conflicts:
	Documentation/kernel-parameters.txt

Signed-off-by: Len Brown <len.brown@intel.com>

Showing 16 changed files Side-by-side Diff

Documentation/kernel-parameters.txt
... ... @@ -198,6 +198,18 @@
198 198 that require a timer override, but don't have
199 199 HPET
200 200  
  201 + acpi_backlight= [HW,ACPI]
  202 + acpi_backlight=vendor
  203 + acpi_backlight=video
  204 + If set to vendor, prefer vendor specific driver
  205 + (e.g. thinkpad_acpi, sony_acpi, etc.) instead
  206 + of the ACPI video.ko driver.
  207 +
  208 + acpi_display_output= [HW,ACPI]
  209 + acpi_display_output=vendor
  210 + acpi_display_output=video
  211 + See above.
  212 +
201 213 acpi.debug_layer= [HW,ACPI,ACPI_DEBUG]
202 214 acpi.debug_level= [HW,ACPI,ACPI_DEBUG]
203 215 Format: <int>
drivers/acpi/Makefile
... ... @@ -46,6 +46,10 @@
46 46 obj-$(CONFIG_ACPI_FAN) += fan.o
47 47 obj-$(CONFIG_ACPI_DOCK) += dock.o
48 48 obj-$(CONFIG_ACPI_VIDEO) += video.o
  49 +ifdef CONFIG_ACPI_VIDEO
  50 +obj-y += video_detect.o
  51 +endif
  52 +
49 53 obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
50 54 obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
51 55 obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
... ... @@ -140,6 +140,46 @@
140 140  
141 141 EXPORT_SYMBOL(acpi_get_physical_device);
142 142  
  143 +/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge
  144 + * This should work in general, but did not on a Lenovo T61 for the
  145 + * graphics card. But this must be fixed when the PCI device is
  146 + * bound and the kernel device struct is attached to the acpi device
  147 + * Note: A success call will increase reference count by one
  148 + * Do call put_device(dev) on the returned device then
  149 + */
  150 +struct device *acpi_get_physical_pci_device(acpi_handle handle)
  151 +{
  152 + struct device *dev;
  153 + long long device_id;
  154 + acpi_status status;
  155 +
  156 + status =
  157 + acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
  158 +
  159 + if (ACPI_FAILURE(status))
  160 + return NULL;
  161 +
  162 + /* We need to attempt to determine whether the _ADR refers to a
  163 + PCI device or not. There's no terribly good way to do this,
  164 + so the best we can hope for is to assume that there'll never
  165 + be a device in the host bridge */
  166 + if (device_id >= 0x10000) {
  167 + /* It looks like a PCI device. Does it exist? */
  168 + dev = acpi_get_physical_device(handle);
  169 + } else {
  170 + /* It doesn't look like a PCI device. Does its parent
  171 + exist? */
  172 + acpi_handle phandle;
  173 + if (acpi_get_parent(handle, &phandle))
  174 + return NULL;
  175 + dev = acpi_get_physical_device(phandle);
  176 + }
  177 + if (!dev)
  178 + return NULL;
  179 + return dev;
  180 +}
  181 +EXPORT_SYMBOL(acpi_get_physical_pci_device);
  182 +
143 183 static int acpi_bind_one(struct device *dev, acpi_handle handle)
144 184 {
145 185 struct acpi_device *acpi_dev;
... ... @@ -919,36 +919,6 @@
919 919 }
920 920 }
921 921  
922   -static int
923   -acpi_video_bus_match(struct acpi_device *device)
924   -{
925   - acpi_handle h_dummy;
926   -
927   - if (!device)
928   - return -EINVAL;
929   -
930   - /* Since there is no HID, CID for ACPI Video drivers, we have
931   - * to check well known required nodes for each feature we support.
932   - */
933   -
934   - /* Does this device able to support video switching ? */
935   - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
936   - ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
937   - return 0;
938   -
939   - /* Does this device able to retrieve a video ROM ? */
940   - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
941   - return 0;
942   -
943   - /* Does this device able to configure which video head to be POSTed ? */
944   - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
945   - ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
946   - ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
947   - return 0;
948   -
949   - return -ENODEV;
950   -}
951   -
952 922 /*
953 923 * acpi_bay_match - see if a device is an ejectable driver bay
954 924 *
... ... @@ -1031,7 +1001,7 @@
1031 1001 will get autoloaded and the device might still match
1032 1002 against another driver.
1033 1003 */
1034   - if (ACPI_SUCCESS(acpi_video_bus_match(device)))
  1004 + if (acpi_is_video_device(device))
1035 1005 cid_add = ACPI_VIDEO_HID;
1036 1006 else if (ACPI_SUCCESS(acpi_bay_match(device)))
1037 1007 cid_add = ACPI_BAY_HID;
drivers/acpi/video.c
... ... @@ -738,7 +738,8 @@
738 738 device->cap._DSS = 1;
739 739 }
740 740  
741   - max_level = acpi_video_init_brightness(device);
  741 + if (acpi_video_backlight_support())
  742 + max_level = acpi_video_init_brightness(device);
742 743  
743 744 if (device->cap._BCL && device->cap._BCM && max_level > 0) {
744 745 int result;
745 746  
... ... @@ -784,18 +785,21 @@
784 785 printk(KERN_ERR PREFIX "Create sysfs link\n");
785 786  
786 787 }
787   - if (device->cap._DCS && device->cap._DSS){
788   - static int count = 0;
789   - char *name;
790   - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
791   - if (!name)
792   - return;
793   - sprintf(name, "acpi_video%d", count++);
794   - device->output_dev = video_output_register(name,
795   - NULL, device, &acpi_output_properties);
796   - kfree(name);
  788 +
  789 + if (acpi_video_display_switch_support()) {
  790 +
  791 + if (device->cap._DCS && device->cap._DSS) {
  792 + static int count;
  793 + char *name;
  794 + name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
  795 + if (!name)
  796 + return;
  797 + sprintf(name, "acpi_video%d", count++);
  798 + device->output_dev = video_output_register(name,
  799 + NULL, device, &acpi_output_properties);
  800 + kfree(name);
  801 + }
797 802 }
798   - return;
799 803 }
800 804  
801 805 /*
802 806  
803 807  
... ... @@ -841,10 +845,15 @@
841 845 static int acpi_video_bus_check(struct acpi_video_bus *video)
842 846 {
843 847 acpi_status status = -ENOENT;
  848 + struct device *dev;
844 849  
845   -
846 850 if (!video)
847 851 return -EINVAL;
  852 +
  853 + dev = acpi_get_physical_pci_device(video->device->handle);
  854 + if (!dev)
  855 + return -ENODEV;
  856 + put_device(dev);
848 857  
849 858 /* Since there is no HID, CID and so on for VGA driver, we have
850 859 * to check well known required nodes.
drivers/acpi/video_detect.c
  1 +/*
  2 + * Copyright (C) 2008 SuSE Linux Products GmbH
  3 + * Thomas Renninger <trenn@suse.de>
  4 + *
  5 + * May be copied or modified under the terms of the GNU General Public License
  6 + *
  7 + * video_detect.c:
  8 + * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
  9 + * There a Linux specific (Spec does not provide a HID for video devices) is
  10 + * assinged
  11 + *
  12 + * After PCI devices are glued with ACPI devices
  13 + * acpi_get_physical_pci_device() can be called to identify ACPI graphics
  14 + * devices for which a real graphics card is plugged in
  15 + *
  16 + * Now acpi_video_get_capabilities() can be called to check which
  17 + * capabilities the graphics cards plugged in support. The check for general
  18 + * video capabilities will be triggered by the first caller of
  19 + * acpi_video_get_capabilities(NULL); which will happen when the first
  20 + * backlight (or display output) switching supporting driver calls:
  21 + * acpi_video_backlight_support();
  22 + *
  23 + * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
  24 + * are available, video.ko should be used to handle the device.
  25 + *
  26 + * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
  27 + * sony_acpi,... can take care about backlight brightness and display output
  28 + * switching.
  29 + *
  30 + * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
  31 + * this file will not be compiled, acpi_video_get_capabilities() and
  32 + * acpi_video_backlight_support() will always return 0 and vendor specific
  33 + * drivers always can handle backlight.
  34 + *
  35 + */
  36 +
  37 +#include <linux/acpi.h>
  38 +#include <linux/dmi.h>
  39 +
  40 +ACPI_MODULE_NAME("video");
  41 +#define _COMPONENT ACPI_VIDEO_COMPONENT
  42 +
  43 +static long acpi_video_support;
  44 +static bool acpi_video_caps_checked;
  45 +
  46 +static acpi_status
  47 +acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
  48 + void **retyurn_value)
  49 +{
  50 + long *cap = context;
  51 + acpi_handle h_dummy;
  52 +
  53 + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
  54 + ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
  55 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
  56 + "support\n"));
  57 + *cap |= ACPI_VIDEO_BACKLIGHT;
  58 + /* We have backlight support, no need to scan further */
  59 + return AE_CTRL_TERMINATE;
  60 + }
  61 + return 0;
  62 +}
  63 +
  64 +/* Returns true if the device is a video device which can be handled by
  65 + * video.ko.
  66 + * The device will get a Linux specific CID added in scan.c to
  67 + * identify the device as an ACPI graphics device
  68 + * Be aware that the graphics device may not be physically present
  69 + * Use acpi_video_get_capabilities() to detect general ACPI video
  70 + * capabilities of present cards
  71 + */
  72 +long acpi_is_video_device(struct acpi_device *device)
  73 +{
  74 + acpi_handle h_dummy;
  75 + long video_caps = 0;
  76 +
  77 + if (!device)
  78 + return 0;
  79 +
  80 + /* Does this device able to support video switching ? */
  81 + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
  82 + ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
  83 + video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
  84 +
  85 + /* Does this device able to retrieve a video ROM ? */
  86 + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
  87 + video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
  88 +
  89 + /* Does this device able to configure which video head to be POSTed ? */
  90 + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
  91 + ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
  92 + ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
  93 + video_caps |= ACPI_VIDEO_DEVICE_POSTING;
  94 +
  95 + /* Only check for backlight functionality if one of the above hit. */
  96 + if (video_caps)
  97 + acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
  98 + ACPI_UINT32_MAX, acpi_backlight_cap_match,
  99 + &video_caps, NULL);
  100 +
  101 + return video_caps;
  102 +}
  103 +EXPORT_SYMBOL(acpi_is_video_device);
  104 +
  105 +static acpi_status
  106 +find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
  107 +{
  108 + long *cap = context;
  109 + struct device *dev;
  110 + struct acpi_device *acpi_dev;
  111 +
  112 + const struct acpi_device_id video_ids[] = {
  113 + {ACPI_VIDEO_HID, 0},
  114 + {"", 0},
  115 + };
  116 + if (acpi_bus_get_device(handle, &acpi_dev))
  117 + return AE_OK;
  118 +
  119 + if (!acpi_match_device_ids(acpi_dev, video_ids)) {
  120 + dev = acpi_get_physical_pci_device(handle);
  121 + if (!dev)
  122 + return AE_OK;
  123 + put_device(dev);
  124 + *cap |= acpi_is_video_device(acpi_dev);
  125 + }
  126 + return AE_OK;
  127 +}
  128 +
  129 +/*
  130 + * Returns the video capabilities of a specific ACPI graphics device
  131 + *
  132 + * if NULL is passed as argument all ACPI devices are enumerated and
  133 + * all graphics capabilities of physically present devices are
  134 + * summerized and returned. This is cached and done only once.
  135 + */
  136 +long acpi_video_get_capabilities(acpi_handle graphics_handle)
  137 +{
  138 + long caps = 0;
  139 + struct acpi_device *tmp_dev;
  140 + acpi_status status;
  141 +
  142 + if (acpi_video_caps_checked && graphics_handle == NULL)
  143 + return acpi_video_support;
  144 +
  145 + if (!graphics_handle) {
  146 + /* Only do the global walk through all graphics devices once */
  147 + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
  148 + ACPI_UINT32_MAX, find_video,
  149 + &caps, NULL);
  150 + /* There might be boot param flags set already... */
  151 + acpi_video_support |= caps;
  152 + acpi_video_caps_checked = 1;
  153 + /* Add blacklists here. Be careful to use the right *DMI* bits
  154 + * to still be able to override logic via boot params, e.g.:
  155 + *
  156 + * if (dmi_name_in_vendors("XY")) {
  157 + * acpi_video_support |=
  158 + * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR;
  159 + * acpi_video_support |=
  160 + * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR;
  161 + *}
  162 + */
  163 + } else {
  164 + status = acpi_bus_get_device(graphics_handle, &tmp_dev);
  165 + if (ACPI_FAILURE(status)) {
  166 + ACPI_EXCEPTION((AE_INFO, status, "Invalid device"));
  167 + return 0;
  168 + }
  169 + acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
  170 + ACPI_UINT32_MAX, find_video,
  171 + &caps, NULL);
  172 + }
  173 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
  174 + graphics_handle ? caps : acpi_video_support,
  175 + graphics_handle ? "on device " : "in general",
  176 + graphics_handle ? acpi_device_bid(tmp_dev) : ""));
  177 + return caps;
  178 +}
  179 +EXPORT_SYMBOL(acpi_video_get_capabilities);
  180 +
  181 +/* Returns true if video.ko can do backlight switching */
  182 +int acpi_video_backlight_support(void)
  183 +{
  184 + /*
  185 + * We must check whether the ACPI graphics device is physically plugged
  186 + * in. Therefore this must be called after binding PCI and ACPI devices
  187 + */
  188 + if (!acpi_video_caps_checked)
  189 + acpi_video_get_capabilities(NULL);
  190 +
  191 + /* First check for boot param -> highest prio */
  192 + if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR)
  193 + return 0;
  194 + else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO)
  195 + return 1;
  196 +
  197 + /* Then check for DMI blacklist -> second highest prio */
  198 + if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR)
  199 + return 0;
  200 + else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO)
  201 + return 1;
  202 +
  203 + /* Then go the default way */
  204 + return acpi_video_support & ACPI_VIDEO_BACKLIGHT;
  205 +}
  206 +EXPORT_SYMBOL(acpi_video_backlight_support);
  207 +
  208 +/*
  209 + * Returns true if video.ko can do display output switching.
  210 + * This does not work well/at all with binary graphics drivers
  211 + * which disable system io ranges and do it on their own.
  212 + */
  213 +int acpi_video_display_switch_support(void)
  214 +{
  215 + if (!acpi_video_caps_checked)
  216 + acpi_video_get_capabilities(NULL);
  217 +
  218 + if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR)
  219 + return 0;
  220 + else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO)
  221 + return 1;
  222 +
  223 + if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR)
  224 + return 0;
  225 + else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO)
  226 + return 1;
  227 +
  228 + return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING;
  229 +}
  230 +EXPORT_SYMBOL(acpi_video_display_switch_support);
  231 +
  232 +/*
  233 + * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video
  234 + * To force that backlight or display output switching is processed by vendor
  235 + * specific acpi drivers or video.ko driver.
  236 + */
  237 +int __init acpi_backlight(char *str)
  238 +{
  239 + if (str == NULL || *str == '\0')
  240 + return 1;
  241 + else {
  242 + if (!strcmp("vendor", str))
  243 + acpi_video_support |=
  244 + ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
  245 + if (!strcmp("video", str))
  246 + acpi_video_support |=
  247 + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
  248 + }
  249 + return 1;
  250 +}
  251 +__setup("acpi_backlight=", acpi_backlight);
  252 +
  253 +int __init acpi_display_output(char *str)
  254 +{
  255 + if (str == NULL || *str == '\0')
  256 + return 1;
  257 + else {
  258 + if (!strcmp("vendor", str))
  259 + acpi_video_support |=
  260 + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR;
  261 + if (!strcmp("video", str))
  262 + acpi_video_support |=
  263 + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
  264 + }
  265 + return 1;
  266 +}
  267 +__setup("acpi_display_output=", acpi_display_output);
drivers/misc/acer-wmi.c
... ... @@ -1297,6 +1297,12 @@
1297 1297  
1298 1298 set_quirks();
1299 1299  
  1300 + if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
  1301 + interface->capability &= ~ACER_CAP_BRIGHTNESS;
  1302 + printk(ACER_INFO "Brightness must be controlled by "
  1303 + "generic video driver\n");
  1304 + }
  1305 +
1300 1306 if (platform_driver_register(&acer_platform_driver)) {
1301 1307 printk(ACER_ERR "Unable to register platform driver.\n");
1302 1308 goto error_platform_register;
drivers/misc/asus-laptop.c
... ... @@ -1208,9 +1208,13 @@
1208 1208  
1209 1209 dev = acpi_get_physical_device(hotk->device->handle);
1210 1210  
1211   - result = asus_backlight_init(dev);
1212   - if (result)
1213   - goto fail_backlight;
  1211 + if (!acpi_video_backlight_support()) {
  1212 + result = asus_backlight_init(dev);
  1213 + if (result)
  1214 + goto fail_backlight;
  1215 + } else
  1216 + printk(ASUS_INFO "Brightness ignored, must be controlled by "
  1217 + "ACPI video driver\n");
1214 1218  
1215 1219 result = asus_led_init(dev);
1216 1220 if (result)
drivers/misc/compal-laptop.c
... ... @@ -326,12 +326,14 @@
326 326  
327 327 /* Register backlight stuff */
328 328  
329   - compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
330   - &compalbl_ops);
331   - if (IS_ERR(compalbl_device))
332   - return PTR_ERR(compalbl_device);
  329 + if (!acpi_video_backlight_support()) {
  330 + compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
  331 + &compalbl_ops);
  332 + if (IS_ERR(compalbl_device))
  333 + return PTR_ERR(compalbl_device);
333 334  
334   - compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
  335 + compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
  336 + }
335 337  
336 338 ret = platform_driver_register(&compal_driver);
337 339 if (ret)
drivers/misc/eeepc-laptop.c
... ... @@ -825,9 +825,15 @@
825 825 return -ENODEV;
826 826 }
827 827 dev = acpi_get_physical_device(ehotk->device->handle);
828   - result = eeepc_backlight_init(dev);
829   - if (result)
830   - goto fail_backlight;
  828 +
  829 + if (!acpi_video_backlight_support()) {
  830 + result = eeepc_backlight_init(dev);
  831 + if (result)
  832 + goto fail_backlight;
  833 + } else
  834 + printk(EEEPC_INFO "Backlight controlled by ACPI video "
  835 + "driver\n");
  836 +
831 837 result = eeepc_hwmon_init(dev);
832 838 if (result)
833 839 goto fail_hwmon;
drivers/misc/fujitsu-laptop.c
... ... @@ -1005,17 +1005,17 @@
1005 1005  
1006 1006 /* Register backlight stuff */
1007 1007  
1008   - fujitsu->bl_device =
1009   - backlight_device_register("fujitsu-laptop", NULL, NULL,
1010   - &fujitsubl_ops);
1011   - if (IS_ERR(fujitsu->bl_device))
1012   - return PTR_ERR(fujitsu->bl_device);
  1008 + if (!acpi_video_backlight_support()) {
  1009 + fujitsu->bl_device =
  1010 + backlight_device_register("fujitsu-laptop", NULL, NULL,
  1011 + &fujitsubl_ops);
  1012 + if (IS_ERR(fujitsu->bl_device))
  1013 + return PTR_ERR(fujitsu->bl_device);
  1014 + max_brightness = fujitsu->max_brightness;
  1015 + fujitsu->bl_device->props.max_brightness = max_brightness - 1;
  1016 + fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
  1017 + }
1013 1018  
1014   - max_brightness = fujitsu->max_brightness;
1015   -
1016   - fujitsu->bl_device->props.max_brightness = max_brightness - 1;
1017   - fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
1018   -
1019 1019 ret = platform_driver_register(&fujitsupf_driver);
1020 1020 if (ret)
1021 1021 goto fail_backlight;
... ... @@ -1050,7 +1050,8 @@
1050 1050  
1051 1051 fail_backlight:
1052 1052  
1053   - backlight_device_unregister(fujitsu->bl_device);
  1053 + if (fujitsu->bl_device)
  1054 + backlight_device_unregister(fujitsu->bl_device);
1054 1055  
1055 1056 fail_platform_device2:
1056 1057  
... ... @@ -1077,7 +1078,8 @@
1077 1078 &fujitsupf_attribute_group);
1078 1079 platform_device_unregister(fujitsu->pf_device);
1079 1080 platform_driver_unregister(&fujitsupf_driver);
1080   - backlight_device_unregister(fujitsu->bl_device);
  1081 + if (fujitsu->bl_device)
  1082 + backlight_device_unregister(fujitsu->bl_device);
1081 1083  
1082 1084 acpi_bus_unregister_driver(&acpi_fujitsu_driver);
1083 1085  
drivers/misc/msi-laptop.c
... ... @@ -347,12 +347,16 @@
347 347  
348 348 /* Register backlight stuff */
349 349  
350   - msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
351   - &msibl_ops);
352   - if (IS_ERR(msibl_device))
353   - return PTR_ERR(msibl_device);
354   -
355   - msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
  350 + if (acpi_video_backlight_support()) {
  351 + printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
  352 + "by ACPI video driver\n");
  353 + } else {
  354 + msibl_device = backlight_device_register("msi-laptop-bl", NULL,
  355 + NULL, &msibl_ops);
  356 + if (IS_ERR(msibl_device))
  357 + return PTR_ERR(msibl_device);
  358 + msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
  359 + }
356 360  
357 361 ret = platform_driver_register(&msipf_driver);
358 362 if (ret)
drivers/misc/sony-laptop.c
... ... @@ -1038,7 +1038,11 @@
1038 1038 goto outinput;
1039 1039 }
1040 1040  
1041   - if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) {
  1041 + if (!acpi_video_backlight_support()) {
  1042 + printk(KERN_INFO DRV_PFX "Sony: Brightness ignored, must be "
  1043 + "controlled by ACPI video driver\n");
  1044 + } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
  1045 + &handle))) {
1042 1046 sony_backlight_device = backlight_device_register("sony", NULL,
1043 1047 NULL,
1044 1048 &sony_backlight_ops);
drivers/misc/thinkpad_acpi.c
... ... @@ -4932,16 +4932,25 @@
4932 4932 */
4933 4933 b = tpacpi_check_std_acpi_brightness_support();
4934 4934 if (b > 0) {
4935   - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
4936   - printk(TPACPI_NOTICE
4937   - "Lenovo BIOS switched to ACPI backlight "
4938   - "control mode\n");
4939   - }
4940   - if (brightness_enable > 1) {
4941   - printk(TPACPI_NOTICE
4942   - "standard ACPI backlight interface "
4943   - "available, not loading native one...\n");
4944   - return 1;
  4935 +
  4936 + if (acpi_video_backlight_support()) {
  4937 + if (brightness_enable > 1) {
  4938 + printk(TPACPI_NOTICE
  4939 + "Standard ACPI backlight interface "
  4940 + "available, not loading native one.\n");
  4941 + return 1;
  4942 + } else if (brightness_enable == 1) {
  4943 + printk(TPACPI_NOTICE
  4944 + "Backlight control force enabled, even if standard "
  4945 + "ACPI backlight interface is available\n");
  4946 + }
  4947 + } else {
  4948 + if (brightness_enable > 1) {
  4949 + printk(TPACPI_NOTICE
  4950 + "Standard ACPI backlight interface not "
  4951 + "available, thinkpad_acpi native "
  4952 + "brightness control enabled\n");
  4953 + }
4945 4954 }
4946 4955 }
4947 4956  
include/acpi/acpi_bus.h
... ... @@ -380,6 +380,8 @@
380 380 int register_acpi_bus_type(struct acpi_bus_type *);
381 381 int unregister_acpi_bus_type(struct acpi_bus_type *);
382 382 struct device *acpi_get_physical_device(acpi_handle);
  383 +struct device *acpi_get_physical_pci_device(acpi_handle);
  384 +
383 385 /* helper */
384 386 acpi_handle acpi_get_child(acpi_handle, acpi_integer);
385 387 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
include/linux/acpi.h
... ... @@ -190,6 +190,50 @@
190 190  
191 191 #endif /* CONFIG_ACPI_WMI */
192 192  
  193 +#define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001
  194 +#define ACPI_VIDEO_DEVICE_POSTING 0x0002
  195 +#define ACPI_VIDEO_ROM_AVAILABLE 0x0004
  196 +#define ACPI_VIDEO_BACKLIGHT 0x0008
  197 +#define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010
  198 +#define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020
  199 +#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040
  200 +#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080
  201 +#define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100
  202 +#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200
  203 +#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400
  204 +#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800
  205 +
  206 +#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
  207 +
  208 +extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle);
  209 +extern long acpi_is_video_device(struct acpi_device *device);
  210 +extern int acpi_video_backlight_support(void);
  211 +extern int acpi_video_display_switch_support(void);
  212 +
  213 +#else
  214 +
  215 +static inline long acpi_video_get_capabilities(acpi_handle graphics_dev_handle)
  216 +{
  217 + return 0;
  218 +}
  219 +
  220 +static inline long acpi_is_video_device(struct acpi_device *device)
  221 +{
  222 + return 0;
  223 +}
  224 +
  225 +static inline int acpi_video_backlight_support(void)
  226 +{
  227 + return 0;
  228 +}
  229 +
  230 +static inline int acpi_video_display_switch_support(void)
  231 +{
  232 + return 0;
  233 +}
  234 +
  235 +#endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */
  236 +
193 237 extern int acpi_blacklisted(void);
194 238 #ifdef CONFIG_DMI
195 239 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);