summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pm-t3.c
diff options
context:
space:
mode:
authorWen Yi <wyi@nvidia.com>2012-06-20 21:42:13 -0700
committerSimone Willett <swillett@nvidia.com>2012-07-16 17:20:28 -0700
commit5e07056dc8b922b8b43a01b60a949c1dda75d9a9 (patch)
treebd8a99dc9e78be49ec0613779535f4dfdd2c466e /arch/arm/mach-tegra/pm-t3.c
parent5a34d0584c5a45547c6733e177a0aa0c93dc1884 (diff)
arm: tegra: sd: enable sd dpd
This is a WAR solution that allows for the turning on SD DPD feature. The original issue is that enabling SD DPD immediately after device comes out of LP0 causes ULPI disconnect. The root cause of that is not known. The WAR is to delay the enabling of SD DPD for 100ms after device comes out of LP0. Bug 929628 Change-Id: I3c5e35ace422e5441535c2c0fe18545b53bbddc4 Signed-off-by: Wen Yi <wyi@nvidia.com> (cherry picked from commit bffb7b917d52a3523af80db21322ec7ba5fd33f9) Reviewed-on: http://git-master/r/113392 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/pm-t3.c')
-rw-r--r--arch/arm/mach-tegra/pm-t3.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c
index 89041c41c389..32a260e2dd43 100644
--- a/arch/arm/mach-tegra/pm-t3.c
+++ b/arch/arm/mach-tegra/pm-t3.c
@@ -31,6 +31,7 @@
#include <mach/gpio.h>
#include <mach/iomap.h>
#include <mach/irqs.h>
+#include <mach/io_dpd.h>
#include <asm/cpu_pm.h>
#include <asm/hardware/gic.h>
@@ -456,6 +457,7 @@ struct tegra_io_dpd tegra_list_io_dpd[] = {
IO_DPD_INFO("sdhci-tegra.3", 1, 3), /* SDMMC4 */
};
+#ifdef CONFIG_PM_SLEEP
struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
{
int i;
@@ -473,7 +475,6 @@ struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
((name) ? name : "NULL"));
return NULL;
}
-EXPORT_SYMBOL(tegra_io_dpd_get);
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
static DEFINE_SPINLOCK(tegra_io_dpd_lock);
@@ -507,7 +508,6 @@ void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
spin_unlock(&tegra_io_dpd_lock);
return;
}
-EXPORT_SYMBOL(tegra_io_dpd_enable);
void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
{
@@ -533,4 +533,52 @@ void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
spin_unlock(&tegra_io_dpd_lock);
return;
}
+
+static void tegra_io_dpd_delayed_disable(struct work_struct *work)
+{
+ struct tegra_io_dpd *hnd = container_of(
+ to_delayed_work(work), struct tegra_io_dpd, delay_dpd);
+ tegra_io_dpd_disable(hnd);
+ hnd->need_delay_dpd = 0;
+}
+
+int tegra_io_dpd_init(void)
+{
+ int i;
+ for (i = 0;
+ i < (sizeof(tegra_list_io_dpd) / sizeof(struct tegra_io_dpd));
+ i++) {
+ INIT_DELAYED_WORK(&(tegra_list_io_dpd[i].delay_dpd),
+ tegra_io_dpd_delayed_disable);
+ mutex_init(&(tegra_list_io_dpd[i].delay_lock));
+ tegra_list_io_dpd[i].need_delay_dpd = 0;
+ }
+ return 0;
+}
+
+#else
+
+int tegra_io_dpd_init(void)
+{
+ return 0;
+}
+
+void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
+{
+}
+
+void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
+{
+}
+
+struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
+{
+ return NULL;
+}
+
+#endif
+
+EXPORT_SYMBOL(tegra_io_dpd_get);
+EXPORT_SYMBOL(tegra_io_dpd_enable);
EXPORT_SYMBOL(tegra_io_dpd_disable);
+EXPORT_SYMBOL(tegra_io_dpd_init);