aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-21 13:11:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-21 13:11:04 -0400
commitea45ea70b6131fa0b006f5b687b9b1398b24f681 (patch)
tree634e94b991a6a34f9a92d6e1c73ac676737efd19 /drivers/acpi
parent90db76e829479ef2ba1fed8f2552846015469831 (diff)
parentefaa14c7e981bdf8d3c8d39d3ed12bdc60faabb8 (diff)
Merge tag 'acpi-video-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI video support fixes from Rafael Wysocki: "I'm sending a separate pull request for this as it may be somewhat controversial. The breakage addressed here is not really new and the fixes may not satisfy all users of the affected systems, but we've had so much back and forth dance in this area over the last several weeks that I think it's time to actually make some progress. The source of the problem is that about a year ago we started to tell BIOSes that we're compatible with Windows 8, which we really need to do, because some systems shipping with Windows 8 are tested with it and nothing else, so if we tell their BIOSes that we aren't compatible with Windows 8, we expose our users to untested BIOS/AML code paths. However, as it turns out, some Windows 8-specific AML code paths are not tested either, because Windows 8 actually doesn't use the ACPI methods containing them, so if we declare Windows 8 compatibility and attempt to use those ACPI methods, things break. That occurs mostly in the backlight support area where in particular the _BCM and _BQC methods are plain unusable on some systems if the OS declares Windows 8 compatibility. [ The additional twist is that they actually become usable if the OS says it is not compatible with Windows 8, but that may cause problems to show up elsewhere ] Investigation carried out by Matthew Garrett indicates that what Windows 8 does about backlight is to leave backlight control up to individual graphics drivers. At least there's evidence that it does that if the Intel graphics driver is used, so we've decided to follow Windows 8 in that respect and allow i915 to control backlight (Daniel likes that part). The first commit from Aaron Lu makes ACPICA export the variable from which we can infer whether or not the BIOS believes that we are compatible with Windows 8. The second commit from Matthew Garrett prepares the ACPI video driver by making it initialize the ACPI backlight even if it is not going to be used afterward (that is needed for backlight control to work on Thinkpads). The third commit implements the actual workaround making i915 take over backlight control if the firmware thinks it's dealing with Windows 8 and is based on the work of multiple developers, including Matthew Garrett, Chun-Yi Lee, Seth Forshee, and Aaron Lu. The final commit from Aaron Lu makes us follow Windows 8 by informing the firmware through the _DOS method that it should not carry out automatic brightness changes, so that brightness can be controlled by GUI. Hopefully, this approach will allow us to avoid using blacklists of systems that should not declare Windows 8 compatibility just to avoid backlight control problems in the future. - Change from Aaron Lu makes ACPICA export a variable which can be used by driver code to determine whether or not the BIOS believes that we are compatible with Windows 8. - Change from Matthew Garrett makes the ACPI video driver initialize the ACPI backlight even if it is not going to be used afterward (that is needed for backlight control to work on Thinkpads). - Fix from Rafael J Wysocki implements Windows 8 backlight support workaround making i915 take over bakclight control if the firmware thinks it's dealing with Windows 8. Based on the work of multiple developers including Matthew Garrett, Chun-Yi Lee, Seth Forshee, and Aaron Lu. - Fix from Aaron Lu makes the kernel follow Windows 8 by informing the firmware through the _DOS method that it should not carry out automatic brightness changes, so that brightness can be controlled by GUI" * tag 'acpi-video-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / video: no automatic brightness changes by win8-compatible firmware ACPI / video / i915: No ACPI backlight if firmware expects Windows 8 ACPI / video: Always call acpi_video_init_brightness() on init ACPICA: expose OSI version
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpica/aclocal.h13
-rw-r--r--drivers/acpi/internal.h11
-rw-r--r--drivers/acpi/video.c90
-rw-r--r--drivers/acpi/video_detect.c21
4 files changed, 109 insertions, 26 deletions
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index dfed26545ba2..d4a4901637cd 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -931,19 +931,6 @@ struct acpi_bit_register_info {
931 931
932/* Structs and definitions for _OSI support and I/O port validation */ 932/* Structs and definitions for _OSI support and I/O port validation */
933 933
934#define ACPI_OSI_WIN_2000 0x01
935#define ACPI_OSI_WIN_XP 0x02
936#define ACPI_OSI_WIN_XP_SP1 0x03
937#define ACPI_OSI_WINSRV_2003 0x04
938#define ACPI_OSI_WIN_XP_SP2 0x05
939#define ACPI_OSI_WINSRV_2003_SP1 0x06
940#define ACPI_OSI_WIN_VISTA 0x07
941#define ACPI_OSI_WINSRV_2008 0x08
942#define ACPI_OSI_WIN_VISTA_SP1 0x09
943#define ACPI_OSI_WIN_VISTA_SP2 0x0A
944#define ACPI_OSI_WIN_7 0x0B
945#define ACPI_OSI_WIN_8 0x0C
946
947#define ACPI_ALWAYS_ILLEGAL 0x00 934#define ACPI_ALWAYS_ILLEGAL 0x00
948 935
949struct acpi_interface_info { 936struct acpi_interface_info {
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 3a50a34fe176..227aca77ee1e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -164,4 +164,15 @@ struct platform_device;
164int acpi_create_platform_device(struct acpi_device *adev, 164int acpi_create_platform_device(struct acpi_device *adev,
165 const struct acpi_device_id *id); 165 const struct acpi_device_id *id);
166 166
167/*--------------------------------------------------------------------------
168 Video
169 -------------------------------------------------------------------------- */
170#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
171bool acpi_video_backlight_quirks(void);
172bool acpi_video_verify_backlight_support(void);
173#else
174static inline bool acpi_video_backlight_quirks(void) { return false; }
175static inline bool acpi_video_verify_backlight_support(void) { return false; }
176#endif
177
167#endif /* _ACPI_INTERNAL_H_ */ 178#endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e441876f5d5b..6dd237e79b4f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -44,6 +44,8 @@
44#include <linux/suspend.h> 44#include <linux/suspend.h>
45#include <acpi/video.h> 45#include <acpi/video.h>
46 46
47#include "internal.h"
48
47#define PREFIX "ACPI: " 49#define PREFIX "ACPI: "
48 50
49#define ACPI_VIDEO_BUS_NAME "Video Bus" 51#define ACPI_VIDEO_BUS_NAME "Video Bus"
@@ -906,7 +908,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
906 device->cap._DDC = 1; 908 device->cap._DDC = 1;
907 } 909 }
908 910
909 if (acpi_video_backlight_support()) { 911 if (acpi_video_init_brightness(device))
912 return;
913
914 if (acpi_video_verify_backlight_support()) {
910 struct backlight_properties props; 915 struct backlight_properties props;
911 struct pci_dev *pdev; 916 struct pci_dev *pdev;
912 acpi_handle acpi_parent; 917 acpi_handle acpi_parent;
@@ -915,9 +920,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
915 static int count = 0; 920 static int count = 0;
916 char *name; 921 char *name;
917 922
918 result = acpi_video_init_brightness(device);
919 if (result)
920 return;
921 name = kasprintf(GFP_KERNEL, "acpi_video%d", count); 923 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
922 if (!name) 924 if (!name)
923 return; 925 return;
@@ -977,6 +979,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
977 if (result) 979 if (result)
978 printk(KERN_ERR PREFIX "Create sysfs link\n"); 980 printk(KERN_ERR PREFIX "Create sysfs link\n");
979 981
982 } else {
983 /* Remove the brightness object. */
984 kfree(device->brightness->levels);
985 kfree(device->brightness);
986 device->brightness = NULL;
980 } 987 }
981} 988}
982 989
@@ -1359,8 +1366,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1359 unsigned long long level_current, level_next; 1366 unsigned long long level_current, level_next;
1360 int result = -EINVAL; 1367 int result = -EINVAL;
1361 1368
1362 /* no warning message if acpi_backlight=vendor is used */ 1369 /* no warning message if acpi_backlight=vendor or a quirk is used */
1363 if (!acpi_video_backlight_support()) 1370 if (!acpi_video_verify_backlight_support())
1364 return 0; 1371 return 0;
1365 1372
1366 if (!device->brightness) 1373 if (!device->brightness)
@@ -1540,14 +1547,20 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1540 1547
1541/* acpi_video interface */ 1548/* acpi_video interface */
1542 1549
1550/*
1551 * Win8 requires setting bit2 of _DOS to let firmware know it shouldn't
1552 * preform any automatic brightness change on receiving a notification.
1553 */
1543static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 1554static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1544{ 1555{
1545 return acpi_video_bus_DOS(video, 0, 0); 1556 return acpi_video_bus_DOS(video, 0,
1557 acpi_video_backlight_quirks() ? 1 : 0);
1546} 1558}
1547 1559
1548static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 1560static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1549{ 1561{
1550 return acpi_video_bus_DOS(video, 0, 1); 1562 return acpi_video_bus_DOS(video, 0,
1563 acpi_video_backlight_quirks() ? 0 : 1);
1551} 1564}
1552 1565
1553static void acpi_video_bus_notify(struct acpi_device *device, u32 event) 1566static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
@@ -1862,6 +1875,46 @@ static int acpi_video_bus_remove(struct acpi_device *device)
1862 return 0; 1875 return 0;
1863} 1876}
1864 1877
1878static acpi_status video_unregister_backlight(acpi_handle handle, u32 lvl,
1879 void *context, void **rv)
1880{
1881 struct acpi_device *acpi_dev;
1882 struct acpi_video_bus *video;
1883 struct acpi_video_device *dev, *next;
1884
1885 if (acpi_bus_get_device(handle, &acpi_dev))
1886 return AE_OK;
1887
1888 if (acpi_match_device_ids(acpi_dev, video_device_ids))
1889 return AE_OK;
1890
1891 video = acpi_driver_data(acpi_dev);
1892 if (!video)
1893 return AE_OK;
1894
1895 acpi_video_bus_stop_devices(video);
1896 mutex_lock(&video->device_list_lock);
1897 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1898 if (dev->backlight) {
1899 backlight_device_unregister(dev->backlight);
1900 dev->backlight = NULL;
1901 kfree(dev->brightness->levels);
1902 kfree(dev->brightness);
1903 }
1904 if (dev->cooling_dev) {
1905 sysfs_remove_link(&dev->dev->dev.kobj,
1906 "thermal_cooling");
1907 sysfs_remove_link(&dev->cooling_dev->device.kobj,
1908 "device");
1909 thermal_cooling_device_unregister(dev->cooling_dev);
1910 dev->cooling_dev = NULL;
1911 }
1912 }
1913 mutex_unlock(&video->device_list_lock);
1914 acpi_video_bus_start_devices(video);
1915 return AE_OK;
1916}
1917
1865static int __init is_i740(struct pci_dev *dev) 1918static int __init is_i740(struct pci_dev *dev)
1866{ 1919{
1867 if (dev->device == 0x00D1) 1920 if (dev->device == 0x00D1)
@@ -1893,14 +1946,25 @@ static int __init intel_opregion_present(void)
1893 return opregion; 1946 return opregion;
1894} 1947}
1895 1948
1896int acpi_video_register(void) 1949int __acpi_video_register(bool backlight_quirks)
1897{ 1950{
1898 int result = 0; 1951 bool no_backlight;
1952 int result;
1953
1954 no_backlight = backlight_quirks ? acpi_video_backlight_quirks() : false;
1955
1899 if (register_count) { 1956 if (register_count) {
1900 /* 1957 /*
1901 * if the function of acpi_video_register is already called, 1958 * If acpi_video_register() has been called already, don't try
1902 * don't register the acpi_vide_bus again and return no error. 1959 * to register acpi_video_bus, but unregister backlight devices
1960 * if no backlight support is requested.
1903 */ 1961 */
1962 if (no_backlight)
1963 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1964 ACPI_UINT32_MAX,
1965 video_unregister_backlight,
1966 NULL, NULL, NULL);
1967
1904 return 0; 1968 return 0;
1905 } 1969 }
1906 1970
@@ -1916,7 +1980,7 @@ int acpi_video_register(void)
1916 1980
1917 return 0; 1981 return 0;
1918} 1982}
1919EXPORT_SYMBOL(acpi_video_register); 1983EXPORT_SYMBOL(__acpi_video_register);
1920 1984
1921void acpi_video_unregister(void) 1985void acpi_video_unregister(void)
1922{ 1986{
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index e6bd910bc6ed..826e52def080 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -38,6 +38,8 @@
38#include <linux/dmi.h> 38#include <linux/dmi.h>
39#include <linux/pci.h> 39#include <linux/pci.h>
40 40
41#include "internal.h"
42
41#define PREFIX "ACPI: " 43#define PREFIX "ACPI: "
42 44
43ACPI_MODULE_NAME("video"); 45ACPI_MODULE_NAME("video");
@@ -234,6 +236,17 @@ static void acpi_video_caps_check(void)
234 acpi_video_get_capabilities(NULL); 236 acpi_video_get_capabilities(NULL);
235} 237}
236 238
239bool acpi_video_backlight_quirks(void)
240{
241 if (acpi_gbl_osi_data >= ACPI_OSI_WIN_8) {
242 acpi_video_caps_check();
243 acpi_video_support |= ACPI_VIDEO_SKIP_BACKLIGHT;
244 return true;
245 }
246 return false;
247}
248EXPORT_SYMBOL(acpi_video_backlight_quirks);
249
237/* Promote the vendor interface instead of the generic video module. 250/* Promote the vendor interface instead of the generic video module.
238 * This function allow DMI blacklists to be implemented by externals 251 * This function allow DMI blacklists to be implemented by externals
239 * platform drivers instead of putting a big blacklist in video_detect.c 252 * platform drivers instead of putting a big blacklist in video_detect.c
@@ -278,6 +291,14 @@ int acpi_video_backlight_support(void)
278} 291}
279EXPORT_SYMBOL(acpi_video_backlight_support); 292EXPORT_SYMBOL(acpi_video_backlight_support);
280 293
294/* For the ACPI video driver use only. */
295bool acpi_video_verify_backlight_support(void)
296{
297 return (acpi_video_support & ACPI_VIDEO_SKIP_BACKLIGHT) ?
298 false : acpi_video_backlight_support();
299}
300EXPORT_SYMBOL(acpi_video_verify_backlight_support);
301
281/* 302/*
282 * Use acpi_backlight=vendor/video to force that backlight switching 303 * Use acpi_backlight=vendor/video to force that backlight switching
283 * is processed by vendor specific acpi drivers or video.ko driver. 304 * is processed by vendor specific acpi drivers or video.ko driver.