aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--include/acpi/acpixf.h1
-rw-r--r--include/acpi/actypes.h15
-rw-r--r--include/acpi/video.h11
-rw-r--r--include/linux/acpi.h1
9 files changed, 137 insertions, 28 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.
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index adb319b53ecd..cf188ab7051a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1648,7 +1648,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1648 if (INTEL_INFO(dev)->num_pipes) { 1648 if (INTEL_INFO(dev)->num_pipes) {
1649 /* Must be done after probing outputs */ 1649 /* Must be done after probing outputs */
1650 intel_opregion_init(dev); 1650 intel_opregion_init(dev);
1651 acpi_video_register(); 1651 acpi_video_register_with_quirks();
1652 } 1652 }
1653 1653
1654 if (IS_GEN5(dev)) 1654 if (IS_GEN5(dev))
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 1b09300810e6..22d497ee6ef9 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -62,6 +62,7 @@ extern u32 acpi_current_gpe_count;
62extern struct acpi_table_fadt acpi_gbl_FADT; 62extern struct acpi_table_fadt acpi_gbl_FADT;
63extern u8 acpi_gbl_system_awake_and_running; 63extern u8 acpi_gbl_system_awake_and_running;
64extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */ 64extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */
65extern u8 acpi_gbl_osi_data;
65 66
66/* Runtime configuration of debug print levels */ 67/* Runtime configuration of debug print levels */
67 68
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index a64adcc29ae5..22b03c9286e9 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -1144,4 +1144,19 @@ struct acpi_memory_list {
1144#endif 1144#endif
1145}; 1145};
1146 1146
1147/* Definitions for _OSI support */
1148
1149#define ACPI_OSI_WIN_2000 0x01
1150#define ACPI_OSI_WIN_XP 0x02
1151#define ACPI_OSI_WIN_XP_SP1 0x03
1152#define ACPI_OSI_WINSRV_2003 0x04
1153#define ACPI_OSI_WIN_XP_SP2 0x05
1154#define ACPI_OSI_WINSRV_2003_SP1 0x06
1155#define ACPI_OSI_WIN_VISTA 0x07
1156#define ACPI_OSI_WINSRV_2008 0x08
1157#define ACPI_OSI_WIN_VISTA_SP1 0x09
1158#define ACPI_OSI_WIN_VISTA_SP2 0x0A
1159#define ACPI_OSI_WIN_7 0x0B
1160#define ACPI_OSI_WIN_8 0x0C
1161
1147#endif /* __ACTYPES_H__ */ 1162#endif /* __ACTYPES_H__ */
diff --git a/include/acpi/video.h b/include/acpi/video.h
index 61109f2609fc..b26dc4fb7ba8 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -17,12 +17,21 @@ struct acpi_device;
17#define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 17#define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200
18 18
19#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) 19#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
20extern int acpi_video_register(void); 20extern int __acpi_video_register(bool backlight_quirks);
21static inline int acpi_video_register(void)
22{
23 return __acpi_video_register(false);
24}
25static inline int acpi_video_register_with_quirks(void)
26{
27 return __acpi_video_register(true);
28}
21extern void acpi_video_unregister(void); 29extern void acpi_video_unregister(void);
22extern int acpi_video_get_edid(struct acpi_device *device, int type, 30extern int acpi_video_get_edid(struct acpi_device *device, int type,
23 int device_id, void **edid); 31 int device_id, void **edid);
24#else 32#else
25static inline int acpi_video_register(void) { return 0; } 33static inline int acpi_video_register(void) { return 0; }
34static inline int acpi_video_register_with_quirks(void) { return 0; }
26static inline void acpi_video_unregister(void) { return; } 35static inline void acpi_video_unregister(void) { return; }
27static inline int acpi_video_get_edid(struct acpi_device *device, int type, 36static inline int acpi_video_get_edid(struct acpi_device *device, int type,
28 int device_id, void **edid) 37 int device_id, void **edid)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 353ba256f368..6ad72f92469c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -191,6 +191,7 @@ extern bool wmi_has_guid(const char *guid);
191#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200 191#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200
192#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400 192#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400
193#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800 193#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800
194#define ACPI_VIDEO_SKIP_BACKLIGHT 0x1000
194 195
195#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) 196#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
196 197