Merge branch 'korg-android-tegra-3.1' into after-upstream-android
Dan Willemsen [Thu, 1 Dec 2011 05:51:56 +0000 (21:51 -0800)]
Conflicts:
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/board-ventana.c
drivers/misc/Kconfig
drivers/video/tegra/dc/hdmi.c

Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

21 files changed:
1  2 
arch/arm/Kconfig
arch/arm/include/asm/cacheflush.h
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-ventana.c
arch/arm/mach-tegra/tegra_i2s_audio.c
arch/arm/mach-tegra/tegra_spdif_audio.c
drivers/base/power/runtime.c
drivers/cpufreq/cpufreq_stats.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/mmc/host/sdhci.c
drivers/net/Makefile
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/usb/gadget/Makefile
drivers/usb/host/ehci.h
drivers/usb/otg/Makefile
drivers/video/tegra/dc/hdmi.c

Simple merge
Simple merge
@@@ -209,17 -115,17 +209,24 @@@ config TEGRA_PW
        help
          Enable support for the Tegra PWM controller(s).
  
+ config TEGRA_FIQ_DEBUGGER
+       bool "Enable the FIQ serial debugger on Tegra"
+       default y
+       select FIQ_DEBUGGER
+       help
+         Enables the FIQ serial debugger on Tegra"
 +config TEGRA_CARDHU_DSI
 +      bool "Support DSI panel on Cardhu"
 +      depends on MACH_CARDHU
 +      select TEGRA_DSI
 +      help
 +              Support for DSI Panel on Nvidia Cardhu
 +
  config TEGRA_EMC_SCALING_ENABLE
        bool "Enable scaling the memory frequency"
 -
 -endif
 +      depends on TEGRA_SILICON_PLATFORM
 +      default n
  
  config TEGRA_CPU_DVFS
        bool "Enable voltage scaling on Tegra CPU"
@@@ -21,85 -11,43 +21,86 @@@ obj-
  obj-y                                   += devices.o
  obj-y                                   += delay.o
  obj-y                                   += powergate.o
 -obj-$(CONFIG_PM_SLEEP)                        += pm.o
 -obj-$(CONFIG_PM_SLEEP)                        += pm-irq.o
 -obj-$(CONFIG_PM_SLEEP)                        += sleep.o
 -obj-y                                 += fuse.o
 +obj-y                                   += pm.o
 +obj-$(CONFIG_PM_SLEEP)                  += pm-irq.o
 +obj-y                                   += gic.o
 +obj-y                                   += sleep.o
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += sleep-t2.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += sleep-t3.o
 +obj-y                                   += fuse.o
  obj-y                                   += kfuse.o
 -obj-y                                 += tegra_i2s_audio.o
 -obj-y                                 += tegra_spdif_audio.o
 -obj-y                                 += mc.o
 +obj-y                                   += csi.o
 +obj-$(CONFIG_TEGRA_SILICON_PLATFORM)    += tegra_odm_fuses.o
 +obj-y                                   += i2c_error_recovery.o
 +obj-$(CONFIG_TEGRA_LEGACY_AUDIO)        += tegra_i2s_audio.o
 +obj-$(CONFIG_TEGRA_LEGACY_AUDIO)        += tegra_spdif_audio.o
 +obj-y                                   += mc.o
 +obj-$(CONFIG_TEGRA_STAT_MON)            += tegra2_statmon.o
  obj-$(CONFIG_USB_SUPPORT)               += usb_phy.o
  obj-$(CONFIG_FIQ)                       += fiq.o
+ obj-$(CONFIG_TEGRA_FIQ_DEBUGGER)        += tegra_fiq_debugger.o
  obj-$(CONFIG_TEGRA_PWM)                 += pwm.o
 -obj-$(CONFIG_TEGRA_ARB_SEMAPHORE)     += arb_sema.o
 +obj-$(CONFIG_TEGRA_ARB_SEMAPHORE)       += arb_sema.o
  
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clock.o
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += dvfs.o
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
 +ifeq ($(CONFIG_TEGRA_SILICON_PLATFORM),y)
 +obj-y                                   += dvfs.o
  obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_dvfs.o
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_fuse.o
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)               += tegra2_emc.o
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)               += wakeups-t2.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_dvfs.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += latency_allowance.o
 +obj-$(CONFIG_TEGRA_EDP_LIMITS)          += edp.o
 +endif
 +ifeq ($(CONFIG_TEGRA_SILICON_PLATFORM),y)
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_speedo.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_speedo.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_actmon.o
 +endif
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_emc.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_emc.o
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += wakeups-t2.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += wakeups-t3.o
  obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += pm-t2.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += pm-t3.o
  
 -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)               += pinmux-t2-tables.o
 -obj-$(CONFIG_LOCAL_TIMERS)            += localtimer.o
 -obj-$(CONFIG_SMP)                     += platsmp.o
 -obj-$(CONFIG_HOTPLUG_CPU)             += hotplug.o
 -obj-$(CONFIG_SMP)                     += headsmp.o
 -obj-$(CONFIG_TEGRA_SYSTEM_DMA)                += dma.o
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += pinmux-t2-tables.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += pinmux-t3-tables.o
 +obj-$(CONFIG_LOCAL_TIMERS)              += localtimer.o
 +obj-$(CONFIG_SMP)                       += platsmp.o
 +obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 +obj-y                                   += headsmp.o
 +obj-y                                   += reset.o
 +obj-$(CONFIG_TEGRA_SYSTEM_DMA)          += dma.o
  obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 -obj-$(CONFIG_TEGRA_PCI)                       += pcie.o
 -obj-$(CONFIG_USB_SUPPORT)             += usb_phy.o
 -obj-$(CONFIG_CPU_IDLE)                        += cpuidle.o
 +ifeq ($(CONFIG_TEGRA_AUTO_HOTPLUG),y)
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += cpu-tegra3.o
 +endif
 +obj-$(CONFIG_TEGRA_PCI)                 += pcie.o
 +obj-$(CONFIG_USB_SUPPORT)               += usb_phy.o
 +ifeq ($(CONFIG_CPU_IDLE),y)
 +obj-y                                   += cpuidle.o
 +ifeq ($(CONFIG_PM_SLEEP),y)
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += cpuidle-t2.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += cpuidle-t3.o
 +endif
 +endif
 +ifeq ($(CONFIG_TEGRA_THERMAL_THROTTLE),y)
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_throttle.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_throttle.o
 +endif
  obj-$(CONFIG_TEGRA_IOVMM)               += iovmm.o
  obj-$(CONFIG_TEGRA_IOVMM_GART)          += iovmm-gart.o
 +obj-$(CONFIG_TEGRA_IOVMM_SMMU)          += iovmm-smmu.o
 +obj-$(CONFIG_DEBUG_ICEDCC)              += sysfs-dcc.o
 +obj-$(CONFIG_TEGRA_CLUSTER_CONTROL)     += sysfs-cluster.o
 +ifeq ($(CONFIG_TEGRA_MC_PROFILE),y)
 +obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_mc.o
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_mc.o
 +endif
 +obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += tegra3_tsensor.o
 +obj-$(CONFIG_TEGRA_DYNAMIC_PWRDET)      += powerdetect.o
 +obj-$(CONFIG_TEGRA_USB_MODEM_POWER)     += tegra_usb_modem_power.o
  
  obj-${CONFIG_MACH_HARMONY}              += board-harmony.o
 +obj-${CONFIG_MACH_HARMONY}              += board-harmony-kbc.o
  obj-${CONFIG_MACH_HARMONY}              += board-harmony-panel.o
  obj-${CONFIG_MACH_HARMONY}              += board-harmony-pinmux.o
  obj-${CONFIG_MACH_HARMONY}              += board-harmony-pcie.o
  #include <linux/gpio.h>
  #include <linux/gpio_keys.h>
  #include <linux/input.h>
 +#include <linux/platform_data/tegra_usb.h>
+ #include <linux/usb/android_composite.h>
 +#include <linux/mfd/tps6586x.h>
 +#include <linux/memblock.h>
 +#include <linux/i2c/atmel_mxt_ts.h>
 +#include <linux/tegra_uart.h>
 +
 +#include <sound/wm8903.h>
  
  #include <mach/clk.h>
  #include <mach/iomap.h>
  #include "board-ventana.h"
  #include "devices.h"
  #include "gpio-names.h"
+ #include "fuse.h"
 +#include "wakeups-t2.h"
 +#include "pm.h"
 +
 +static struct tegra_utmip_config utmi_phy_config[] = {
 +      [0] = {
 +                      .hssync_start_delay = 9,
 +                      .idle_wait_delay = 17,
 +                      .elastic_limit = 16,
 +                      .term_range_adj = 6,
 +                      .xcvr_setup = 15,
 +                      .xcvr_setup_offset = 0,
 +                      .xcvr_use_fuses = 1,
 +                      .xcvr_lsfslew = 2,
 +                      .xcvr_lsrslew = 2,
 +      },
 +      [1] = {
 +                      .hssync_start_delay = 9,
 +                      .idle_wait_delay = 17,
 +                      .elastic_limit = 16,
 +                      .term_range_adj = 6,
 +                      .xcvr_setup = 8,
 +                      .xcvr_setup_offset = 0,
 +                      .xcvr_use_fuses = 1,
 +                      .xcvr_lsfslew = 2,
 +                      .xcvr_lsrslew = 2,
 +      },
 +};
  
 -static struct plat_serial8250_port debug_uart_platform_data[] = {
 -      {
 -              .membase        = IO_ADDRESS(TEGRA_UARTD_BASE),
 -              .mapbase        = TEGRA_UARTD_BASE,
 -              .irq            = INT_UARTD,
 -              .flags          = UPF_BOOT_AUTOCONF,
 -              .iotype         = UPIO_MEM,
 -              .regshift       = 2,
 -              .uartclk        = 216000000,
 -      }, {
 -              .flags          = 0,
 -      }
 +static struct tegra_ulpi_config ulpi_phy_config = {
 +      .reset_gpio = TEGRA_GPIO_PG2,
 +      .clk = "cdev2",
  };
  
 -static struct platform_device debug_uart = {
 -      .name = "serial8250",
 -      .id = PLAT8250_DEV_PLATFORM,
 -      .dev = {
 -              .platform_data = debug_uart_platform_data,
 +#ifdef CONFIG_BCM4329_RFKILL
 +
 +static struct resource ventana_bcm4329_rfkill_resources[] = {
 +      {
 +              .name   = "bcm4329_nshutdown_gpio",
 +              .start  = TEGRA_GPIO_PU0,
 +              .end    = TEGRA_GPIO_PU0,
 +              .flags  = IORESOURCE_IO,
        },
  };
  
@@@ -135,18 -82,43 +137,55 @@@ static __initdata struct tegra_clk_init
        { NULL,         NULL,           0,              0},
  };
  
+ static char *usb_functions[] = { "mtp" };
+ static char *usb_functions_adb[] = { "mtp", "adb" };
+ static struct android_usb_product usb_products[] = {
+       {
+               .product_id     = 0x7102,
+               .num_functions  = ARRAY_SIZE(usb_functions),
+               .functions      = usb_functions,
+       },
+       {
+               .product_id     = 0x7100,
+               .num_functions  = ARRAY_SIZE(usb_functions_adb),
+               .functions      = usb_functions_adb,
+       },
+ };
+ /* standard android USB platform data */
+ static struct android_usb_platform_data andusb_plat = {
+       .vendor_id              = 0x0955,
+       .product_id             = 0x7100,
+       .manufacturer_name      = "NVIDIA",
+       .product_name           = "Ventana",
+       .serial_number          = NULL,
+       .num_products = ARRAY_SIZE(usb_products),
+       .products = usb_products,
+       .num_functions = ARRAY_SIZE(usb_functions_adb),
+       .functions = usb_functions_adb,
+ };
+ static struct platform_device androidusb_device = {
+       .name   = "android_usb",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &andusb_plat,
+       },
+ };
 +static struct tegra_ulpi_config ventana_ehci2_ulpi_phy_config = {
 +      .reset_gpio = TEGRA_GPIO_PV1,
 +      .clk = "cdev2",
 +};
 +
 +static struct tegra_ehci_platform_data ventana_ehci2_ulpi_platform_data = {
 +      .operating_mode = TEGRA_USB_HOST,
 +      .power_down_on_bus_suspend = 1,
 +      .phy_config = &ventana_ehci2_ulpi_phy_config,
 +      .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI,
 +};
 +
  static struct tegra_i2c_platform_data ventana_i2c1_platform_data = {
        .adapter_nr     = 0,
        .bus_count      = 1,
@@@ -455,147 -243,24 +494,150 @@@ static int __init ventana_touch_init_pa
        return 0;
  }
  
 +static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
 +      [0] = {
 +                      .instance = 0,
 +                      .vbus_irq = TPS6586X_INT_BASE + TPS6586X_INT_USB_DET,
 +                      .vbus_gpio = TEGRA_GPIO_PD0,
 +      },
 +      [1] = {
 +                      .instance = 1,
 +                      .vbus_gpio = -1,
 +      },
 +      [2] = {
 +                      .instance = 2,
 +                      .vbus_gpio = TEGRA_GPIO_PD3,
 +      },
 +};
 +
 +static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
 +      [0] = {
 +                      .phy_config = &utmi_phy_config[0],
 +                      .operating_mode = TEGRA_USB_HOST,
 +                      .power_down_on_bus_suspend = 1,
 +      },
 +      [1] = {
 +                      .phy_config = &ulpi_phy_config,
 +                      .operating_mode = TEGRA_USB_HOST,
 +                      .power_down_on_bus_suspend = 1,
 +                      .phy_type = TEGRA_USB_PHY_TYPE_LINK_ULPI,
 +      },
 +      [2] = {
 +                      .phy_config = &utmi_phy_config[1],
 +                      .operating_mode = TEGRA_USB_HOST,
 +                      .power_down_on_bus_suspend = 1,
 +                      .hotplug = 1,
 +      },
 +};
 +
 +static struct tegra_otg_platform_data tegra_otg_pdata = {
 +      .ehci_device = &tegra_ehci1_device,
 +      .ehci_pdata = &tegra_ehci_pdata[0],
 +};
 +
 +static int __init ventana_gps_init(void)
 +{
 +      struct clk *clk32 = clk_get_sys(NULL, "blink");
 +      if (!IS_ERR(clk32)) {
 +              clk_set_rate(clk32,clk32->parent->rate);
 +              clk_enable(clk32);
 +      }
 +
 +      tegra_gpio_enable(TEGRA_GPIO_PZ3);
 +      return 0;
 +}
 +
 +static void ventana_power_off(void)
 +{
 +      int ret;
 +
 +      ret = tps6586x_power_off();
 +      if (ret)
 +              pr_err("ventana: failed to power off\n");
 +
 +      while(1);
 +}
 +
 +static void __init ventana_power_off_init(void)
 +{
 +      pm_power_off = ventana_power_off;
 +}
 +
 +static void ventana_usb_init(void)
 +{
 +      tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
 +      /* OTG should be the first to be registered */
 +      tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
 +      platform_device_register(&tegra_otg_device);
 +
 +      platform_device_register(&tegra_udc_device);
 +      platform_device_register(&tegra_ehci2_device);
 +
 +      tegra_ehci3_device.dev.platform_data=&tegra_ehci_pdata[2];
 +      platform_device_register(&tegra_ehci3_device);
 +}
 +
  static void __init tegra_ventana_init(void)
  {
 -      char serial[20];
 +      struct board_info BoardInfo;
  
 -      tegra_common_init();
        tegra_clk_init_from_table(ventana_clk_init_table);
        ventana_pinmux_init();
 -
 +      ventana_i2c_init();
 +      ventana_uart_init();
+       snprintf(serial, sizeof(serial), "%llx", tegra_chip_uid());
+       andusb_plat.serial_number = kstrdup(serial, GFP_KERNEL);
 +      tegra_ehci2_device.dev.platform_data
 +              = &ventana_ehci2_ulpi_platform_data;
        platform_add_devices(ventana_devices, ARRAY_SIZE(ventana_devices));
        ventana_sdhci_init();
 -      ventana_i2c_init();
 +      ventana_charge_init();
        ventana_regulator_init();
 -      ventana_touch_init();
 +      ventana_charger_init();
 +
 +      tegra_get_board_info(&BoardInfo);
 +
 +      /* boards with sku > 0 have atmel touch panels */
 +      if (BoardInfo.sku) {
 +              pr_info("Initializing Atmel touch driver\n");
 +              ventana_touch_init_atmel();
 +      } else {
 +              pr_info("Initializing Panjit touch driver\n");
 +              ventana_touch_init_panjit();
 +      }
 +
 +#ifdef CONFIG_KEYBOARD_GPIO
        ventana_keys_init();
 +#endif
 +
 +      ventana_usb_init();
 +      ventana_gps_init();
        ventana_panel_init();
 +      ventana_sensors_init();
 +      ventana_bt_rfkill();
 +      ventana_power_off_init();
 +      ventana_emc_init();
 +
 +      tegra_release_bootloader_fb();
 +}
 +
 +int __init tegra_ventana_protected_aperture_init(void)
 +{
 +      if (!machine_is_ventana())
 +              return 0;
 +
 +      tegra_protected_aperture_init(tegra_grhost_aperture);
 +      return 0;
 +}
 +late_initcall(tegra_ventana_protected_aperture_init);
 +
 +void __init tegra_ventana_reserve(void)
 +{
 +      if (memblock_reserve(0x0, 4096) < 0)
 +              pr_warn("Cannot reserve first 4K of memory for safety\n");
 +
 +      tegra_reserve(SZ_256M, SZ_8M, SZ_16M);
  }
  
  MACHINE_START(VENTANA, "ventana")
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -508,25 -524,29 +524,48 @@@ config USB_SWITCH_FSA948
          stereo and mono audio, video, microphone and UART data to use
          a common connector port.
  
+ config WL127X_RFKILL
+       tristate "Bluetooth power control driver for TI wl127x"
+       depends on RFKILL
+       default n
+       ---help---
+        Creates an rfkill entry in sysfs for power control of Bluetooth
+        TI wl127x chips.
+ config APANIC
+       bool "Android kernel panic diagnostics driver"
+       default n
+       ---help---
+        Driver which handles kernel panics and attempts to write
+        critical debugging data to flash.
+ config APANIC_PLABEL
+       string "Android panic dump flash partition label"
+       depends on APANIC
+       default "kpanic"
+       ---help---
+        If your platform uses a different flash partition label for storing
+        crashdumps, enter it here.
 +config BCM4329_RFKILL
 +      bool "Enable BCM4329 RFKILL driver"
 +      default n
 +      ---help---
 +      Adds BCM4329 RFKILL driver for Broadcom BCM4329 chipset
 +
 +config TEGRA_CRYPTO_DEV
 +      bool "Device node to access tegra aes hardware"
 +      ---help---
 +      Dev node /dev/tegra-crypto in order to get access to tegra aes
 +      hardware from user space
 +
 +config MAX1749_VIBRATOR
 +      bool "MAX1749 vibrator device driver"
 +      depends on ANDROID_TIMED_OUTPUT
 +      default n
 +      ---help---
 +      Adds a timed output vibrator device node for MAX1749 vibrator motor
 +
  source "drivers/misc/c2port/Kconfig"
  source "drivers/misc/eeprom/Kconfig"
  source "drivers/misc/cb710/Kconfig"
@@@ -48,8 -49,7 +50,11 @@@ obj-$(CONFIG_AB8500_PWM)     += ab8500-pwm.
  obj-y                         += lis3lv02d/
  obj-y                         += carma/
  obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+ obj-$(CONFIG_WL127X_RFKILL)   += wl127x-rfkill.o
+ obj-$(CONFIG_APANIC)          += apanic.o
+ obj-$(CONFIG_SENSORS_AK8975)  += akm8975.o
  obj-$(CONFIG_SENSORS_NCT1008) += nct1008.o
 +obj-$(CONFIG_BCM4329_RFKILL)  += bcm4329_rfkill.o
 +obj-$(CONFIG_MPU_SENSORS_MPU3050)     += mpu3050/
 +obj-$(CONFIG_TEGRA_CRYPTO_DEV)        += tegra-cryptodev.o
 +obj-$(CONFIG_MAX1749_VIBRATOR)        += max1749.o
@@@ -1047,11 -1047,14 +1047,11 @@@ static void sdhci_set_clock(struct sdhc
        u16 clk = 0;
        unsigned long timeout;
  
-       if (clock == host->clock)
+       if (clock && clock == host->clock)
                return;
  
 -      if (host->ops->set_clock) {
 -              host->ops->set_clock(host, clock);
 -              if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
 -                      return;
 -      }
 +      if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
 +              return;
  
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  #include <linux/kernel.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
+ #include <linux/switch.h>
  #include <linux/workqueue.h>
 +#include <linux/debugfs.h>
 +#include <linux/seq_file.h>
  
  #include <mach/clk.h>
  #include <mach/dc.h>
@@@ -76,16 -58,12 +77,18 @@@ struct tegra_dc_hdmi_data 
  
        struct clk                      *disp1_clk;
        struct clk                      *disp2_clk;
 +      struct clk                      *hda_clk;
 +      struct clk                      *hda2codec_clk;
 +      struct clk                      *hda2hdmi_clk;
  
+       struct switch_dev               hpd_switch;
        spinlock_t                      suspend_lock;
        bool                            suspended;
 -      bool                            hpd_pending;
 +      bool                            eld_retrieved;
 +      bool                            clk_enabled;
 +      unsigned                        audio_freq;
 +      unsigned                        audio_source;
  
        bool                            dvi;
  };
@@@ -737,63 -441,6 +740,64 @@@ static bool tegra_dc_hdmi_hpd(struct te
                (sense == TEGRA_DC_OUT_HOTPLUG_LOW && !level);
  }
  
 +
 +void tegra_dc_hdmi_detect_config(struct tegra_dc *dc,
 +                                              struct fb_monspecs *specs)
 +{
 +      struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
 +
 +      /* monitors like to lie about these but they are still useful for
 +       * detecting aspect ratios
 +       */
 +      dc->out->h_size = specs->max_x * 1000;
 +      dc->out->v_size = specs->max_y * 1000;
 +
 +      hdmi->dvi = !(specs->misc & FB_MISC_HDMI);
 +
 +      tegra_fb_update_monspecs(dc->fb, specs, tegra_dc_hdmi_mode_filter);
++      switch_set_state(&hdmi->hpd_switch, 1);
 +      dev_info(&dc->ndev->dev, "display detected\n");
 +
 +      dc->connected = true;
 +      tegra_dc_ext_process_hotplug(dc->ndev->id);
 +}
 +
 +/* This function is used to enable DC1 and HDMI for the purpose of testing. */
 +bool tegra_dc_hdmi_detect_test(struct tegra_dc *dc, unsigned char *edid_ptr)
 +{
 +      int err;
 +      struct fb_monspecs specs;
 +      struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
 +
 +      if (!dc || !hdmi || !edid_ptr) {
 +              dev_err(&dc->ndev->dev, "HDMI test failed to get arguments.\n");
 +              return false;
 +      }
 +
 +      err = tegra_edid_get_monspecs_test(hdmi->edid, &specs, edid_ptr);
 +      if (err < 0) {
 +              dev_err(&dc->ndev->dev, "error reading edid\n");
 +              goto fail;
 +      }
 +
 +      err = tegra_edid_get_eld(hdmi->edid, &hdmi->eld);
 +      if (err < 0) {
 +              dev_err(&dc->ndev->dev, "error populating eld\n");
 +              goto fail;
 +      }
 +      hdmi->eld_retrieved = true;
 +
 +      tegra_dc_hdmi_detect_config(dc, &specs);
 +
 +      return true;
 +
 +fail:
 +      hdmi->eld_retrieved = false;
 +      tegra_nvhdcp_set_plug(hdmi->nvhdcp, 0);
 +      return false;
 +}
 +EXPORT_SYMBOL(tegra_dc_hdmi_detect_test);
 +
  static bool tegra_dc_hdmi_detect(struct tegra_dc *dc)
  {
        struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
        return true;
  
  fail:
 +      hdmi->eld_retrieved = false;
+       switch_set_state(&hdmi->hpd_switch, 0);
        tegra_nvhdcp_set_plug(hdmi->nvhdcp, 0);
        return false;
  }
@@@ -1009,12 -634,12 +1014,15 @@@ static int tegra_dc_hdmi_init(struct te
        hdmi->disp1_clk = disp1_clk;
        hdmi->disp2_clk = disp2_clk;
        hdmi->suspended = false;
 -      hdmi->hpd_pending = false;
 +      hdmi->eld_retrieved= false;
 +      hdmi->clk_enabled = false;
 +      hdmi->audio_freq = 44100;
 +      hdmi->audio_source = AUTO;
        spin_lock_init(&hdmi->suspend_lock);
  
+       hdmi->hpd_switch.name = "hdmi";
+       switch_dev_register(&hdmi->hpd_switch);
        dc->out->depth = 24;
  
        tegra_dc_set_outdata(dc, hdmi);
@@@ -1065,15 -679,12 +1073,16 @@@ static void tegra_dc_hdmi_destroy(struc
  {
        struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
  
 -      disable_irq_wake(gpio_to_irq(dc->out->hotplug_gpio));
        free_irq(gpio_to_irq(dc->out->hotplug_gpio), dc);
        cancel_delayed_work_sync(&hdmi->work);
+       switch_dev_unregister(&hdmi->hpd_switch);
        iounmap(hdmi->base);
        release_resource(hdmi->base_res);
 +#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
 +      clk_put(hdmi->hda2hdmi_clk);
 +      clk_put(hdmi->hda2codec_clk);
 +      clk_put(hdmi->hda_clk);
 +#endif
        clk_put(hdmi->clk);
        clk_put(hdmi->disp1_clk);
        clk_put(hdmi->disp2_clk);