aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/internal.h11
-rw-r--r--drivers/acpi/video.c69
-rw-r--r--drivers/acpi/video_detect.c21
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--include/acpi/video.h11
-rw-r--r--include/linux/acpi.h1
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;
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 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
1864static 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
1862static int __init is_i740(struct pci_dev *dev) 1904static 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
1893int acpi_video_register(void) 1935int __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}
1916EXPORT_SYMBOL(acpi_video_register); 1969EXPORT_SYMBOL(__acpi_video_register);
1917 1970
1918void acpi_video_unregister(void) 1971void 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
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/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