diff options
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 13 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 11 | ||||
-rw-r--r-- | drivers/acpi/video.c | 90 | ||||
-rw-r--r-- | drivers/acpi/video_detect.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 2 | ||||
-rw-r--r-- | include/acpi/acpixf.h | 1 | ||||
-rw-r--r-- | include/acpi/actypes.h | 15 | ||||
-rw-r--r-- | include/acpi/video.h | 11 | ||||
-rw-r--r-- | include/linux/acpi.h | 1 |
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 | ||
949 | struct acpi_interface_info { | 936 | struct 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; | |||
164 | int acpi_create_platform_device(struct acpi_device *adev, | 164 | int 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) | ||
171 | bool acpi_video_backlight_quirks(void); | ||
172 | bool acpi_video_verify_backlight_support(void); | ||
173 | #else | ||
174 | static inline bool acpi_video_backlight_quirks(void) { return false; } | ||
175 | static 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 | */ | ||
1543 | static int acpi_video_bus_start_devices(struct acpi_video_bus *video) | 1554 | static 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 | ||
1548 | static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) | 1560 | static 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 | ||
1553 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | 1566 | static 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 | ||
1878 | static 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 | |||
1865 | static int __init is_i740(struct pci_dev *dev) | 1918 | static 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 | ||
1896 | int acpi_video_register(void) | 1949 | int __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 | } |
1919 | EXPORT_SYMBOL(acpi_video_register); | 1983 | EXPORT_SYMBOL(__acpi_video_register); |
1920 | 1984 | ||
1921 | void acpi_video_unregister(void) | 1985 | void 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 | ||
43 | ACPI_MODULE_NAME("video"); | 45 | ACPI_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 | ||
239 | bool 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 | } | ||
248 | EXPORT_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 | } |
279 | EXPORT_SYMBOL(acpi_video_backlight_support); | 292 | EXPORT_SYMBOL(acpi_video_backlight_support); |
280 | 293 | ||
294 | /* For the ACPI video driver use only. */ | ||
295 | bool acpi_video_verify_backlight_support(void) | ||
296 | { | ||
297 | return (acpi_video_support & ACPI_VIDEO_SKIP_BACKLIGHT) ? | ||
298 | false : acpi_video_backlight_support(); | ||
299 | } | ||
300 | EXPORT_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; | |||
62 | extern struct acpi_table_fadt acpi_gbl_FADT; | 62 | extern struct acpi_table_fadt acpi_gbl_FADT; |
63 | extern u8 acpi_gbl_system_awake_and_running; | 63 | extern u8 acpi_gbl_system_awake_and_running; |
64 | extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */ | 64 | extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */ |
65 | extern 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) |
20 | extern int acpi_video_register(void); | 20 | extern int __acpi_video_register(bool backlight_quirks); |
21 | static inline int acpi_video_register(void) | ||
22 | { | ||
23 | return __acpi_video_register(false); | ||
24 | } | ||
25 | static inline int acpi_video_register_with_quirks(void) | ||
26 | { | ||
27 | return __acpi_video_register(true); | ||
28 | } | ||
21 | extern void acpi_video_unregister(void); | 29 | extern void acpi_video_unregister(void); |
22 | extern int acpi_video_get_edid(struct acpi_device *device, int type, | 30 | extern 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 |
25 | static inline int acpi_video_register(void) { return 0; } | 33 | static inline int acpi_video_register(void) { return 0; } |
34 | static inline int acpi_video_register_with_quirks(void) { return 0; } | ||
26 | static inline void acpi_video_unregister(void) { return; } | 35 | static inline void acpi_video_unregister(void) { return; } |
27 | static inline int acpi_video_get_edid(struct acpi_device *device, int type, | 36 | static 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 | ||