From 65852c8cbaf89a0dbc4047581feccd6aaddb8bcf Mon Sep 17 00:00:00 2001 From: sharath sarangpur Date: Mon, 24 Jun 2013 19:15:26 -0700 Subject: video: tegra: dc: hdmi: calling tegra_hotplug_signal to queue deferred work Call tegra_hotplug_signal to queue deferred work after a delay of 30ms and call gpio_get_value in tegra_dc_hpd bug 1310096 bug 1298680 Change-Id: Iab37af3258429b1e281705eb5b077be31b53b07f Signed-off-by: sharath sarangpur Reviewed-on: http://git-master/r/241633 GVS: Gerrit_Virtual_Submit Reviewed-by: Jon Mayo Reviewed-by: Anshul Jain (SW) --- drivers/video/tegra/dc/dc.c | 2 +- drivers/video/tegra/dc/hdmi.c | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 8487b86c2034..251aed3c494e 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -749,7 +749,7 @@ bool tegra_dc_hpd(struct tegra_dc *dc) if (dc->out->hotplug_state == -1) /* force off */ return false; } - level = gpio_get_value_cansleep(dc->out->hotplug_gpio); + level = gpio_get_value(dc->out->hotplug_gpio); sense = dc->out->flags & TEGRA_DC_OUT_HOTPLUG_MASK; diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c index 253a13ad24db..5ad5d1fcbdf9 100644 --- a/drivers/video/tegra/dc/hdmi.c +++ b/drivers/video/tegra/dc/hdmi.c @@ -639,6 +639,28 @@ static int dbg_hotplug_open(struct inode *inode, struct file *file) return single_open(file, dbg_hotplug_show, inode->i_private); } +static inline void tegra_hdmi_hotplug_signal(struct tegra_dc_hdmi_data *hdmi) +{ + tegra_dc_hpd(hdmi->dc); + queue_delayed_work(system_nrt_wq, &hdmi->work, + msecs_to_jiffies(30)); +} + +static inline void tegra_hdmi_hotplug_disable(struct tegra_dc_hdmi_data *hdmi) +{ + struct tegra_dc *dc = hdmi->dc; + + disable_irq(gpio_to_irq(dc->out->hotplug_gpio)); +} + +/* enables hotplug IRQ - this must be balanced */ +static inline void tegra_hdmi_hotplug_enable(struct tegra_dc_hdmi_data *hdmi) +{ + struct tegra_dc *dc = hdmi->dc; + + enable_irq(gpio_to_irq(dc->out->hotplug_gpio)); +} + static int dbg_hotplug_write(struct file *file, const char __user *addr, size_t len, loff_t *pos) { @@ -657,9 +679,7 @@ static int dbg_hotplug_write(struct file *file, const char __user *addr, dc->out->hotplug_state = new_state; - queue_delayed_work(system_nrt_wq, &hdmi->work, - msecs_to_jiffies(100)); - + tegra_hdmi_hotplug_signal(hdmi); return len; } @@ -947,8 +967,7 @@ static irqreturn_t tegra_dc_hdmi_irq(int irq, void *ptr) spin_lock_irqsave(&hdmi->suspend_lock, flags); if (!hdmi->suspended) { __cancel_delayed_work(&hdmi->work); - queue_delayed_work(system_nrt_wq, &hdmi->work, - msecs_to_jiffies(100)); + tegra_hdmi_hotplug_signal(hdmi); } spin_unlock_irqrestore(&hdmi->suspend_lock, flags); @@ -960,6 +979,9 @@ static void tegra_dc_hdmi_suspend(struct tegra_dc *dc) struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc); unsigned long flags; + /* turn off hotplug detection to avoid resume event when +5V falls */ + tegra_hdmi_hotplug_disable(hdmi); + tegra_nvhdcp_suspend(hdmi->nvhdcp); spin_lock_irqsave(&hdmi->suspend_lock, flags); hdmi->suspended = true; @@ -969,17 +991,17 @@ static void tegra_dc_hdmi_suspend(struct tegra_dc *dc) static void tegra_dc_hdmi_resume(struct tegra_dc *dc) { struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc); - bool hpd = tegra_dc_hdmi_hpd(dc); unsigned long flags; spin_lock_irqsave(&hdmi->suspend_lock, flags); hdmi->suspended = false; - queue_delayed_work(system_nrt_wq, &hdmi->work, - msecs_to_jiffies(hpd ? 100 : 30)); - spin_unlock_irqrestore(&hdmi->suspend_lock, flags); + tegra_nvhdcp_resume(hdmi->nvhdcp); + /* restore hotplug detection */ + tegra_hdmi_hotplug_enable(hdmi); + tegra_hdmi_hotplug_signal(hdmi); } #ifdef CONFIG_SWITCH -- cgit v1.2.3