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 | ||
