imx-drm: imx-drm-core: Fix circular locking dependency
Booting a mx6 with CONFIG_PROVE_LOCKING we get:
======================================================
[ INFO: possible circular locking dependency detected ]
3.12.0-rc4-next-
20131009+ #34 Not tainted
-------------------------------------------------------
swapper/0/1 is trying to acquire lock:
(&imx_drm_device->mutex){+.+.+.}, at: [<
804575a8>] imx_drm_encoder_get_mux_id+0x28/0x98
but task is already holding lock:
(&crtc->mutex){+.+...}, at: [<
802fe778>] drm_modeset_lock_all+0x40/0x54
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&crtc->mutex){+.+...}:
[<
800777d0>] __lock_acquire+0x18d4/0x1c24
[<
80077fec>] lock_acquire+0x68/0x7c
[<
805ead5c>] _mutex_lock_nest_lock+0x58/0x3a8
[<
802fec50>] drm_crtc_init+0x48/0xa8
[<
80457c88>] imx_drm_add_crtc+0xd4/0x144
[<
8045e2e8>] ipu_drm_probe+0x114/0x1fc
[<
80312278>] platform_drv_probe+0x20/0x50
[<
80310c68>] driver_probe_device+0x110/0x22c
[<
80310e20>] __driver_attach+0x9c/0xa0
[<
8030f218>] bus_for_each_dev+0x5c/0x90
[<
80310750>] driver_attach+0x20/0x28
[<
8031034c>] bus_add_driver+0xdc/0x1dc
[<
803114d8>] driver_register+0x80/0xfc
[<
80312198>] __platform_driver_register+0x50/0x64
[<
808172fc>] ipu_drm_driver_init+0x18/0x20
[<
800088c0>] do_one_initcall+0xfc/0x160
[<
807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<
805e2930>] kernel_init+0x10/0xec
[<
8000ea68>] ret_from_fork+0x14/0x2c
-> #1 (&dev->mode_config.mutex){+.+.+.}:
[<
800777d0>] __lock_acquire+0x18d4/0x1c24
[<
80077fec>] lock_acquire+0x68/0x7c
[<
805eb100>] mutex_lock_nested+0x54/0x3a4
[<
802fe758>] drm_modeset_lock_all+0x20/0x54
[<
802fead4>] drm_encoder_init+0x20/0x7c
[<
80457ae4>] imx_drm_add_encoder+0x88/0xec
[<
80459838>] imx_ldb_probe+0x344/0x4fc
[<
80312278>] platform_drv_probe+0x20/0x50
[<
80310c68>] driver_probe_device+0x110/0x22c
[<
80310e20>] __driver_attach+0x9c/0xa0
[<
8030f218>] bus_for_each_dev+0x5c/0x90
[<
80310750>] driver_attach+0x20/0x28
[<
8031034c>] bus_add_driver+0xdc/0x1dc
[<
803114d8>] driver_register+0x80/0xfc
[<
80312198>] __platform_driver_register+0x50/0x64
[<
8081722c>] imx_ldb_driver_init+0x18/0x20
[<
800088c0>] do_one_initcall+0xfc/0x160
[<
807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<
805e2930>] kernel_init+0x10/0xec
[<
8000ea68>] ret_from_fork+0x14/0x2c
-> #0 (&imx_drm_device->mutex){+.+.+.}:
[<
805e510c>] print_circular_bug+0x74/0x2e0
[<
80077ad0>] __lock_acquire+0x1bd4/0x1c24
[<
80077fec>] lock_acquire+0x68/0x7c
[<
805eb100>] mutex_lock_nested+0x54/0x3a4
[<
804575a8>] imx_drm_encoder_get_mux_id+0x28/0x98
[<
80459a98>] imx_ldb_encoder_prepare+0x34/0x114
[<
802ef724>] drm_crtc_helper_set_mode+0x1f0/0x4c0
[<
802f0344>] drm_crtc_helper_set_config+0x828/0x99c
[<
802ff270>] drm_mode_set_config_internal+0x5c/0xdc
[<
802eebe0>] drm_fb_helper_set_par+0x50/0xb4
[<
802af580>] fbcon_init+0x490/0x500
[<
802dd104>] visual_init+0xa8/0xf8
[<
802df414>] do_bind_con_driver+0x140/0x37c
[<
802df764>] do_take_over_console+0x114/0x1c4
[<
802af65c>] do_fbcon_takeover+0x6c/0xd4
[<
802b2b30>] fbcon_event_notify+0x7c8/0x818
[<
80049954>] notifier_call_chain+0x4c/0x8c
[<
80049cd8>] __blocking_notifier_call_chain+0x50/0x68
[<
80049d10>] blocking_notifier_call_chain+0x20/0x28
[<
802a75f0>] fb_notifier_call_chain+0x1c/0x24
[<
802a9224>] register_framebuffer+0x188/0x268
[<
802ee994>] drm_fb_helper_initial_config+0x2bc/0x4b8
[<
802f118c>] drm_fbdev_cma_init+0x7c/0xec
[<
80817288>] imx_fb_helper_init+0x54/0x90
[<
800088c0>] do_one_initcall+0xfc/0x160
[<
807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<
805e2930>] kernel_init+0x10/0xec
[<
8000ea68>] ret_from_fork+0x14/0x2c
other info that might help us debug this:
Chain exists of:
&imx_drm_device->mutex --> &dev->mode_config.mutex --> &crtc->mutex
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&crtc->mutex);
lock(&dev->mode_config.mutex);
lock(&crtc->mutex);
lock(&imx_drm_device->mutex);
*** DEADLOCK ***
6 locks held by swapper/0/1:
#0: (registration_lock){+.+.+.}, at: [<
802a90bc>] register_framebuffer+0x20/0x268
#1: (&fb_info->lock){+.+.+.}, at: [<
802a7a90>] lock_fb_info+0x20/0x44
#2: (console_lock){+.+.+.}, at: [<
802a9218>] register_framebuffer+0x17c/0x268
#3: ((fb_notifier_list).rwsem){.+.+.+}, at: [<
80049cbc>] __blocking_notifier_call_chain+0x34/0x68
#4: (&dev->mode_config.mutex){+.+.+.}, at: [<
802fe758>] drm_modeset_lock_all+0x20/0x54
#5: (&crtc->mutex){+.+...}, at: [<
802fe778>] drm_modeset_lock_all+0x40/0x54
In order to avoid this lockdep warning, remove the locking from
imx_drm_encoder_get_mux_id() and imx_drm_crtc_panel_format_pins().
Tested on a mx6sabrelite and mx53qsb.
Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>