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:
commit
b12745cce2
|
@ -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(®ister_count_mutex);
|
||||
if (register_count) {
|
||||
mutex_lock(®ister_done_mutex);
|
||||
if (completion_done(®ister_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(®ister_done);
|
||||
|
||||
leave:
|
||||
mutex_unlock(®ister_count_mutex);
|
||||
mutex_unlock(®ister_done_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_register);
|
||||
|
||||
void acpi_video_unregister(void)
|
||||
{
|
||||
mutex_lock(®ister_count_mutex);
|
||||
if (register_count) {
|
||||
mutex_lock(®ister_done_mutex);
|
||||
if (completion_done(®ister_done)) {
|
||||
acpi_bus_unregister_driver(&acpi_video_bus);
|
||||
register_count = 0;
|
||||
reinit_completion(®ister_done);
|
||||
}
|
||||
mutex_unlock(®ister_count_mutex);
|
||||
mutex_unlock(®ister_done_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_unregister);
|
||||
|
||||
|
@ -2062,16 +2094,30 @@ void acpi_video_unregister_backlight(void)
|
|||
{
|
||||
struct acpi_video_bus *video;
|
||||
|
||||
mutex_lock(®ister_count_mutex);
|
||||
if (register_count) {
|
||||
mutex_lock(®ister_done_mutex);
|
||||
if (completion_done(®ister_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(®ister_count_mutex);
|
||||
mutex_unlock(®ister_done_mutex);
|
||||
}
|
||||
|
||||
bool acpi_video_handles_brightness_key_presses(void)
|
||||
{
|
||||
bool have_video_busses;
|
||||
|
||||
wait_for_completion(®ister_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
|
||||
|
|
|
@ -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"),
|
||||
},
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
|
||||
|
||||
static int acpi_video;
|
||||
|
||||
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
||||
|
||||
/*
|
||||
|
@ -159,7 +157,8 @@ static void dell_wmi_process_key(int reported_key)
|
|||
|
||||
/* Don't report brightness notifications that will also come via ACPI */
|
||||
if ((key->keycode == KEY_BRIGHTNESSUP ||
|
||||
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video)
|
||||
key->keycode == KEY_BRIGHTNESSDOWN) &&
|
||||
acpi_video_handles_brightness_key_presses())
|
||||
return;
|
||||
|
||||
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
|
||||
|
@ -398,7 +397,6 @@ static int __init dell_wmi_init(void)
|
|||
}
|
||||
|
||||
dmi_walk(find_hk_type, NULL);
|
||||
acpi_video = acpi_video_get_backlight_type() != acpi_backlight_vendor;
|
||||
|
||||
err = dell_wmi_input_setup();
|
||||
if (err)
|
||||
|
|
|
@ -3488,7 +3488,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||
/* Do not issue duplicate brightness change events to
|
||||
* userspace. tpacpi_detect_brightness_capabilities() must have
|
||||
* 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 "
|
||||
"brightness control, supported by the ACPI "
|
||||
"video driver\n");
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __ACPI_VIDEO_H
|
||||
|
||||
#include <linux/errno.h> /* for ENODEV */
|
||||
#include <linux/types.h> /* for bool */
|
||||
|
||||
struct acpi_device;
|
||||
|
||||
|
@ -31,6 +32,7 @@ extern int acpi_video_get_edid(struct acpi_device *device, int type,
|
|||
int device_id, void **edid);
|
||||
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 bool acpi_video_handles_brightness_key_presses(void);
|
||||
#else
|
||||
static inline int acpi_video_register(void) { return 0; }
|
||||
static inline void acpi_video_unregister(void) { return; }
|
||||
|
@ -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 bool acpi_video_handles_brightness_key_presses(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue