Commit b12745cc authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

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
parents f3a1bca0 aecbd9b1
...@@ -77,14 +77,21 @@ module_param(allow_duplicates, bool, 0644); ...@@ -77,14 +77,21 @@ module_param(allow_duplicates, bool, 0644);
static int disable_backlight_sysfs_if = -1; static int disable_backlight_sysfs_if = -1;
module_param(disable_backlight_sysfs_if, int, 0444); 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; static bool device_id_scheme = false;
module_param(device_id_scheme, bool, 0444); module_param(device_id_scheme, bool, 0444);
static bool only_lcd = false; static bool only_lcd = false;
module_param(only_lcd, bool, 0444); module_param(only_lcd, bool, 0444);
static int register_count; static DECLARE_COMPLETION(register_done);
static DEFINE_MUTEX(register_count_mutex); static DEFINE_MUTEX(register_done_mutex);
static struct mutex video_list_lock; static struct mutex video_list_lock;
static struct list_head video_bus_head; static struct list_head video_bus_head;
static int acpi_video_bus_add(struct acpi_device *device); 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,6 +419,13 @@ static int video_enable_only_lcd(const struct dmi_system_id *d)
return 0; 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[] = { static struct dmi_system_id video_dmi_table[] = {
/* /*
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 * 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,6 +514,24 @@ static struct dmi_system_id video_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"), 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) ...@@ -1480,7 +1512,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
/* Something vetoed the keypress. */ /* Something vetoed the keypress. */
keycode = 0; keycode = 0;
if (keycode) { if (keycode && (report_key_events & REPORT_OUTPUT_KEY_EVENTS)) {
input_report_key(input, keycode, 1); input_report_key(input, keycode, 1);
input_sync(input); input_sync(input);
input_report_key(input, keycode, 0); input_report_key(input, keycode, 0);
...@@ -1544,7 +1576,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -1544,7 +1576,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
acpi_notifier_call_chain(device, event, 0); 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_report_key(input, keycode, 1);
input_sync(input); input_sync(input);
input_report_key(input, keycode, 0); input_report_key(input, keycode, 0);
...@@ -2017,8 +2049,8 @@ int acpi_video_register(void) ...@@ -2017,8 +2049,8 @@ int acpi_video_register(void)
{ {
int ret = 0; int ret = 0;
mutex_lock(&register_count_mutex); mutex_lock(&register_done_mutex);
if (register_count) { if (completion_done(&register_done)) {
/* /*
* if the function of acpi_video_register is already called, * if the function of acpi_video_register is already called,
* don't register the acpi_vide_bus again and return no error. * don't register the acpi_vide_bus again and return no error.
...@@ -2039,22 +2071,22 @@ int acpi_video_register(void) ...@@ -2039,22 +2071,22 @@ int acpi_video_register(void)
* When the acpi_video_bus is loaded successfully, increase * When the acpi_video_bus is loaded successfully, increase
* the counter reference. * the counter reference.
*/ */
register_count = 1; complete(&register_done);
leave: leave:
mutex_unlock(&register_count_mutex); mutex_unlock(&register_done_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(acpi_video_register); EXPORT_SYMBOL(acpi_video_register);
void acpi_video_unregister(void) void acpi_video_unregister(void)
{ {
mutex_lock(&register_count_mutex); mutex_lock(&register_done_mutex);
if (register_count) { if (completion_done(&register_done)) {
acpi_bus_unregister_driver(&acpi_video_bus); 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); EXPORT_SYMBOL(acpi_video_unregister);
...@@ -2062,15 +2094,29 @@ void acpi_video_unregister_backlight(void) ...@@ -2062,15 +2094,29 @@ void acpi_video_unregister_backlight(void)
{ {
struct acpi_video_bus *video; struct acpi_video_bus *video;
mutex_lock(&register_count_mutex); mutex_lock(&register_done_mutex);
if (register_count) { if (completion_done(&register_done)) {
mutex_lock(&video_list_lock); mutex_lock(&video_list_lock);
list_for_each_entry(video, &video_bus_head, entry) list_for_each_entry(video, &video_bus_head, entry)
acpi_video_bus_unregister_backlight(video); acpi_video_bus_unregister_backlight(video);
mutex_unlock(&video_list_lock); 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 * This is kind of nasty. Hardware using Intel chipsets may require
......
...@@ -250,6 +250,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { ...@@ -250,6 +250,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), 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 */ /* Non win8 machines which need native backlight nevertheless */
{ {
...@@ -279,6 +288,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { ...@@ -279,6 +288,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), 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"),
},
},
{ }, { },
}; };
......
...@@ -43,8 +43,6 @@ MODULE_LICENSE("GPL"); ...@@ -43,8 +43,6 @@ MODULE_LICENSE("GPL");
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492" #define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
static int acpi_video;
MODULE_ALIAS("wmi:"DELL_EVENT_GUID); MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
/* /*
...@@ -159,7 +157,8 @@ static void dell_wmi_process_key(int reported_key) ...@@ -159,7 +157,8 @@ static void dell_wmi_process_key(int reported_key)
/* Don't report brightness notifications that will also come via ACPI */ /* Don't report brightness notifications that will also come via ACPI */
if ((key->keycode == KEY_BRIGHTNESSUP || if ((key->keycode == KEY_BRIGHTNESSUP ||
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) key->keycode == KEY_BRIGHTNESSDOWN) &&
acpi_video_handles_brightness_key_presses())
return; return;
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true); sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
...@@ -398,7 +397,6 @@ static int __init dell_wmi_init(void) ...@@ -398,7 +397,6 @@ static int __init dell_wmi_init(void)
} }
dmi_walk(find_hk_type, NULL); dmi_walk(find_hk_type, NULL);
acpi_video = acpi_video_get_backlight_type() != acpi_backlight_vendor;
err = dell_wmi_input_setup(); err = dell_wmi_input_setup();
if (err) if (err)
......
...@@ -3488,7 +3488,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -3488,7 +3488,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* Do not issue duplicate brightness change events to /* Do not issue duplicate brightness change events to
* userspace. tpacpi_detect_brightness_capabilities() must have * userspace. tpacpi_detect_brightness_capabilities() must have
* been called before this point */ * been called before this point */
if (acpi_video_get_backlight_type() != acpi_backlight_vendor) { if (acpi_video_handles_brightness_key_presses()) {
pr_info("This ThinkPad has standard ACPI backlight " pr_info("This ThinkPad has standard ACPI backlight "
"brightness control, supported by the ACPI " "brightness control, supported by the ACPI "
"video driver\n"); "video driver\n");
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __ACPI_VIDEO_H #define __ACPI_VIDEO_H
#include <linux/errno.h> /* for ENODEV */ #include <linux/errno.h> /* for ENODEV */
#include <linux/types.h> /* for bool */
struct acpi_device; struct acpi_device;
...@@ -31,6 +32,7 @@ extern int acpi_video_get_edid(struct acpi_device *device, int type, ...@@ -31,6 +32,7 @@ extern int acpi_video_get_edid(struct acpi_device *device, int type,
int device_id, void **edid); int device_id, void **edid);
extern enum acpi_backlight_type acpi_video_get_backlight_type(void); extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type); extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
extern bool acpi_video_handles_brightness_key_presses(void);
#else #else
static inline int acpi_video_register(void) { return 0; } static inline int acpi_video_register(void) { return 0; }
static inline void acpi_video_unregister(void) { return; } static inline void acpi_video_unregister(void) { return; }
...@@ -46,6 +48,10 @@ static inline enum acpi_backlight_type acpi_video_get_backlight_type(void) ...@@ -46,6 +48,10 @@ static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type) static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
{ {
} }
static inline bool acpi_video_handles_brightness_key_presses(void)
{
return false;
}
#endif #endif
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment