--- /dev/null
+From aa74274b464d4aa24703963ac89a0ee942d5d267 Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Date: Tue, 17 Jan 2012 11:05:32 +0200
+Subject: OMAP: 4430SDP/Panda: add HDMI HPD gpio
+
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+commit aa74274b464d4aa24703963ac89a0ee942d5d267 upstream.
+
+Both Panda and 4430SDP use GPIO 63 as HDMI hot-plug-detect. Configure
+this GPIO in the board files.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/board-4430sdp.c | 3 +++
+ arch/arm/mach-omap2/board-omap4panda.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+--- a/arch/arm/mach-omap2/board-4430sdp.c
++++ b/arch/arm/mach-omap2/board-4430sdp.c
+@@ -54,6 +54,7 @@
+ #define OMAP4_SFH7741_ENABLE_GPIO 188
+ #define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
++#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+ #define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
+ #define DLP_POWER_ON_GPIO 40
+
+@@ -608,6 +609,7 @@ static void sdp4430_hdmi_mux_init(void)
+ static struct gpio sdp4430_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
++ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+ };
+
+ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
+@@ -827,6 +829,7 @@ static void omap_4430sdp_display_init(vo
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
++ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+ }
+
+ #ifdef CONFIG_OMAP_MUX
+--- a/arch/arm/mach-omap2/board-omap4panda.c
++++ b/arch/arm/mach-omap2/board-omap4panda.c
+@@ -53,6 +53,7 @@
+ #define GPIO_WIFI_IRQ 53
+ #define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
++#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+
+ /* wl127x BT, FM, GPS connectivity chip */
+ static int wl1271_gpios[] = {46, -1, -1};
+@@ -492,6 +493,7 @@ static void omap4_panda_hdmi_mux_init(vo
+ static struct gpio panda_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
++ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+ };
+
+ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
+@@ -544,6 +546,7 @@ void omap4_panda_display_init(void)
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
++ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+ }
+
+ static void __init omap4_panda_init(void)
--- /dev/null
+From c49d005b6cc8491fad5b24f82805be2d6bcbd3dd Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Date: Tue, 17 Jan 2012 11:09:57 +0200
+Subject: OMAPDSS: HDMI: PHY burnout fix
+
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+commit c49d005b6cc8491fad5b24f82805be2d6bcbd3dd upstream.
+
+A hardware bug in the OMAP4 HDMI PHY causes physical damage to the board
+if the HDMI PHY is kept powered on when the cable is not connected.
+
+This patch solves the problem by adding hot-plug-detection into the HDMI
+IP driver. This is not a real HPD support in the sense that nobody else
+than the IP driver gets to know about the HPD events, but is only meant
+to fix the HW bug.
+
+The strategy is simple: If the display device is turned off by the user,
+the PHY power is set to OFF. When the display device is turned on by the
+user, the PHY power is set either to LDOON or TXON, depending on whether
+the HDMI cable is connected.
+
+The reason to avoid PHY OFF when the display device is on, but the cable
+is disconnected, is that when the PHY is turned OFF, the HDMI IP is not
+"ticking" and thus the DISPC does not receive pixel clock from the HDMI
+IP. This would, for example, prevent any VSYNCs from happening, and
+would thus affect the users of omapdss. By using LDOON when the cable is
+disconnected we'll avoid the HW bug, but keep the HDMI working as usual
+from the user's point of view.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/board-4430sdp.c | 5 ++
+ arch/arm/mach-omap2/board-omap4panda.c | 5 ++
+ drivers/video/omap2/dss/hdmi.c | 3 +
+ drivers/video/omap2/dss/ti_hdmi.h | 4 +
+ drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 68 ++++++++++++++++++++++++++++--
+ include/video/omapdss.h | 5 ++
+ 6 files changed, 86 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/mach-omap2/board-4430sdp.c
++++ b/arch/arm/mach-omap2/board-4430sdp.c
+@@ -742,6 +742,10 @@ static void sdp4430_lcd_init(void)
+ pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
+ }
+
++static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
++ .hpd_gpio = HDMI_GPIO_HPD,
++};
++
+ static struct omap_dss_device sdp4430_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+@@ -749,6 +753,7 @@ static struct omap_dss_device sdp4430_hd
+ .platform_enable = sdp4430_panel_enable_hdmi,
+ .platform_disable = sdp4430_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
++ .data = &sdp4430_hdmi_data,
+ };
+
+ static struct picodlp_panel_data sdp4430_picodlp_pdata = {
+--- a/arch/arm/mach-omap2/board-omap4panda.c
++++ b/arch/arm/mach-omap2/board-omap4panda.c
+@@ -513,6 +513,10 @@ static void omap4_panda_panel_disable_hd
+ gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
+ }
+
++static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
++ .hpd_gpio = HDMI_GPIO_HPD,
++};
++
+ static struct omap_dss_device omap4_panda_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+@@ -520,6 +524,7 @@ static struct omap_dss_device omap4_pan
+ .platform_enable = omap4_panda_panel_enable_hdmi,
+ .platform_disable = omap4_panda_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
++ .data = &omap4_panda_hdmi_data,
+ };
+
+ static struct omap_dss_device *omap4_panda_dss_devices[] = {
+--- a/drivers/video/omap2/dss/hdmi.c
++++ b/drivers/video/omap2/dss/hdmi.c
+@@ -490,6 +490,7 @@ bool omapdss_hdmi_detect(void)
+
+ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
+ {
++ struct omap_dss_hdmi_data *priv = dssdev->data;
+ int r = 0;
+
+ DSSDBG("ENTER hdmi_display_enable\n");
+@@ -502,6 +503,8 @@ int omapdss_hdmi_display_enable(struct o
+ goto err0;
+ }
+
++ hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
++
+ r = omap_dss_start_device(dssdev);
+ if (r) {
+ DSSERR("failed to start device\n");
+--- a/drivers/video/omap2/dss/ti_hdmi.h
++++ b/drivers/video/omap2/dss/ti_hdmi.h
+@@ -121,6 +121,10 @@ struct hdmi_ip_data {
+ const struct ti_hdmi_ip_ops *ops;
+ struct hdmi_config cfg;
+ struct hdmi_pll_info pll_data;
++
++ /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
++ int hpd_gpio;
++ bool phy_tx_enabled;
+ };
+ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
+ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
+--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
++++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+@@ -28,6 +28,7 @@
+ #include <linux/delay.h>
+ #include <linux/string.h>
+ #include <linux/seq_file.h>
++#include <linux/gpio.h>
+
+ #include "ti_hdmi_4xxx_ip.h"
+ #include "dss.h"
+@@ -223,6 +224,49 @@ void ti_hdmi_4xxx_pll_disable(struct hdm
+ hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
+ }
+
++static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
++{
++ unsigned long flags;
++ bool hpd;
++ int r;
++ /* this should be in ti_hdmi_4xxx_ip private data */
++ static DEFINE_SPINLOCK(phy_tx_lock);
++
++ spin_lock_irqsave(&phy_tx_lock, flags);
++
++ hpd = gpio_get_value(ip_data->hpd_gpio);
++
++ if (hpd == ip_data->phy_tx_enabled) {
++ spin_unlock_irqrestore(&phy_tx_lock, flags);
++ return 0;
++ }
++
++ if (hpd)
++ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
++ else
++ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
++
++ if (r) {
++ DSSERR("Failed to %s PHY TX power\n",
++ hpd ? "enable" : "disable");
++ goto err;
++ }
++
++ ip_data->phy_tx_enabled = hpd;
++err:
++ spin_unlock_irqrestore(&phy_tx_lock, flags);
++ return r;
++}
++
++static irqreturn_t hpd_irq_handler(int irq, void *data)
++{
++ struct hdmi_ip_data *ip_data = data;
++
++ hdmi_check_hpd_state(ip_data);
++
++ return IRQ_HANDLED;
++}
++
+ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
+ {
+ u16 r = 0;
+@@ -232,10 +276,6 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_
+ if (r)
+ return r;
+
+- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
+- if (r)
+- return r;
+-
+ /*
+ * Read address 0 in order to get the SCP reset done completed
+ * Dummy access performed to make sure reset is done
+@@ -257,12 +297,32 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_
+ /* Write to phy address 3 to change the polarity control */
+ REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+
++ r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio),
++ NULL, hpd_irq_handler,
++ IRQF_DISABLED | IRQF_TRIGGER_RISING |
++ IRQF_TRIGGER_FALLING, "hpd", ip_data);
++ if (r) {
++ DSSERR("HPD IRQ request failed\n");
++ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
++ return r;
++ }
++
++ r = hdmi_check_hpd_state(ip_data);
++ if (r) {
++ free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
++ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
++ return r;
++ }
++
+ return 0;
+ }
+
+ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
+ {
++ free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
++
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
++ ip_data->phy_tx_enabled = false;
+ }
+
+ static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
+--- a/include/video/omapdss.h
++++ b/include/video/omapdss.h
+@@ -575,6 +575,11 @@ struct omap_dss_device {
+ int (*get_backlight)(struct omap_dss_device *dssdev);
+ };
+
++struct omap_dss_hdmi_data
++{
++ int hpd_gpio;
++};
++
+ struct omap_dss_driver {
+ struct device_driver driver;
+