--- /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
+@@ -51,6 +51,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 */
+
+ static const int sdp4430_keymap[] = {
+ KEY(0, 0, KEY_E),
+@@ -589,6 +590,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)
+@@ -634,6 +636,7 @@ void omap_4430sdp_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);
+ }
+
+ #ifdef CONFIG_OMAP_MUX
+--- a/arch/arm/mach-omap2/board-omap4panda.c
++++ b/arch/arm/mach-omap2/board-omap4panda.c
+@@ -54,6 +54,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};
+@@ -625,6 +626,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)
+@@ -677,6 +679,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 | 71 +++++++++++++++++++++++++++++++--
+ include/video/omapdss.h | 5 ++
+ 4 files changed, 82 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/mach-omap2/board-4430sdp.c
++++ b/arch/arm/mach-omap2/board-4430sdp.c
+@@ -610,6 +610,10 @@ static void sdp4430_panel_disable_hdmi(s
+ gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
+ }
+
++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",
+@@ -617,6 +621,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 omap_dss_device *sdp4430_dss_devices[] = {
+--- a/arch/arm/mach-omap2/board-omap4panda.c
++++ b/arch/arm/mach-omap2/board-omap4panda.c
+@@ -646,6 +646,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",
+@@ -653,6 +657,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
+@@ -29,6 +29,7 @@
+ #include <linux/mutex.h>
+ #include <linux/delay.h>
+ #include <linux/string.h>
++#include <linux/gpio.h>
+ #include <video/omapdss.h>
+ #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+@@ -54,6 +55,9 @@ static struct {
+ u8 edid_set;
+ bool custom_set;
+ struct hdmi_config cfg;
++
++ int hpd_gpio;
++ bool phy_tx_enabled;
+ } hdmi;
+
+ /*
+@@ -278,6 +282,47 @@ static int hdmi_pll_reset(void)
+ return 0;
+ }
+
++static int hdmi_check_hpd_state(void)
++{
++ 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(hdmi.hpd_gpio);
++
++ if (hpd == hdmi.phy_tx_enabled) {
++ spin_unlock_irqrestore(&phy_tx_lock, flags);
++ return 0;
++ }
++
++ if (hpd)
++ r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
++ else
++ r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
++
++ if (r) {
++ DSSERR("Failed to %s PHY TX power\n",
++ hpd ? "enable" : "disable");
++ goto err;
++ }
++
++ hdmi.phy_tx_enabled = hpd;
++err:
++ spin_unlock_irqrestore(&phy_tx_lock, flags);
++ return r;
++}
++
++static irqreturn_t hpd_irq_handler(int irq, void *data)
++{
++ hdmi_check_hpd_state();
++
++ return IRQ_HANDLED;
++}
++
+ static int hdmi_phy_init(void)
+ {
+ u16 r = 0;
+@@ -286,10 +331,6 @@ static int hdmi_phy_init(void)
+ if (r)
+ return r;
+
+- r = hdmi_set_phy_pwr(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
+@@ -311,6 +352,23 @@ static int hdmi_phy_init(void)
+ /* Write to phy address 3 to change the polarity control */
+ REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+
++ r = request_threaded_irq(gpio_to_irq(hdmi.hpd_gpio),
++ NULL, hpd_irq_handler,
++ IRQF_DISABLED | IRQF_TRIGGER_RISING |
++ IRQF_TRIGGER_FALLING, "hpd", NULL);
++ if (r) {
++ DSSERR("HPD IRQ request failed\n");
++ hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
++ return r;
++ }
++
++ r = hdmi_check_hpd_state();
++ if (r) {
++ free_irq(gpio_to_irq(hdmi.hpd_gpio), NULL);
++ hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
++ return r;
++ }
++
+ return 0;
+ }
+
+@@ -361,7 +419,9 @@ static int hdmi_pll_program(struct hdmi_
+
+ static void hdmi_phy_off(void)
+ {
++ free_irq(gpio_to_irq(hdmi.hpd_gpio), NULL);
+ hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
++ hdmi.phy_tx_enabled = false;
+ }
+
+ static int hdmi_core_ddc_edid(u8 *pedid, int ext)
+@@ -1236,12 +1296,15 @@ void omapdss_hdmi_display_set_timing(str
+
+ 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");
+
+ mutex_lock(&hdmi.lock);
+
++ hdmi.hpd_gpio = priv->hpd_gpio;
++
+ r = omap_dss_start_device(dssdev);
+ if (r) {
+ DSSERR("failed to start device\n");
+--- a/include/video/omapdss.h
++++ b/include/video/omapdss.h
+@@ -514,6 +514,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;
+