From: Adrien Schildknecht Date: Mon, 4 Jan 2016 22:22:28 +0000 (+0100) Subject: ACPI / video: driver must be registered before checking for keypresses X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=aecbd9b1bff6;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git ACPI / video: driver must be registered before checking for keypresses acpi_video_handles_brightness_key_presses() may use an uninitialized mutex. The error has been reported by lockdep: DEBUG_LOCKS_WARN_ON(l->magic != l). The function assumes that the video driver has been registered before being called. As explained in the comment of acpi_video_init(), the registration of the video class may be defered and thus may not take place in the init function of the module. Use completion mechanisms to make sure that acpi_video_handles_brightness_key_presses() wait for the completion of acpi_video_register() before using the mutex. Also get rid of register_count since task completion can replace it. Signed-off-by: Adrien Schildknecht Reviewed-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 80b13d498091..06a006ff89b0 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -90,8 +90,8 @@ 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); @@ -2049,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. @@ -2071,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); @@ -2094,20 +2094,21 @@ 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);