video: tegra: dc: hdmi: calling tegra_hotplug_signal to queue deferred work
authorsharath sarangpur <ssarangpur@nvidia.com>
Tue, 25 Jun 2013 02:15:26 +0000 (19:15 -0700)
committerHarshada Kale <hkale@nvidia.com>
Tue, 9 Jul 2013 07:14:45 +0000 (00:14 -0700)
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 <ssarangpur@nvidia.com>
Reviewed-on: http://git-master/r/241633
GVS: Gerrit_Virtual_Submit
Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-by: Anshul Jain (SW) <anshulj@nvidia.com>
Reviewed-on: http://git-master/r/243635
Reviewed-by: Matt Wagner <mwagner@nvidia.com>
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/hdmi.c

index e7847b8b5da650ba94874ae5dcda29bedf3042ca..5805355c847c1e41537bcdc72103256ddb648852 100644 (file)
@@ -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;
 
index 253a13ad24db07ef78f4f5de8db961a10e5a746b..5ad5d1fcbdf9d408b67b70ce9a8c975e7dc502e0 100644 (file)
@@ -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