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
This commit is contained in:
Rafael J. Wysocki 2016-01-12 01:09:27 +01:00
commit b12745cce2
5 changed files with 87 additions and 20 deletions

View file

@ -77,14 +77,21 @@ module_param(allow_duplicates, bool, 0644);
static int disable_backlight_sysfs_if = -1;
module_param(disable_backlight_sysfs_if, int, 0444);
#define REPORT_OUTPUT_KEY_EVENTS 0x01
#define REPORT_BRIGHTNESS_KEY_EVENTS 0x02
static int report_key_events = -1;
module_param(report_key_events, int, 0644);
MODULE_PARM_DESC(report_key_events,
"0: none, 1: output changes, 2: brightness changes, 3: all");
static bool device_id_scheme = false;
module_param(device_id_scheme, bool, 0444);
static bool only_lcd = false;
module_param(only_lcd, bool, 0444);
static int register_count;
static DEFINE_MUTEX(register_count_mutex);
static DECLARE_COMPLETION(register_done);
static DEFINE_MUTEX(register_done_mutex);
static struct mutex video_list_lock;
static struct list_head video_bus_head;
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)
return 0;
}
static int video_set_report_key_events(const struct dmi_system_id *id)
{
if (report_key_events == -1)
report_key_events = (uintptr_t)id->driver_data;
return 0;
}
static struct dmi_system_id video_dmi_table[] = {
/*
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
@ -500,6 +514,24 @@ static struct dmi_system_id video_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),
},
},
/*
* Some machines report wrong key events on the acpi-bus, suppress
* key event reporting on these. Note this is only intended to work
* around events which are plain wrong. In some cases we get double
* events, in this case acpi-video is considered the canonical source
* and the events from the other source should be filtered. E.g.
* by calling acpi_video_handles_brightness_key_presses() from the
* vendor acpi/wmi driver or by using /lib/udev/hwdb.d/60-keyboard.hwdb
*/
{
.callback = video_set_report_key_events,
.driver_data = (void *)((uintptr_t)REPORT_OUTPUT_KEY_EVENTS),
.ident = "Dell Vostro V131",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
},
},
{}
};
@ -1480,7 +1512,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
/* Something vetoed the keypress. */
keycode = 0;
if (keycode) {
if (keycode && (report_key_events & REPORT_OUTPUT_KEY_EVENTS)) {
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
@ -1544,7 +1576,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
acpi_notifier_call_chain(device, event, 0);
if (keycode) {
if (keycode && (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS)) {
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
@ -2017,8 +2049,8 @@ int acpi_video_register(void)
{
int ret = 0;
mutex_lock(&register_count_mutex);
if (register_count) {
mutex_lock(&register_done_mutex);
if (completion_done(&register_done)) {
/*
* if the function of acpi_video_register is already called,
* don't register the acpi_vide_bus again and return no error.
@ -2039,22 +2071,22 @@ int acpi_video_register(void)
* When the acpi_video_bus is loaded successfully, increase
* the counter reference.
*/
register_count = 1;
complete(&register_done);
leave:
mutex_unlock(&register_count_mutex);
mutex_unlock(&register_done_mutex);
return ret;
}
EXPORT_SYMBOL(acpi_video_register);
void acpi_video_unregister(void)
{
mutex_lock(&register_count_mutex);
if (register_count) {
mutex_lock(&register_done_mutex);
if (completion_done(&register_done)) {
acpi_bus_unregister_driver(&acpi_video_bus);
register_count = 0;
reinit_completion(&register_done);
}
mutex_unlock(&register_count_mutex);
mutex_unlock(&register_done_mutex);
}
EXPORT_SYMBOL(acpi_video_unregister);
@ -2062,16 +2094,30 @@ void acpi_video_unregister_backlight(void)
{
struct acpi_video_bus *video;
mutex_lock(&register_count_mutex);
if (register_count) {
mutex_lock(&register_done_mutex);
if (completion_done(&register_done)) {
mutex_lock(&video_list_lock);
list_for_each_entry(video, &video_bus_head, entry)
acpi_video_bus_unregister_backlight(video);
mutex_unlock(&video_list_lock);
}
mutex_unlock(&register_count_mutex);
mutex_unlock(&register_done_mutex);
}
bool acpi_video_handles_brightness_key_presses(void)
{
bool have_video_busses;
wait_for_completion(&register_done);
mutex_lock(&video_list_lock);
have_video_busses = !list_empty(&video_bus_head);
mutex_unlock(&video_list_lock);
return have_video_busses &&
(report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS);
}
EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses);
/*
* This is kind of nasty. Hardware using Intel chipsets may require
* the video opregion code to be run first in order to initialise

View file

@ -250,6 +250,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
},
},
{
/* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
.callback = video_detect_force_video,
.ident = "SAMSUNG 530U4E/540U4E",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
},
},
/* Non win8 machines which need native backlight nevertheless */
{
@ -279,6 +288,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
},
},
{
.callback = video_detect_force_native,
.ident = "Dell Vostro V131",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
},
},
{ },
};