diff options
-rw-r--r-- | drivers/acpi/internal.h | 11 | ||||
-rw-r--r-- | drivers/acpi/video.c | 69 | ||||
-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/video.h | 11 | ||||
-rw-r--r-- | include/linux/acpi.h | 1 |
6 files changed, 105 insertions, 10 deletions
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 f236e172d948..e9d4bb60c35c 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" |
@@ -901,7 +903,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
901 | if (acpi_video_init_brightness(device)) | 903 | if (acpi_video_init_brightness(device)) |
902 | return; | 904 | return; |
903 | 905 | ||
904 | if (acpi_video_backlight_support()) { | 906 | if (acpi_video_verify_backlight_support()) { |
905 | struct backlight_properties props; | 907 | struct backlight_properties props; |
906 | struct pci_dev *pdev; | 908 | struct pci_dev *pdev; |
907 | acpi_handle acpi_parent; | 909 | acpi_handle acpi_parent; |
@@ -1356,8 +1358,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) | |||
1356 | unsigned long long level_current, level_next; | 1358 | unsigned long long level_current, level_next; |
1357 | int result = -EINVAL; | 1359 | int result = -EINVAL; |
1358 | 1360 | ||
1359 | /* no warning message if acpi_backlight=vendor is used */ | 1361 | /* no warning message if acpi_backlight=vendor or a quirk is used */ |
1360 | if (!acpi_video_backlight_support()) | 1362 | if (!acpi_video_verify_backlight_support()) |
1361 | return 0; | 1363 | return 0; |
1362 | 1364 | ||
1363 | if (!device->brightness) | 1365 | if (!device->brightness) |
@@ -1859,6 +1861,46 @@ static int acpi_video_bus_remove(struct acpi_device *device) | |||
1859 | return 0; | 1861 | return 0; |
1860 | } | 1862 | } |
1861 | 1863 | ||
1864 | static acpi_status video_unregister_backlight(acpi_handle handle, u32 lvl, | ||
1865 | void *context, void **rv) | ||
1866 | { | ||
1867 | struct acpi_device *acpi_dev; | ||
1868 | struct acpi_video_bus *video; | ||
1869 | struct acpi_video_device *dev, *next; | ||
1870 | |||
1871 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
1872 | return AE_OK; | ||
1873 | |||
1874 | if (acpi_match_device_ids(acpi_dev, video_device_ids)) | ||
1875 | return AE_OK; | ||
1876 | |||
1877 | video = acpi_driver_data(acpi_dev); | ||
1878 | if (!video) | ||
1879 | return AE_OK; | ||
1880 | |||
1881 | acpi_video_bus_stop_devices(video); | ||
1882 | mutex_lock(&video->device_list_lock); | ||
1883 | list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { | ||
1884 | if (dev->backlight) { | ||
1885 | backlight_device_unregister(dev->backlight); | ||
1886 | dev->backlight = NULL; | ||
1887 | kfree(dev->brightness->levels); | ||
1888 | kfree(dev->brightness); | ||
1889 | } | ||
1890 | if (dev->cooling_dev) { | ||
1891 | sysfs_remove_link(&dev->dev->dev.kobj, | ||
1892 | "thermal_cooling"); | ||
1893 | sysfs_remove_link(&dev->cooling_dev->device.kobj, | ||
1894 | "device"); | ||
1895 | thermal_cooling_device_unregister(dev->cooling_dev); | ||
1896 | dev->cooling_dev = NULL; | ||
1897 | } | ||
1898 | } | ||
1899 | mutex_unlock(&video->device_list_lock); | ||
1900 | acpi_video_bus_start_devices(video); | ||
1901 | return AE_OK; | ||
1902 | } | ||
1903 | |||
1862 | static int __init is_i740(struct pci_dev *dev) | 1904 | static int __init is_i740(struct pci_dev *dev) |
1863 | { | 1905 | { |
1864 | if (dev->device == 0x00D1) | 1906 | if (dev->device == 0x00D1) |
@@ -1890,14 +1932,25 @@ static int __init intel_opregion_present(void) | |||
1890 | return opregion; | 1932 | return opregion; |
1891 | } | 1933 | } |
1892 | 1934 | ||
1893 | int acpi_video_register(void) | 1935 | int __acpi_video_register(bool backlight_quirks) |
1894 | { | 1936 | { |
1895 | int result = 0; | 1937 | bool no_backlight; |
1938 | int result; | ||
1939 | |||
1940 | no_backlight = backlight_quirks ? acpi_video_backlight_quirks() : false; | ||
1941 | |||
1896 | if (register_count) { | 1942 | if (register_count) { |
1897 | /* | 1943 | /* |
1898 | * if the function of acpi_video_register is already called, | 1944 | * If acpi_video_register() has been called already, don't try |
1899 | * don't register the acpi_vide_bus again and return no error. | 1945 | * to register acpi_video_bus, but unregister backlight devices |
1946 | * if no backlight support is requested. | ||
1900 | */ | 1947 | */ |
1948 | if (no_backlight) | ||
1949 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
1950 | ACPI_UINT32_MAX, | ||
1951 | video_unregister_backlight, | ||
1952 | NULL, NULL, NULL); | ||
1953 | |||
1901 | return 0; | 1954 | return 0; |
1902 | } | 1955 | } |
1903 | 1956 | ||
@@ -1913,7 +1966,7 @@ int acpi_video_register(void) | |||
1913 | 1966 | ||
1914 | return 0; | 1967 | return 0; |
1915 | } | 1968 | } |
1916 | EXPORT_SYMBOL(acpi_video_register); | 1969 | EXPORT_SYMBOL(__acpi_video_register); |
1917 | 1970 | ||
1918 | void acpi_video_unregister(void) | 1971 | void acpi_video_unregister(void) |
1919 | { | 1972 | { |
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/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 | ||