summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBibek Basu <bbasu@nvidia.com>2014-08-04 12:57:21 +0530
committerWinnie Hsu <whsu@nvidia.com>2014-09-03 18:00:03 -0700
commitac954dd4168e97d41d68d79d530144333a8ef132 (patch)
treecbe8a49e3775e0927be98812396efeba980b62e4 /drivers
parent2eed826401188b5d241d3bb9302915b50c6ef91e (diff)
tegra: dc: dont synchronize irq from irq thread
Synchronizing IRQ from irq thread context will never return because the thread will sleep forever.And thats the reason for DPM timeout and kernel crash when suspend hook also tries to do so. [ 204.471652] tegradc tegradc.1: **** DPM device timeout **** [ 204.484865] [<c07a58a8>] (__schedule+0x3b4/0x6e0) from [<c00ccf94>] (synchronize_irq+0xac/0xe4) [ 204.501399] [<c00ccf94>] (synchronize_irq+0xac/0xe4) from [<c0341628>] (tegra_dc_suspend+0xcc/0x15c) [ 204.518507] [<c0341628>] (tegra_dc_suspend+0xcc/0x15c) from [<c03da574>] (platform_pm_suspend+0x58/0x64) [ 204.536166] [<c03da574>] (platform_pm_suspend+0x58/0x64) from [<c0032c00>] (tegra_pd_suspend_dev+0x34/0x9c) [ 204.554226] [<c0032c00>] (tegra_pd_suspend_dev+0x34/0x9c) from [<c03e5384>] (pm_genpd_default_suspend+0x24/0x30) [ 204.572942] [<c03e5384>] (pm_genpd_default_suspend+0x24/0x30) from [<c03e5864>] (pm_genpd_suspend+0x58/0xa4) [ 204.591515] [<c03e5864>] (pm_genpd_suspend+0x58/0xa4) from [<c03dfb30>] (dpm_run_callback+0x34/0x54) [ 204.609552] [<c03dfb30>] (dpm_run_callback+0x34/0x54) from [<c03dffe4>] (__device_suspend+0x16c/0x380) Bug 1486344 Change-Id: Ie512262fdfef90dc199f1f39ebffb540b909f3e2 Signed-off-by: Bibek Basu <bbasu@nvidia.com> Reviewed-on: http://git-master/r/450815 GVS: Gerrit_Virtual_Submit Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/dc/dc.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 7602b4e87c9e..2809eef48ea3 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -100,7 +100,7 @@ static struct fb_videomode tegra_dc_vga_mode = {
static struct tegra_dc_mode override_disp_mode[3];
static void _tegra_dc_controller_disable(struct tegra_dc *dc);
-
+static void tegra_dc_disable_nosync(struct tegra_dc *dc);
struct tegra_dc *tegra_dcs[TEGRA_MAX_DC];
DEFINE_MUTEX(tegra_dc_lock);
@@ -2035,7 +2035,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *ptr)
mutex_unlock(&dc->lock);
if (need_disable)
- tegra_dc_disable(dc);
+ tegra_dc_disable_nosync(dc);
return IRQ_HANDLED;
}
@@ -2667,6 +2667,42 @@ static void _tegra_dc_disable(struct tegra_dc *dc)
tegra_log_suspend_time();
}
+static void tegra_dc_disable_nosync(struct tegra_dc *dc)
+{
+ if (WARN_ON(!dc || !dc->out || !dc->out_ops))
+ return;
+
+ tegra_dc_ext_disable(dc->ext);
+
+ /* it's important that new underflow work isn't scheduled before the
+ * lock is acquired. */
+ cancel_delayed_work_sync(&dc->underflow_work);
+
+ if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
+ mutex_lock(&dc->one_shot_lp_lock);
+ mutex_lock(&dc->lock);
+
+ if (dc->enabled) {
+ dc->enabled = false;
+ dc->blanked = false;
+
+ if (!dc->suspended)
+ _tegra_dc_disable(dc);
+ }
+
+#ifdef CONFIG_SWITCH
+ switch_set_state(&dc->modeset_switch, 0);
+#endif
+ mutex_unlock(&dc->lock);
+ if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
+ mutex_unlock(&dc->one_shot_lp_lock);
+ trace_display_mode(dc, &dc->mode);
+
+ /* disable pending clks due to uncompleted frames */
+ while (tegra_is_clk_enabled(dc->clk))
+ tegra_dc_put(dc);
+}
+
void tegra_dc_disable(struct tegra_dc *dc)
{
if (WARN_ON(!dc || !dc->out || !dc->out_ops))