diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-01-11 19:09:27 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-01-11 19:09:27 -0500 |
commit | b12745cce2c903ff8e84ebbd1f8632063156d194 (patch) | |
tree | f17873fe6c0ca446de56c9d2cc260c60b02aabd1 /drivers/acpi | |
parent | f3a1bca09a1f4ac445434b97ed2a43e5c6449cf4 (diff) | |
parent | aecbd9b1bff6afbe349921b406b99d285b412820 (diff) |
Merge branch 'acpi-video'
* acpi-video:
ACPI / video: driver must be registered before checking for keypresses
ACPI / video: Add a quirk to force acpi-video backlight on SAMSUNG 530U4E/540U4E
ACPI / video: Add quirks for the Dell Vostro V131
ACPI / video: Add a module option to disable the reporting of keypresses
thinkpad_acpi: Use acpi_video_handles_brightness_key_presses()
dell-wmi: Use acpi_video_handles_brightness_key_presses()
ACPI / video: Add a acpi_video_handles_brightness_key_presses() helper
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_video.c | 76 | ||||
-rw-r--r-- | drivers/acpi/video_detect.c | 17 |
2 files changed, 78 insertions, 15 deletions
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 3405f7a41e25..06a006ff89b0 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c | |||
@@ -77,14 +77,21 @@ module_param(allow_duplicates, bool, 0644); | |||
77 | static int disable_backlight_sysfs_if = -1; | 77 | static int disable_backlight_sysfs_if = -1; |
78 | module_param(disable_backlight_sysfs_if, int, 0444); | 78 | module_param(disable_backlight_sysfs_if, int, 0444); |
79 | 79 | ||
80 | #define REPORT_OUTPUT_KEY_EVENTS 0x01 | ||
81 | #define REPORT_BRIGHTNESS_KEY_EVENTS 0x02 | ||
82 | static int report_key_events = -1; | ||
83 | module_param(report_key_events, int, 0644); | ||
84 | MODULE_PARM_DESC(report_key_events, | ||
85 | "0: none, 1: output changes, 2: brightness changes, 3: all"); | ||
86 | |||
80 | static bool device_id_scheme = false; | 87 | static bool device_id_scheme = false; |
81 | module_param(device_id_scheme, bool, 0444); | 88 | module_param(device_id_scheme, bool, 0444); |
82 | 89 | ||
83 | static bool only_lcd = false; | 90 | static bool only_lcd = false; |
84 | module_param(only_lcd, bool, 0444); | 91 | module_param(only_lcd, bool, 0444); |
85 | 92 | ||
86 | static int register_count; | 93 | static DECLARE_COMPLETION(register_done); |
87 | static DEFINE_MUTEX(register_count_mutex); | 94 | static DEFINE_MUTEX(register_done_mutex); |
88 | static struct mutex video_list_lock; | 95 | static struct mutex video_list_lock; |
89 | static struct list_head video_bus_head; | 96 | static struct list_head video_bus_head; |
90 | static int acpi_video_bus_add(struct acpi_device *device); | 97 | static int acpi_video_bus_add(struct acpi_device *device); |
@@ -412,6 +419,13 @@ static int video_enable_only_lcd(const struct dmi_system_id *d) | |||
412 | return 0; | 419 | return 0; |
413 | } | 420 | } |
414 | 421 | ||
422 | static int video_set_report_key_events(const struct dmi_system_id *id) | ||
423 | { | ||
424 | if (report_key_events == -1) | ||
425 | report_key_events = (uintptr_t)id->driver_data; | ||
426 | return 0; | ||
427 | } | ||
428 | |||
415 | static struct dmi_system_id video_dmi_table[] = { | 429 | static struct dmi_system_id video_dmi_table[] = { |
416 | /* | 430 | /* |
417 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | 431 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 |
@@ -500,6 +514,24 @@ static struct dmi_system_id video_dmi_table[] = { | |||
500 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), | 514 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), |
501 | }, | 515 | }, |
502 | }, | 516 | }, |
517 | /* | ||
518 | * Some machines report wrong key events on the acpi-bus, suppress | ||
519 | * key event reporting on these. Note this is only intended to work | ||
520 | * around events which are plain wrong. In some cases we get double | ||
521 | * events, in this case acpi-video is considered the canonical source | ||
522 | * and the events from the other source should be filtered. E.g. | ||
523 | * by calling acpi_video_handles_brightness_key_presses() from the | ||
524 | * vendor acpi/wmi driver or by using /lib/udev/hwdb.d/60-keyboard.hwdb | ||
525 | */ | ||
526 | { | ||
527 | .callback = video_set_report_key_events, | ||
528 | .driver_data = (void *)((uintptr_t)REPORT_OUTPUT_KEY_EVENTS), | ||
529 | .ident = "Dell Vostro V131", | ||
530 | .matches = { | ||
531 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
532 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), | ||
533 | }, | ||
534 | }, | ||
503 | {} | 535 | {} |
504 | }; | 536 | }; |
505 | 537 | ||
@@ -1480,7 +1512,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1480 | /* Something vetoed the keypress. */ | 1512 | /* Something vetoed the keypress. */ |
1481 | keycode = 0; | 1513 | keycode = 0; |
1482 | 1514 | ||
1483 | if (keycode) { | 1515 | if (keycode && (report_key_events & REPORT_OUTPUT_KEY_EVENTS)) { |
1484 | input_report_key(input, keycode, 1); | 1516 | input_report_key(input, keycode, 1); |
1485 | input_sync(input); | 1517 | input_sync(input); |
1486 | input_report_key(input, keycode, 0); | 1518 | input_report_key(input, keycode, 0); |
@@ -1544,7 +1576,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1544 | 1576 | ||
1545 | acpi_notifier_call_chain(device, event, 0); | 1577 | acpi_notifier_call_chain(device, event, 0); |
1546 | 1578 | ||
1547 | if (keycode) { | 1579 | if (keycode && (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS)) { |
1548 | input_report_key(input, keycode, 1); | 1580 | input_report_key(input, keycode, 1); |
1549 | input_sync(input); | 1581 | input_sync(input); |
1550 | input_report_key(input, keycode, 0); | 1582 | input_report_key(input, keycode, 0); |
@@ -2017,8 +2049,8 @@ int acpi_video_register(void) | |||
2017 | { | 2049 | { |
2018 | int ret = 0; | 2050 | int ret = 0; |
2019 | 2051 | ||
2020 | mutex_lock(®ister_count_mutex); | 2052 | mutex_lock(®ister_done_mutex); |
2021 | if (register_count) { | 2053 | if (completion_done(®ister_done)) { |
2022 | /* | 2054 | /* |
2023 | * if the function of acpi_video_register is already called, | 2055 | * if the function of acpi_video_register is already called, |
2024 | * don't register the acpi_vide_bus again and return no error. | 2056 | * don't register the acpi_vide_bus again and return no error. |
@@ -2039,22 +2071,22 @@ int acpi_video_register(void) | |||
2039 | * When the acpi_video_bus is loaded successfully, increase | 2071 | * When the acpi_video_bus is loaded successfully, increase |
2040 | * the counter reference. | 2072 | * the counter reference. |
2041 | */ | 2073 | */ |
2042 | register_count = 1; | 2074 | complete(®ister_done); |
2043 | 2075 | ||
2044 | leave: | 2076 | leave: |
2045 | mutex_unlock(®ister_count_mutex); | 2077 | mutex_unlock(®ister_done_mutex); |
2046 | return ret; | 2078 | return ret; |
2047 | } | 2079 | } |
2048 | EXPORT_SYMBOL(acpi_video_register); | 2080 | EXPORT_SYMBOL(acpi_video_register); |
2049 | 2081 | ||
2050 | void acpi_video_unregister(void) | 2082 | void acpi_video_unregister(void) |
2051 | { | 2083 | { |
2052 | mutex_lock(®ister_count_mutex); | 2084 | mutex_lock(®ister_done_mutex); |
2053 | if (register_count) { | 2085 | if (completion_done(®ister_done)) { |
2054 | acpi_bus_unregister_driver(&acpi_video_bus); | 2086 | acpi_bus_unregister_driver(&acpi_video_bus); |
2055 | register_count = 0; | 2087 | reinit_completion(®ister_done); |
2056 | } | 2088 | } |
2057 | mutex_unlock(®ister_count_mutex); | 2089 | mutex_unlock(®ister_done_mutex); |
2058 | } | 2090 | } |
2059 | EXPORT_SYMBOL(acpi_video_unregister); | 2091 | EXPORT_SYMBOL(acpi_video_unregister); |
2060 | 2092 | ||
@@ -2062,15 +2094,29 @@ void acpi_video_unregister_backlight(void) | |||
2062 | { | 2094 | { |
2063 | struct acpi_video_bus *video; | 2095 | struct acpi_video_bus *video; |
2064 | 2096 | ||
2065 | mutex_lock(®ister_count_mutex); | 2097 | mutex_lock(®ister_done_mutex); |
2066 | if (register_count) { | 2098 | if (completion_done(®ister_done)) { |
2067 | mutex_lock(&video_list_lock); | 2099 | mutex_lock(&video_list_lock); |
2068 | list_for_each_entry(video, &video_bus_head, entry) | 2100 | list_for_each_entry(video, &video_bus_head, entry) |
2069 | acpi_video_bus_unregister_backlight(video); | 2101 | acpi_video_bus_unregister_backlight(video); |
2070 | mutex_unlock(&video_list_lock); | 2102 | mutex_unlock(&video_list_lock); |
2071 | } | 2103 | } |
2072 | mutex_unlock(®ister_count_mutex); | 2104 | mutex_unlock(®ister_done_mutex); |
2105 | } | ||
2106 | |||
2107 | bool acpi_video_handles_brightness_key_presses(void) | ||
2108 | { | ||
2109 | bool have_video_busses; | ||
2110 | |||
2111 | wait_for_completion(®ister_done); | ||
2112 | mutex_lock(&video_list_lock); | ||
2113 | have_video_busses = !list_empty(&video_bus_head); | ||
2114 | mutex_unlock(&video_list_lock); | ||
2115 | |||
2116 | return have_video_busses && | ||
2117 | (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS); | ||
2073 | } | 2118 | } |
2119 | EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses); | ||
2074 | 2120 | ||
2075 | /* | 2121 | /* |
2076 | * This is kind of nasty. Hardware using Intel chipsets may require | 2122 | * This is kind of nasty. Hardware using Intel chipsets may require |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index daaf1c4e1e0f..90e2d54be526 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -250,6 +250,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { | |||
250 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), | 250 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), |
251 | }, | 251 | }, |
252 | }, | 252 | }, |
253 | { | ||
254 | /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */ | ||
255 | .callback = video_detect_force_video, | ||
256 | .ident = "SAMSUNG 530U4E/540U4E", | ||
257 | .matches = { | ||
258 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
259 | DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), | ||
260 | }, | ||
261 | }, | ||
253 | 262 | ||
254 | /* Non win8 machines which need native backlight nevertheless */ | 263 | /* Non win8 machines which need native backlight nevertheless */ |
255 | { | 264 | { |
@@ -279,6 +288,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { | |||
279 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), | 288 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), |
280 | }, | 289 | }, |
281 | }, | 290 | }, |
291 | { | ||
292 | .callback = video_detect_force_native, | ||
293 | .ident = "Dell Vostro V131", | ||
294 | .matches = { | ||
295 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
296 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), | ||
297 | }, | ||
298 | }, | ||
282 | { }, | 299 | { }, |
283 | }; | 300 | }; |
284 | 301 | ||