diff options
author | Fabio Estevam <fabio.estevam@freescale.com> | 2013-01-16 07:58:41 -0500 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2013-01-17 03:14:29 -0500 |
commit | e6b267ce14f61d9da0151b97ee26ab4d38055567 (patch) | |
tree | 3be89be02a17a929c96187d66098e8163a8121a8 /drivers | |
parent | 83ae20981ae924c37d02a42c829155fc3851260c (diff) |
video: imxfb: Do not crash on reboot
Issuing a "reboot" command after the LCD times out causes the following
warnings:
Requesting system reboot
------------[ cut here ]------------
WARNING: at drivers/clk/clk.c:471 clk_disable+0x24/0x50()
Modules linked in:
[<c001ad90>] (unwind_backtrace+0x0/0xf4) from [<c0025aac>] (warn_slowpath_common+0x48/0x60)
[<c0025aac>] (warn_slowpath_common+0x48/0x60) from [<c0025ae0>] (warn_slowpath_null+0x1c/0x24)
[<c0025ae0>] (warn_slowpath_null+0x1c/0x24) from [<c03960a0>] (clk_disable+0x24/0x50)
[<c03960a0>] (clk_disable+0x24/0x50) from [<c02695a0>] (imxfb_disable_controller+0x48/0x7c)
[<c02695a0>] (imxfb_disable_controller+0x48/0x7c) from [<c029d838>] (platform_drv_shutdown+0x18/0x1c)
[<c029d838>] (platform_drv_shutdown+0x18/0x1c) from [<c02990fc>] (device_shutdown+0x48/0x14c)
[<c02990fc>] (device_shutdown+0x48/0x14c) from [<c003d09c>] (kernel_restart_prepare+0x2c/0x3c)
[<c003d09c>] (kernel_restart_prepare+0x2c/0x3c) from [<c003d0e4>] (kernel_restart+0xc/0x48)
[<c003d0e4>] (kernel_restart+0xc/0x48) from [<c003d1e8>] (sys_reboot+0xc0/0x1bc)
[<c003d1e8>] (sys_reboot+0xc0/0x1bc) from [<c0014ca0>] (ret_fast_syscall+0x0/0x2c)
---[ end trace da6b502ca79c854f ]---
------------[ cut here ]------------
WARNING: at drivers/clk/clk.c:380 clk_unprepare+0x1c/0x2c()
Modules linked in:
[<c001ad90>] (unwind_backtrace+0x0/0xf4) from [<c0025aac>] (warn_slowpath_common+0x48/0x60)
[<c0025aac>] (warn_slowpath_common+0x48/0x60) from [<c0025ae0>] (warn_slowpath_null+0x1c/0x24)
[<c0025ae0>] (warn_slowpath_null+0x1c/0x24) from [<c0396338>] (clk_unprepare+0x1c/0x2c)
[<c0396338>] (clk_unprepare+0x1c/0x2c) from [<c02695a8>] (imxfb_disable_controller+0x50/0x7c)
[<c02695a8>] (imxfb_disable_controller+0x50/0x7c) from [<c029d838>] (platform_drv_shutdown+0x18/0x1c)
[<c029d838>] (platform_drv_shutdown+0x18/0x1c) from [<c02990fc>] (device_shutdown+0x48/0x14c)
[<c02990fc>] (device_shutdown+0x48/0x14c) from [<c003d09c>] (kernel_restart_prepare+0x2c/0x3c)
[<c003d09c>] (kernel_restart_prepare+0x2c/0x3c) from [<c003d0e4>] (kernel_restart+0xc/0x48)
[<c003d0e4>] (kernel_restart+0xc/0x48) from [<c003d1e8>] (sys_reboot+0xc0/0x1bc)
[<c003d1e8>] (sys_reboot+0xc0/0x1bc) from [<c0014ca0>] (ret_fast_syscall+0x0/0x2c)
---[ end trace da6b502ca79c8550 ]---
------------[ cut here ]------------
This happens because "reboot" triggers imxfb_shutdown(), which calls
imxfb_disable_controller with the clocks already disabled.
To prevent this, add a clock enabled status so that we can check if the clocks
are enabled before disabling them.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/imxfb.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 8435c5d601a1..609f4e97bde7 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c | |||
@@ -139,6 +139,7 @@ struct imxfb_info { | |||
139 | struct clk *clk_ahb; | 139 | struct clk *clk_ahb; |
140 | struct clk *clk_per; | 140 | struct clk *clk_per; |
141 | enum imxfb_type devtype; | 141 | enum imxfb_type devtype; |
142 | bool enabled; | ||
142 | 143 | ||
143 | /* | 144 | /* |
144 | * These are the addresses we mapped | 145 | * These are the addresses we mapped |
@@ -536,6 +537,10 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi) | |||
536 | 537 | ||
537 | static void imxfb_enable_controller(struct imxfb_info *fbi) | 538 | static void imxfb_enable_controller(struct imxfb_info *fbi) |
538 | { | 539 | { |
540 | |||
541 | if (fbi->enabled) | ||
542 | return; | ||
543 | |||
539 | pr_debug("Enabling LCD controller\n"); | 544 | pr_debug("Enabling LCD controller\n"); |
540 | 545 | ||
541 | writel(fbi->screen_dma, fbi->regs + LCDC_SSA); | 546 | writel(fbi->screen_dma, fbi->regs + LCDC_SSA); |
@@ -556,6 +561,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) | |||
556 | clk_prepare_enable(fbi->clk_ipg); | 561 | clk_prepare_enable(fbi->clk_ipg); |
557 | clk_prepare_enable(fbi->clk_ahb); | 562 | clk_prepare_enable(fbi->clk_ahb); |
558 | clk_prepare_enable(fbi->clk_per); | 563 | clk_prepare_enable(fbi->clk_per); |
564 | fbi->enabled = true; | ||
559 | 565 | ||
560 | if (fbi->backlight_power) | 566 | if (fbi->backlight_power) |
561 | fbi->backlight_power(1); | 567 | fbi->backlight_power(1); |
@@ -565,6 +571,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) | |||
565 | 571 | ||
566 | static void imxfb_disable_controller(struct imxfb_info *fbi) | 572 | static void imxfb_disable_controller(struct imxfb_info *fbi) |
567 | { | 573 | { |
574 | if (!fbi->enabled) | ||
575 | return; | ||
576 | |||
568 | pr_debug("Disabling LCD controller\n"); | 577 | pr_debug("Disabling LCD controller\n"); |
569 | 578 | ||
570 | if (fbi->backlight_power) | 579 | if (fbi->backlight_power) |
@@ -575,6 +584,7 @@ static void imxfb_disable_controller(struct imxfb_info *fbi) | |||
575 | clk_disable_unprepare(fbi->clk_per); | 584 | clk_disable_unprepare(fbi->clk_per); |
576 | clk_disable_unprepare(fbi->clk_ipg); | 585 | clk_disable_unprepare(fbi->clk_ipg); |
577 | clk_disable_unprepare(fbi->clk_ahb); | 586 | clk_disable_unprepare(fbi->clk_ahb); |
587 | fbi->enabled = false; | ||
578 | 588 | ||
579 | writel(0, fbi->regs + LCDC_RMCR); | 589 | writel(0, fbi->regs + LCDC_RMCR); |
580 | } | 590 | } |