summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorTom Cherry <tcherry@nvidia.com>2012-06-05 11:41:56 -0700
committerTom Cherry <tcherry@nvidia.com>2012-06-05 11:41:56 -0700
commitb46bcc0a3da47431f2711c3d63e9507cfab18ecd (patch)
tree6b9355395470108f5161840638bf48af0e10f3c1 /arch/arm/mach-tegra
parent63fb092060747250a0dd305bd11018caebe23d65 (diff)
parentf61bdbde09605793cfa05f7c59545c62b5e08aa6 (diff)
Merge commit 'main-ics-2012.06.04-A5' into HEAD
Conflicts: drivers/media/video/tegra/nvavp/nvavp_dev.c Change-Id: I7779b0ce58004f80cccf6193148ac49551ce5da5
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Kconfig10
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.c118
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.h3
-rw-r--r--arch/arm/mach-tegra/board-aruba-power.c1
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c4
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c4
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c4
-rw-r--r--arch/arm/mach-tegra/board-cardhu-sdhci.c1
-rw-r--r--arch/arm/mach-tegra/board-enterprise-baseband.c62
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c4
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c3
-rw-r--r--arch/arm/mach-tegra/board-kai-kbc.c7
-rw-r--r--arch/arm/mach-tegra/board-kai-panel.c13
-rw-r--r--arch/arm/mach-tegra/board-kai-pinmux.c5
-rw-r--r--arch/arm/mach-tegra/board-kai-power.c3
-rw-r--r--arch/arm/mach-tegra/board-kai-sdhci.c4
-rw-r--r--arch/arm/mach-tegra/board-kai-sensors.c7
-rw-r--r--arch/arm/mach-tegra/board-kai.c16
-rw-r--r--arch/arm/mach-tegra/board-p1852-pinmux.c53
-rw-r--r--arch/arm/mach-tegra/board-p1852.c36
-rw-r--r--arch/arm/mach-tegra/board-ventana-panel.c8
-rw-r--r--arch/arm/mach-tegra/board-ventana-power.c13
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c13
-rw-r--r--arch/arm/mach-tegra/board-ventana-sensors.c41
-rw-r--r--arch/arm/mach-tegra/board-ventana.c19
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.c60
-rw-r--r--arch/arm/mach-tegra/board-whistler-power.c1
-rw-r--r--arch/arm/mach-tegra/board-whistler-sdhci.c1
-rw-r--r--arch/arm/mach-tegra/board-whistler.c2
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c9
-rw-r--r--arch/arm/mach-tegra/devices.c5
-rw-r--r--arch/arm/mach-tegra/devices.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/sdhci.h8
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h1
-rw-r--r--arch/arm/mach-tegra/p852/board-p852.h1
-rw-r--r--arch/arm/mach-tegra/pcie.c58
-rw-r--r--arch/arm/mach-tegra/pinmux-t3-tables.c29
-rw-r--r--arch/arm/mach-tegra/pm-irq.c1
-rw-r--r--arch/arm/mach-tegra/pm-irq.h2
-rw-r--r--arch/arm/mach-tegra/tegra2_usb_phy.c192
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c4
-rw-r--r--arch/arm/mach-tegra/tegra3_usb_phy.c141
-rw-r--r--arch/arm/mach-tegra/tegra_usb_phy.h1
-rw-r--r--arch/arm/mach-tegra/usb_phy.c68
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.c57
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.h62
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.c57
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.h76
-rw-r--r--arch/arm/mach-tegra/wakeups.c85
-rw-r--r--arch/arm/mach-tegra/wakeups.h29
52 files changed, 959 insertions, 446 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 82306bc4aff5..c11ea97941a2 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -24,6 +24,7 @@ config ARCH_TEGRA_2x_SOC
select ARM_ERRATA_716044
select ARM_ERRATA_764369 if SMP
select ARCH_HAS_SUSPEND_PAGETABLE
+ select NVMAP_CACHE_MAINT_BY_SET_WAYS
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -51,6 +52,7 @@ config ARCH_TEGRA_3x_SOC
select TEGRA_LP2_ARM_TWD if HAVE_ARM_TWD && !TEGRA_RAIL_OFF_MULTIPLE_CPUS
select CPA
select ARCH_HAS_SUSPEND_PAGETABLE
+ select NVMAP_CACHE_MAINT_BY_SET_WAYS
help
Support for NVIDIA Tegra 3 family of SoCs, based upon the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -254,6 +256,14 @@ config TEGRA_FIQ_DEBUGGER
help
Enables the FIQ serial debugger on Tegra
+config TEGRA_P1852_TDM
+ bool "Enable TDM mode for P1852 SKUs"
+ default n
+ depends on MACH_P1852
+ help
+ Enables TDM mode driver for P1852 SKUs. If this
+ is not defined then I2S mode is selected by default.
+
config TEGRA_CARDHU_DSI
bool "Support DSI panel on Cardhu"
depends on MACH_CARDHU
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 3153203c6efc..9acb8305a175 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -67,6 +67,7 @@ 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-y += wakeups.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-t2.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-t3.o
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c
index 4da5d412cf41..30aba86f02f1 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power.c
+++ b/arch/arm/mach-tegra/baseband-xmm-power.c
@@ -187,10 +187,36 @@ static int baseband_modem_power_on(struct baseband_power_platform_data *data)
/* set IPC_HSIC_ACTIVE active */
gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
+ /* wait 20 ms */
+ mdelay(20);
+
/* reset / power on sequence */
- msleep(40);
+ mdelay(40);
gpio_set_value(data->modem.xmm.bb_rst, 1);
mdelay(1);
+
+ gpio_set_value(data->modem.xmm.bb_on, 1);
+ udelay(70);
+ gpio_set_value(data->modem.xmm.bb_on, 0);
+
+ return 0;
+}
+
+/* this function can sleep, do not call in atomic context */
+static int baseband_modem_power_on_async(
+ struct baseband_power_platform_data *data)
+{
+ /* set IPC_HSIC_ACTIVE active */
+ gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
+
+ /* wait 20 ms */
+ msleep(20);
+
+ /* reset / power on sequence */
+ msleep(40);
+ gpio_set_value(data->modem.xmm.bb_rst, 1);
+ usleep_range(1000, 2000);
+
gpio_set_value(data->modem.xmm.bb_on, 1);
udelay(70);
gpio_set_value(data->modem.xmm.bb_on, 0);
@@ -251,8 +277,9 @@ static int xmm_power_on(struct platform_device *device)
if (pdata->hsic_register)
data->hsic_device = pdata->hsic_register();
/* turn on modem */
- pr_debug("%s call baseband_modem_power_on\n", __func__);
- baseband_modem_power_on(pdata);
+ pr_debug("%s call baseband_modem_power_on_async\n",
+ __func__);
+ baseband_modem_power_on_async(pdata);
}
}
ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
@@ -302,11 +329,12 @@ static int xmm_power_off(struct platform_device *device)
gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
/* wait 20 ms */
- mdelay(20);
+ msleep(20);
/* drive bb_rst low */
gpio_set_value(pdata->modem.xmm.bb_rst, 0);
- mdelay(1);
+ /* sleep 1ms */
+ usleep_range(1000, 2000);
baseband_xmm_powerstate = BBXMM_PS_UNINIT;
modem_sleep_flag = false;
@@ -484,6 +512,7 @@ EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
{
struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
+ struct xmm_power_data *drv = &xmm_power_drv_data;
int value;
value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
@@ -521,6 +550,12 @@ irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
/* modem wakeup part */
if (!value) {
pr_debug("%s - falling\n", __func__);
+ if (drv->hostwake == 0) {
+ /* AP L2 to L0 wakeup */
+ pr_debug("received wakeup ap l2->l0\n");
+ drv->hostwake = 1;
+ wake_up_interruptible(&drv->bb_wait);
+ }
/* First check it a CP ack or CP wake */
value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
if (value) {
@@ -528,6 +563,7 @@ irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
ipc_ap_wake_state = IPC_AP_WAKE_L;
return IRQ_HANDLED;
}
+
spin_lock(&xmm_lock);
wakeup_pending = true;
if (system_suspending) {
@@ -593,19 +629,19 @@ static void xmm_power_init1_work(struct work_struct *work)
}
/* wait 100 ms */
- mdelay(100);
+ msleep(100);
/* set IPC_HSIC_ACTIVE low */
gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
/* wait 10 ms */
- mdelay(10);
+ usleep_range(10000, 11000);
/* set IPC_HSIC_ACTIVE high */
gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
/* wait 20 ms */
- mdelay(20);
+ msleep(20);
pr_debug("%s }\n", __func__);
}
@@ -654,9 +690,11 @@ static void xmm_power_autopm_resume(struct work_struct *work)
static void xmm_power_L2_resume(void)
{
struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
+ struct xmm_power_data *drv = &xmm_power_drv_data;
int value;
- int delay = 10000; /* maxmum delay in msec */
+ int delay = 1000; /* maxmum delay in msec */
unsigned long flags;
+ int ret, rcount = 0;
pr_debug("%s\n", __func__);
@@ -680,22 +718,30 @@ static void xmm_power_L2_resume(void)
pr_info("AP L2->L0\n");
value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
if (value) {
- pr_debug("waiting for host wakeup from CP...\n");
+ drv->hostwake = 0;
/* wake bb */
gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
- do {
- mdelay(1);
- value = gpio_get_value(
- pdata->modem.xmm.ipc_ap_wake);
- delay--;
- } while ((value) && (delay));
- if (delay)
- pr_debug("gpio host wakeup low <-\n");
- else
+retry:
+ /* wait for cp */
+ pr_debug("waiting for host wakeup from CP...\n");
+ ret = wait_event_interruptible_timeout(drv->bb_wait,
+ drv->hostwake == 1, msecs_to_jiffies(delay));
+ if (ret == 0) {
pr_info("!!AP L2->L0 Failed\n");
- } else {
+ return;
+ }
+ if (ret == -ERESTARTSYS) {
+ if (rcount >= 5) {
+ pr_info("!!AP L2->L0 Failed\n");
+ return;
+ }
+ pr_debug("%s: caught signal\n", __func__);
+ rcount++;
+ goto retry;
+ }
+ pr_debug("Get gpio host wakeup low <-\n");
+ } else
pr_info("CP already ready\n");
- }
}
}
@@ -723,7 +769,7 @@ static void xmm_power_reset_on(struct baseband_power_platform_data *pdata)
gpio_set_value(pdata->modem.xmm.bb_rst, 0);
msleep(40);
gpio_set_value(pdata->modem.xmm.bb_rst, 1);
- mdelay(1);
+ usleep_range(1000, 2000);
gpio_set_value(pdata->modem.xmm.bb_on, 1);
udelay(70);
gpio_set_value(pdata->modem.xmm.bb_on, 0);
@@ -778,6 +824,7 @@ static void xmm_power_work_func(struct work_struct *work)
* software directly.
*/
break;
+
case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
pr_info("%s: flashless is not supported here\n", __func__);
@@ -915,6 +962,10 @@ static int xmm_power_driver_probe(struct platform_device *device)
/* save platform data */
xmm_power_drv_data.pdata = pdata;
+ /* init wait queue */
+ xmm_power_drv_data.hostwake = 1;
+ init_waitqueue_head(&xmm_power_drv_data.bb_wait);
+
/* create device file */
err = device_create_file(dev, &dev_attr_xmm_onoff);
if (err < 0) {
@@ -1041,7 +1092,7 @@ static int xmm_power_driver_handle_resume(
struct baseband_power_platform_data *pdata)
{
int value;
- int delay = 1000; /* maxmum delay in msec */
+ unsigned long timeout;
unsigned long flags;
pr_debug("%s\n", __func__);
@@ -1064,29 +1115,30 @@ static int xmm_power_driver_handle_resume(
value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
if (value) {
pr_info("AP L3 -> L0\n");
- pr_debug("waiting for host wakeup...\n");
/* wake bb */
gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
+
+ /* Wait for max 1 sec */
+ timeout = jiffies + HZ;
+ pr_debug("Current: %lu: timeout %lu\n", jiffies, timeout);
do {
- mdelay(1);
+ udelay(100);
value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
- delay--;
- } while ((value) && (delay));
- if (delay)
+ if (!value)
+ break;
+ } while (time_before(jiffies, timeout));
+ if (!value)
pr_debug("gpio host wakeup low <-\n");
else
pr_info("!!AP L3->L0 Failed\n");
-
- } else {
+ } else
pr_info("CP L3 -> L0\n");
- }
+
reenable_autosuspend = true;
return 0;
-
}
-
#ifdef CONFIG_PM
static int xmm_power_driver_suspend(struct device *dev)
{
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.h b/arch/arm/mach-tegra/baseband-xmm-power.h
index 1f08e3b6900c..69140891319d 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power.h
+++ b/arch/arm/mach-tegra/baseband-xmm-power.h
@@ -84,6 +84,9 @@ struct xmm_power_data {
struct baseband_power_platform_data *pdata;
struct work_struct work;
struct platform_device *hsic_device;
+ wait_queue_head_t bb_wait;
+ /* host wakeup gpio state*/
+ unsigned int hostwake;
};
enum baseband_xmm_powerstate_t {
diff --git a/arch/arm/mach-tegra/board-aruba-power.c b/arch/arm/mach-tegra/board-aruba-power.c
index 4391f6f19b51..b72b82fc144a 100644
--- a/arch/arm/mach-tegra/board-aruba-power.c
+++ b/arch/arm/mach-tegra/board-aruba-power.c
@@ -26,7 +26,6 @@
#include "pm.h"
#include "board.h"
-#include "wakeups-t3.h"
static int ac_online(void)
{
diff --git a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
index f0dc8afa56fe..9168d9719b7c 100644
--- a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
+++ b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
*
- * Copyright (C) 2011 NVIDIA, Inc.
+ * Copyright (C) 2011-2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -37,7 +37,6 @@
#include "board.h"
#include "board-cardhu.h"
#include "pm.h"
-#include "wakeups-t3.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW BIT(17)
@@ -676,7 +675,6 @@ static struct platform_device *fixed_reg_devs_pm269[] = {
int __init cardhu_pm298_gpio_switch_regulator_init(void)
{
- int i;
struct board_info board_info;
struct platform_device **fixed_reg_devs;
int nfixreg_devs;
diff --git a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
index 6d4db73b6ecd..32f07599fea4 100644
--- a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
+++ b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
*
- * Copyright (C) 2011 NVIDIA, Inc.
+ * Copyright (C) 2011-2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -37,7 +37,6 @@
#include "gpio-names.h"
#include "board.h"
#include "board-cardhu.h"
-#include "wakeups-t3.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
@@ -666,7 +665,6 @@ static struct platform_device *fixed_reg_devs_pm269[] = {
int __init cardhu_pm299_gpio_switch_regulator_init(void)
{
- int i;
struct board_info board_info;
struct platform_device **fixed_reg_devs;
int nfixreg_devs;
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
index 61b5a15ed5c7..d517d8266204 100644
--- a/arch/arm/mach-tegra/board-cardhu-power.c
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-cardhu-power.c
*
- * Copyright (C) 2011-2012 NVIDIA, Inc.
+ * Copyright (C) 2011-2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -42,7 +42,6 @@
#include "board.h"
#include "board-cardhu.h"
#include "pm.h"
-#include "wakeups-t3.h"
#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
@@ -994,7 +993,6 @@ static struct platform_device *fixed_reg_devs_e1291_a04[] = {
int __init cardhu_fixed_regulator_init(void)
{
- int i;
struct board_info board_info;
struct board_info pmu_board_info;
struct board_info display_board_info;
diff --git a/arch/arm/mach-tegra/board-cardhu-sdhci.c b/arch/arm/mach-tegra/board-cardhu-sdhci.c
index cb0684bcc742..d8be9fe6747f 100644
--- a/arch/arm/mach-tegra/board-cardhu-sdhci.c
+++ b/arch/arm/mach-tegra/board-cardhu-sdhci.c
@@ -145,6 +145,7 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
.embedded_sdio = &embedded_sdio_data2,
#endif
.built_in = 0,
+ .ocr_mask = MMC_OCR_1V8_MASK,
},
#ifndef CONFIG_MMC_EMBEDDED_SDIO
.pm_flags = MMC_PM_KEEP_POWER,
diff --git a/arch/arm/mach-tegra/board-enterprise-baseband.c b/arch/arm/mach-tegra/board-enterprise-baseband.c
index 9143103fd036..f2c94fda7727 100644
--- a/arch/arm/mach-tegra/board-enterprise-baseband.c
+++ b/arch/arm/mach-tegra/board-enterprise-baseband.c
@@ -69,11 +69,14 @@ static struct gpio modem_gpios[] = {
static void baseband_phy_init(void);
static void baseband_phy_on(void);
-static void baseband_phy_off(void);
+static void baseband_pre_phy_off(void);
+static void baseband_post_phy_off(void);
+static bool ap2mdm_ack_gpio_off = false;
static struct tegra_usb_phy_platform_ops ulpi_null_plat_ops = {
.init = baseband_phy_init,
- .pre_phy_off = baseband_phy_off,
+ .pre_phy_off = baseband_pre_phy_off,
+ .post_phy_off = baseband_post_phy_off,
.post_phy_on = baseband_phy_on,
};
@@ -133,16 +136,65 @@ static void baseband_phy_init(void)
pr_info("%s\n", __func__);
}
-static void baseband_phy_off(void)
+static inline void null_phy_set_tristate(bool enable)
+{
+ int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
+
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA3, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA4, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA5, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA6, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA7, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_NXT, tristate);
+
+ if (enable)
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, tristate);
+}
+
+
+static void baseband_post_phy_off(void)
+{
+ null_phy_set_tristate(true);
+}
+
+
+static void baseband_pre_phy_off(void)
{
/* set AP2MDM_ACK2 high */
gpio_set_value(AP2MDM_ACK2, 1);
+ ap2mdm_ack_gpio_off = true;
}
static void baseband_phy_on(void)
{
- /* set AP2MDM_ACK2 low */
- gpio_set_value(AP2MDM_ACK2, 0);
+ if (ap2mdm_ack_gpio_off) {
+
+ /* driving linestate using GPIO */
+ gpio_set_value(ULPI_D0, 0);
+ gpio_set_value(ULPI_D1, 0);
+
+ /* remove ULPI tristate */
+ null_phy_set_tristate(false);
+
+ gpio_set_value(AP2MDM_ACK2, 0);
+
+ if (gpio_is_valid(MDM2AP_ACK2)) {
+ int retry = 20000;
+ while (retry) {
+ /* poll phy_restore_gpio high */
+ if (gpio_get_value(MDM2AP_ACK2))
+ break;
+ retry--;
+ }
+
+ if (retry == 0)
+ pr_info("phy_restore_gpio timeout\n");
+ }
+ ap2mdm_ack_gpio_off = false;
+ }
}
static void baseband_start(void)
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index c7598ab56139..f32365d808a7 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -44,7 +44,6 @@
#include "board.h"
#include "board-enterprise.h"
#include "pm.h"
-#include "wakeups-t3.h"
#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
@@ -298,6 +297,7 @@ static struct tps80031_rtc_platform_data rtc_data = {
.tm_min = 2,
.tm_sec = 3,
},
+ .msecure_gpio = TEGRA_GPIO_PF7,
};
int battery_charger_init(void *board_data)
@@ -746,6 +746,8 @@ int __init enterprise_regulator_init(void)
battery_gauge_data.battery_present = 0;
}
+ tegra_gpio_enable(TEGRA_GPIO_PF7);
+
if (board_info.fab < BOARD_FAB_A03) {
tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs_a02);
tps_platform.subdevs = tps80031_devs_a02;
diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
index d92ac57dd054..e23a9a468081 100644
--- a/arch/arm/mach-tegra/board-enterprise.c
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -684,7 +684,8 @@ static struct tegra_usb_platform_data tegra_udc_pdata = {
.phy_intf = TEGRA_USB_PHY_INTF_UTMI,
.op_mode = TEGRA_USB_OPMODE_DEVICE,
.u_data.dev = {
- .vbus_pmu_irq = 0,
+ .vbus_pmu_irq = ENT_TPS80031_IRQ_BASE +
+ TPS80031_INT_VBUS_DET,
.vbus_gpio = -1,
.charging_supported = false,
.remote_wakeup_supported = false,
diff --git a/arch/arm/mach-tegra/board-kai-kbc.c b/arch/arm/mach-tegra/board-kai-kbc.c
index 928e5de707c9..e55383a1028b 100644
--- a/arch/arm/mach-tegra/board-kai-kbc.c
+++ b/arch/arm/mach-tegra/board-kai-kbc.c
@@ -90,13 +90,6 @@ int __init kai_keys_init(void)
pr_info("Registering gpio keys\n");
- /* Enable gpio mode for other pins */
- for (i = 0; i < kai_keys_platform_data.nbuttons; i++) {
- if (kai_keys_platform_data.buttons[i].gpio < 0)
- continue;
- tegra_gpio_enable(kai_keys_platform_data.buttons[i].gpio);
- }
-
platform_device_register(&kai_keys_device);
return 0;
diff --git a/arch/arm/mach-tegra/board-kai-panel.c b/arch/arm/mach-tegra/board-kai-panel.c
index 4073afe2fc8d..45333840ffb7 100644
--- a/arch/arm/mach-tegra/board-kai-panel.c
+++ b/arch/arm/mach-tegra/board-kai-panel.c
@@ -111,8 +111,6 @@ static int kai_backlight_init(struct device *dev)
if (WARN_ON(ARRAY_SIZE(kai_bl_output_measured) != 256))
pr_err("bl_output array does not have 256 elements\n");
- tegra_gpio_disable(kai_bl_pwm);
-
ret = gpio_request(kai_bl_enb, "backlight_enb");
if (ret < 0)
return ret;
@@ -120,8 +118,6 @@ static int kai_backlight_init(struct device *dev)
ret = gpio_direction_output(kai_bl_enb, 1);
if (ret < 0)
gpio_free(kai_bl_enb);
- else
- tegra_gpio_enable(kai_bl_enb);
return ret;
};
@@ -132,7 +128,6 @@ static void kai_backlight_exit(struct device *dev)
/*ret = gpio_request(kai_bl_enb, "backlight_enb");*/
gpio_set_value(kai_bl_enb, 0);
gpio_free(kai_bl_enb);
- tegra_gpio_disable(kai_bl_enb);
return;
}
@@ -654,35 +649,27 @@ int __init kai_panel_init(void)
#endif
gpio_request(kai_lvds_avdd_en, "lvds_avdd_en");
gpio_direction_output(kai_lvds_avdd_en, 1);
- tegra_gpio_enable(kai_lvds_avdd_en);
gpio_request(kai_lvds_stdby, "lvds_stdby");
gpio_direction_output(kai_lvds_stdby, 1);
- tegra_gpio_enable(kai_lvds_stdby);
gpio_request(kai_lvds_rst, "lvds_rst");
gpio_direction_output(kai_lvds_rst, 1);
- tegra_gpio_enable(kai_lvds_rst);
if (board_info.fab == BOARD_FAB_A00) {
gpio_request(kai_lvds_rs_a00, "lvds_rs");
gpio_direction_output(kai_lvds_rs_a00, 0);
- tegra_gpio_enable(kai_lvds_rs_a00);
} else {
gpio_request(kai_lvds_rs, "lvds_rs");
gpio_direction_output(kai_lvds_rs, 0);
- tegra_gpio_enable(kai_lvds_rs);
}
gpio_request(kai_lvds_lr, "lvds_lr");
gpio_direction_output(kai_lvds_lr, 1);
- tegra_gpio_enable(kai_lvds_lr);
gpio_request(kai_lvds_shutdown, "lvds_shutdown");
gpio_direction_output(kai_lvds_shutdown, 1);
- tegra_gpio_enable(kai_lvds_shutdown);
- tegra_gpio_enable(kai_hdmi_hpd);
gpio_request(kai_hdmi_hpd, "hdmi_hpd");
gpio_direction_input(kai_hdmi_hpd);
diff --git a/arch/arm/mach-tegra/board-kai-pinmux.c b/arch/arm/mach-tegra/board-kai-pinmux.c
index fa750f15ca7e..be11d4ef6698 100644
--- a/arch/arm/mach-tegra/board-kai-pinmux.c
+++ b/arch/arm/mach-tegra/board-kai-pinmux.c
@@ -449,13 +449,9 @@ static __initdata struct tegra_pingroup_config unused_pins_lowpower[] = {
static void __init kai_pinmux_audio_init(void)
{
- tegra_gpio_enable(TEGRA_GPIO_CDC_IRQ);
gpio_request(TEGRA_GPIO_CDC_IRQ, "rt5640");
gpio_direction_input(TEGRA_GPIO_CDC_IRQ);
- tegra_gpio_enable(TEGRA_GPIO_HP_DET);
- tegra_gpio_enable(TEGRA_GPIO_INT_MIC_EN);
- tegra_gpio_enable(TEGRA_GPIO_EXT_MIC_EN);
}
/* We are disabling this code for now. */
@@ -551,7 +547,6 @@ static void set_unused_pin_gpio(struct gpio_init_pin_info *lpm_pin_info,
gpio_free(pin_info->gpio_nr);
continue;
}
- tegra_gpio_enable(pin_info->gpio_nr);
}
}
diff --git a/arch/arm/mach-tegra/board-kai-power.c b/arch/arm/mach-tegra/board-kai-power.c
index e89b2bd2246d..cc3b35608c98 100644
--- a/arch/arm/mach-tegra/board-kai-power.c
+++ b/arch/arm/mach-tegra/board-kai-power.c
@@ -40,7 +40,6 @@
#include "board.h"
#include "board-kai.h"
#include "pm.h"
-#include "wakeups-t3.h"
#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
@@ -567,8 +566,6 @@ static int __init kai_fixed_regulator_init(void)
fixed_reg_devs[i]->dev.platform_data;
gpio_nr = fixed_reg_pdata->gpio;
- if (gpio_nr < TEGRA_NR_GPIOS)
- tegra_gpio_enable(gpio_nr);
}
return platform_add_devices(fixed_reg_devs, nfixreg_devs);
diff --git a/arch/arm/mach-tegra/board-kai-sdhci.c b/arch/arm/mach-tegra/board-kai-sdhci.c
index 8d1d4a9bd4a8..0fa39ccf475d 100644
--- a/arch/arm/mach-tegra/board-kai-sdhci.c
+++ b/arch/arm/mach-tegra/board-kai-sdhci.c
@@ -106,6 +106,7 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
.mmc_data = {
.register_status_notify = kai_wifi_status_register,
.built_in = 0,
+ .ocr_mask = MMC_OCR_1V8_MASK,
},
#ifndef CONFIG_MMC_EMBEDDED_SDIO
.pm_flags = MMC_PM_KEEP_POWER,
@@ -243,9 +244,6 @@ static int __init kai_wifi_init(void)
if (rc)
pr_err("WLAN_IRQ gpio request failed:%d\n", rc);
- tegra_gpio_enable(KAI_WLAN_EN);
- tegra_gpio_enable(KAI_WLAN_IRQ);
-
rc = gpio_direction_output(KAI_WLAN_EN, 0);
if (rc)
pr_err("WLAN_EN gpio direction configuration failed:%d\n", rc);
diff --git a/arch/arm/mach-tegra/board-kai-sensors.c b/arch/arm/mach-tegra/board-kai-sensors.c
index 9564aaf0cfde..c545b2d0d786 100644
--- a/arch/arm/mach-tegra/board-kai-sensors.c
+++ b/arch/arm/mach-tegra/board-kai-sensors.c
@@ -135,9 +135,6 @@ static int kai_nct1008_init(void)
pr_err("%s: set gpio to input failed\n", __func__);
gpio_free(KAI_TEMP_ALERT_GPIO);
}
- else
- tegra_gpio_enable(KAI_TEMP_ALERT_GPIO);
-
return ret;
}
@@ -158,7 +155,6 @@ static int kai_camera_init(void)
{
int ret;
- tegra_gpio_enable(CAM2_POWER_DWN_GPIO);
ret = gpio_request(CAM2_POWER_DWN_GPIO, "cam2_power_en");
if (ret < 0) {
pr_err("%s: gpio_request failed for gpio %s\n",
@@ -168,7 +164,6 @@ static int kai_camera_init(void)
gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
mdelay(10);
- tegra_gpio_enable(CAM2_RST_GPIO);
ret = gpio_request(CAM2_RST_GPIO, "cam2_reset");
if (ret < 0) {
pr_err("%s: gpio_request failed for gpio %s\n",
@@ -314,7 +309,6 @@ static void mpuirq_init(void)
#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
#if MPU_ACCEL_IRQ_GPIO
/* ACCEL-IRQ assignment */
- tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
if (ret < 0) {
pr_err("%s: gpio_request failed %d\n", __func__, ret);
@@ -331,7 +325,6 @@ static void mpuirq_init(void)
#endif
/* MPU-IRQ assignment */
- tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
if (ret < 0) {
pr_err("%s: gpio_request failed %d\n", __func__, ret);
diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c
index 193d68632d52..86374cf27271 100644
--- a/arch/arm/mach-tegra/board-kai.c
+++ b/arch/arm/mach-tegra/board-kai.c
@@ -108,7 +108,6 @@ static noinline void __init kai_bt_st(void)
platform_device_register(&wl128x_device);
platform_device_register(&btwilink_device);
- tegra_gpio_enable(TEGRA_GPIO_PU0);
}
static struct resource kai_bluesleep_resources[] = {
@@ -620,9 +619,6 @@ static int __init kai_touch_init(void)
{
int touch_id;
- tegra_gpio_enable(KAI_TS_ID1);
- tegra_gpio_enable(KAI_TS_ID2);
-
gpio_request(KAI_TS_ID1, "touch-id1");
gpio_direction_input(KAI_TS_ID1);
@@ -764,10 +760,6 @@ static void kai_modem_init(void)
{
int ret;
- tegra_gpio_enable(TEGRA_GPIO_W_DISABLE);
- tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD1);
- tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD2);
-
ret = gpio_request(TEGRA_GPIO_W_DISABLE, "w_disable_gpio");
if (ret < 0)
pr_err("%s: gpio_request failed for gpio %d\n",
@@ -813,13 +805,6 @@ static void kai_audio_init(void)
}
}
-static void kai_nfc_init(void)
-{
- tegra_gpio_enable(TEGRA_GPIO_PX0);
- tegra_gpio_enable(TEGRA_GPIO_PS7);
- tegra_gpio_enable(TEGRA_GPIO_PR3);
-}
-
static void __init tegra_kai_init(void)
{
tegra_thermal_init(&thermal_data);
@@ -843,7 +828,6 @@ static void __init tegra_kai_init(void)
kai_panel_init();
kai_bt_st();
kai_tegra_setup_tibluesleep();
- kai_nfc_init();
kai_sensors_init();
kai_pins_state_init();
kai_emc_init();
diff --git a/arch/arm/mach-tegra/board-p1852-pinmux.c b/arch/arm/mach-tegra/board-p1852-pinmux.c
index 1503c80c8269..9133c7daa972 100644
--- a/arch/arm/mach-tegra/board-p1852-pinmux.c
+++ b/arch/arm/mach-tegra/board-p1852-pinmux.c
@@ -63,14 +63,21 @@
/* !!!FIXME!!!! Update drive strength with characterized value */
static __initdata struct tegra_drive_pingroup_config p1852_drive_pinmux[] = {
- SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
+ /* ATC1 CFG */
+ SET_DRIVE(AT1, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* ATC2 CFG */
+ SET_DRIVE(AT2, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* ATC3 CFG */
+ SET_DRIVE(AT3, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* ATC4 CFG */
+ SET_DRIVE(AT4, DISABLE, DISABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
/* All I2C pins are driven to maximum drive strength */
/* GEN1 I2C */
SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
/* GEN2 I2C */
- SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
+ SET_DRIVE(AT5, DISABLE, ENABLE, DIV_1, 12, 30, FASTEST, FASTEST),
/* DDC I2C */
SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
@@ -83,6 +90,48 @@ static __initdata struct tegra_drive_pingroup_config p1852_drive_pinmux[] = {
SET_DRIVE(GMF, DISABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
SET_DRIVE(GMG, DISABLE, ENABLE, DIV_1, 15, 6, SLOWEST, SLOWEST),
SET_DRIVE(GMH, DISABLE, ENABLE, DIV_1, 12, 6, SLOWEST, SLOWEST),
+
+ /* LCD */
+ SET_DRIVE(LCD1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
+ SET_DRIVE(LCD2, DISABLE, ENABLE, DIV_1, 2, 2, FASTEST, FASTEST),
+
+ /* DAP2 */
+ SET_DRIVE(DAP2, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* DAP4 */
+ SET_DRIVE(DAP4, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* DBG */
+ SET_DRIVE(DBG, ENABLE, ENABLE, DIV_1, 20, 0, SLOWEST, SLOWEST),
+ /* SPI */
+ SET_DRIVE(SPI, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* UAA */
+ SET_DRIVE(UAA, DISABLE, DISABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* UART2 */
+ SET_DRIVE(UART2, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* UART3 */
+ SET_DRIVE(UART3, ENABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* GME */
+ SET_DRIVE(GME, DISABLE, ENABLE, DIV_1, 1, 4, SLOWEST, SLOWEST),
+ /* GMF */
+ SET_DRIVE(GMF, DISABLE, ENABLE, DIV_1, 0, 0, SLOWEST, SLOWEST),
+ /* GMG */
+ SET_DRIVE(GMG, DISABLE, ENABLE, DIV_1, 3, 0, SLOWEST, SLOWEST),
+ /* GMH */
+ SET_DRIVE(GMH, DISABLE, ENABLE, DIV_1, 0, 12, SLOWEST, SLOWEST),
+
+ /* I2S/TDM */
+#ifdef CONFIG_TEGRA_MODS
+ SET_DRIVE(DAP1, ENABLE, ENABLE, DIV_1, 20, 20, SLOWEST, SLOWEST),
+ SET_DRIVE(DAP3, ENABLE, ENABLE, DIV_1, 20, 20, SLOWEST, SLOWEST),
+#else
+ SET_DRIVE(DAP1, ENABLE, ENABLE, DIV_1, 3, 3, SLOWEST, SLOWEST),
+ SET_DRIVE(DAP3, ENABLE, ENABLE, DIV_1, 3, 3, SLOWEST, SLOWEST),
+#endif
+
+ /* SPI */
+ SET_DRIVE(UAD, DISABLE, ENABLE, DIV_1, 4, 1, SLOWEST, SLOWEST),
+ SET_DRIVE(UAB, DISABLE, ENABLE, DIV_1, 4, 1, SLOWEST, SLOWEST),
+ SET_DRIVE(SDIO3, DISABLE, ENABLE, DIV_8, 4, 1, FASTEST, FASTEST),
+
};
#define DEFAULT_PINMUX(_pingroup, _mux, _pupd, _tri, _io) \
diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c
index 71c12756539d..eebbb24a9871 100644
--- a/arch/arm/mach-tegra/board-p1852.c
+++ b/arch/arm/mach-tegra/board-p1852.c
@@ -200,12 +200,14 @@ static void __init p1852_uart_init(void)
ARRAY_SIZE(p1852_uart_devices));
}
-static struct tegra_p1852_platform_data p1852_audio_pdata = {
+#if defined(CONFIG_TEGRA_P1852_TDM)
+static struct tegra_p1852_platform_data p1852_audio_tdm_pdata = {
.codec_info[0] = {
.codec_dai_name = "dit-hifi",
.cpu_dai_name = "tegra30-i2s.0",
.codec_name = "spdif-dit.0",
.name = "tegra-i2s-1",
+ .pcm_driver = "tegra-tdm-pcm-audio",
.i2s_format = format_tdm,
.master = 1,
.num_slots = 4,
@@ -218,6 +220,7 @@ static struct tegra_p1852_platform_data p1852_audio_pdata = {
.cpu_dai_name = "tegra30-i2s.4",
.codec_name = "spdif-dit.1",
.name = "tegra-i2s-2",
+ .pcm_driver = "tegra-tdm-pcm-audio",
.i2s_format = format_tdm,
.master = 1,
.num_slots = 8,
@@ -225,9 +228,29 @@ static struct tegra_p1852_platform_data p1852_audio_pdata = {
.tx_mask = 0xff,
.rx_mask = 0xff,
},
-
};
-
+#else
+static struct tegra_p1852_platform_data p1852_audio_i2s_pdata = {
+ .codec_info[0] = {
+ .codec_dai_name = "dit-hifi",
+ .cpu_dai_name = "tegra30-i2s.0",
+ .codec_name = "spdif-dit.0",
+ .name = "tegra-i2s-1",
+ .pcm_driver = "tegra-pcm-audio",
+ .i2s_format = format_i2s,
+ .master = 1,
+ },
+ .codec_info[1] = {
+ .codec_dai_name = "dit-hifi",
+ .cpu_dai_name = "tegra30-i2s.4",
+ .codec_name = "spdif-dit.1",
+ .name = "tegra-i2s-2",
+ .pcm_driver = "tegra-pcm-audio",
+ .i2s_format = format_i2s,
+ .master = 0,
+ },
+};
+#endif
static struct platform_device generic_codec_1 = {
.name = "spdif-dit",
.id = 0,
@@ -241,13 +264,18 @@ static struct platform_device tegra_snd_p1852 = {
.name = "tegra-snd-p1852",
.id = 0,
.dev = {
- .platform_data = &p1852_audio_pdata,
+#if defined(CONFIG_TEGRA_P1852_TDM)
+ .platform_data = &p1852_audio_tdm_pdata,
+#else
+ .platform_data = &p1852_audio_i2s_pdata,
+#endif
},
};
static void p1852_i2s_audio_init(void)
{
platform_device_register(&tegra_pcm_device);
+ platform_device_register(&tegra_tdm_pcm_device);
platform_device_register(&generic_codec_1);
platform_device_register(&generic_codec_2);
platform_device_register(&tegra_i2s_device0);
diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c
index f396557411b8..e848441ef7e0 100644
--- a/arch/arm/mach-tegra/board-ventana-panel.c
+++ b/arch/arm/mach-tegra/board-ventana-panel.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-ventana-panel.c
*
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2012 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,8 +63,6 @@ static int ventana_backlight_init(struct device *dev) {
ret = gpio_direction_output(ventana_bl_enb, 1);
if (ret < 0)
gpio_free(ventana_bl_enb);
- else
- tegra_gpio_enable(ventana_bl_enb);
return ret;
};
@@ -72,7 +70,6 @@ static int ventana_backlight_init(struct device *dev) {
static void ventana_backlight_exit(struct device *dev) {
gpio_set_value(ventana_bl_enb, 0);
gpio_free(ventana_bl_enb);
- tegra_gpio_disable(ventana_bl_enb);
}
static int ventana_backlight_notify(struct device *unused, int brightness)
@@ -392,13 +389,10 @@ int __init ventana_panel_init(void)
gpio_request(ventana_lvds_shutdown, "lvds_shdn");
gpio_direction_output(ventana_lvds_shutdown, 1);
- tegra_gpio_enable(ventana_lvds_shutdown);
- tegra_gpio_enable(ventana_hdmi_enb);
gpio_request(ventana_hdmi_enb, "hdmi_5v_en");
gpio_direction_output(ventana_hdmi_enb, 1);
- tegra_gpio_enable(ventana_hdmi_hpd);
gpio_request(ventana_hdmi_hpd, "hdmi_hpd");
gpio_direction_input(ventana_hdmi_hpd);
diff --git a/arch/arm/mach-tegra/board-ventana-power.c b/arch/arm/mach-tegra/board-ventana-power.c
index 2acfdfed28e4..aa6f4be203ad 100644
--- a/arch/arm/mach-tegra/board-ventana-power.c
+++ b/arch/arm/mach-tegra/board-ventana-power.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 NVIDIA, Inc.
+ * Copyright (C) 2010-2012 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,6 @@
#include "gpio-names.h"
#include "fuse.h"
#include "pm.h"
-#include "wakeups-t2.h"
#include "board.h"
#include "board-ventana.h"
@@ -47,7 +46,6 @@ int __init ventana_charge_init(void)
{
gpio_request(CHARGING_DISABLE, "chg_disable");
gpio_direction_output(CHARGING_DISABLE, 0);
- tegra_gpio_enable(CHARGING_DISABLE);
return 0;
}
@@ -255,14 +253,6 @@ static struct platform_device *fixed_voltage_regulators[] __initdata = {
int __init ventana_fixed_voltage_regulator_init(void)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fixed_voltage_regulators); ++i) {
- struct fixed_voltage_config *fixed_voltage_regulators_pdata =
- fixed_voltage_regulators[i]->dev.platform_data;
- if (fixed_voltage_regulators_pdata->gpio < TEGRA_NR_GPIOS)
- tegra_gpio_enable(fixed_voltage_regulators_pdata->gpio);
- }
return platform_add_devices(fixed_voltage_regulators,
ARRAY_SIZE(fixed_voltage_regulators));
}
@@ -317,7 +307,6 @@ static struct platform_device ventana_charger_device = {
int __init ventana_charger_init(void)
{
- tegra_gpio_enable(AC_PRESENT_GPIO);
platform_device_register(&ventana_charger_device);
return 0;
}
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
index 188335ac98c5..9d426aadff79 100644
--- a/arch/arm/mach-tegra/board-ventana-sdhci.c
+++ b/arch/arm/mach-tegra/board-ventana-sdhci.c
@@ -1,7 +1,6 @@
/*
- * arch/arm/mach-tegra/board-harmony-sdhci.c
- *
* Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010-2012 NVIDIA Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -132,6 +131,7 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.embedded_sdio = &embedded_sdio_data0,
#endif
.built_in = 0,
+ .ocr_mask = MMC_OCR_1V8_MASK,
},
#ifndef CONFIG_MMC_EMBEDDED_SDIO
.pm_flags = MMC_PM_KEEP_POWER,
@@ -257,10 +257,6 @@ static int __init ventana_wifi_init(void)
gpio_request(VENTANA_WLAN_RST, "wlan_rst");
gpio_request(VENTANA_WLAN_WOW, "bcmsdh_sdmmc");
- tegra_gpio_enable(VENTANA_WLAN_PWR);
- tegra_gpio_enable(VENTANA_WLAN_RST);
- tegra_gpio_enable(VENTANA_WLAN_WOW);
-
gpio_direction_output(VENTANA_WLAN_PWR, 0);
gpio_direction_output(VENTANA_WLAN_RST, 0);
gpio_direction_input(VENTANA_WLAN_WOW);
@@ -274,11 +270,6 @@ static int __init ventana_wifi_init(void)
}
int __init ventana_sdhci_init(void)
{
- tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio);
- tegra_gpio_enable(tegra_sdhci_platform_data2.cd_gpio);
- tegra_gpio_enable(tegra_sdhci_platform_data2.wp_gpio);
- tegra_gpio_enable(tegra_sdhci_platform_data3.power_gpio);
-
platform_device_register(&tegra_sdhci_device3);
platform_device_register(&tegra_sdhci_device2);
platform_device_register(&tegra_sdhci_device0);
diff --git a/arch/arm/mach-tegra/board-ventana-sensors.c b/arch/arm/mach-tegra/board-ventana-sensors.c
index 574bdb25fc2a..be7c179dfad9 100644
--- a/arch/arm/mach-tegra/board-ventana-sensors.c
+++ b/arch/arm/mach-tegra/board-ventana-sensors.c
@@ -186,7 +186,6 @@ static struct ssl3250a_platform_data ventana_ssl3250a_pdata = {
static void ventana_isl29018_init(void)
{
- tegra_gpio_enable(ISL29018_IRQ_GPIO);
gpio_request(ISL29018_IRQ_GPIO, "isl29018");
gpio_direction_input(ISL29018_IRQ_GPIO);
}
@@ -194,7 +193,6 @@ static void ventana_isl29018_init(void)
#ifdef CONFIG_SENSORS_AK8975
static void ventana_akm8975_init(void)
{
- tegra_gpio_enable(AKM8975_IRQ_GPIO);
gpio_request(AKM8975_IRQ_GPIO, "akm8975");
gpio_direction_input(AKM8975_IRQ_GPIO);
}
@@ -202,7 +200,6 @@ static void ventana_akm8975_init(void)
static void ventana_nct1008_init(void)
{
- tegra_gpio_enable(NCT1008_THERM2_GPIO);
gpio_request(NCT1008_THERM2_GPIO, "temp_alert");
gpio_direction_input(NCT1008_THERM2_GPIO);
}
@@ -379,7 +376,6 @@ static void mpuirq_init(void)
#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
#if MPU_ACCEL_IRQ_GPIO
/* ACCEL-IRQ assignment */
- tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
if (ret < 0) {
pr_err("%s: gpio_request failed %d\n", __func__, ret);
@@ -396,7 +392,6 @@ static void mpuirq_init(void)
#endif
/* MPU-IRQ assignment */
- tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
if (ret < 0) {
pr_err("%s: gpio_request failed %d\n", __func__, ret);
@@ -465,37 +460,35 @@ int __init ventana_sensors_init(void)
struct tegra_camera_gpios {
const char *name;
int gpio;
- bool tegra_internal_gpio;
int enabled;
};
-#define TEGRA_CAMERA_GPIO(_name, _gpio, _tegra_internal_gpio, _enabled) \
+#define TEGRA_CAMERA_GPIO(_name, _gpio, _enabled) \
{ \
.name = _name, \
.gpio = _gpio, \
- .tegra_internal_gpio = _tegra_internal_gpio, \
.enabled = _enabled, \
}
static struct tegra_camera_gpios ventana_camera_gpio_keys[] = {
- [0] = TEGRA_CAMERA_GPIO("camera_power_en", CAMERA_POWER_GPIO, true, 1),
- [1] = TEGRA_CAMERA_GPIO("camera_csi_sel", CAMERA_CSI_MUX_SEL_GPIO, true, 0),
- [2] = TEGRA_CAMERA_GPIO("torch_gpio_act", CAMERA_FLASH_ACT_GPIO, true, 0),
+ [0] = TEGRA_CAMERA_GPIO("camera_power_en", CAMERA_POWER_GPIO, 1),
+ [1] = TEGRA_CAMERA_GPIO("camera_csi_sel", CAMERA_CSI_MUX_SEL_GPIO, 0),
+ [2] = TEGRA_CAMERA_GPIO("torch_gpio_act", CAMERA_FLASH_ACT_GPIO, 0),
- [3] = TEGRA_CAMERA_GPIO("en_avdd_csi", AVDD_DSI_CSI_ENB_GPIO, false, 1),
- [4] = TEGRA_CAMERA_GPIO("cam_i2c_mux_rst_lo", CAM_I2C_MUX_RST_GPIO, false, 1),
+ [3] = TEGRA_CAMERA_GPIO("en_avdd_csi", AVDD_DSI_CSI_ENB_GPIO, 1),
+ [4] = TEGRA_CAMERA_GPIO("cam_i2c_mux_rst_lo", CAM_I2C_MUX_RST_GPIO, 1),
- [5] = TEGRA_CAMERA_GPIO("cam2_af_pwdn_lo", CAM2_AF_PWR_DN_L_GPIO, false, 0),
- [6] = TEGRA_CAMERA_GPIO("cam2_pwdn", CAM2_PWR_DN_GPIO, false, 0),
- [7] = TEGRA_CAMERA_GPIO("cam2_rst_lo", CAM2_RST_L_GPIO, false, 1),
+ [5] = TEGRA_CAMERA_GPIO("cam2_af_pwdn_lo", CAM2_AF_PWR_DN_L_GPIO, 0),
+ [6] = TEGRA_CAMERA_GPIO("cam2_pwdn", CAM2_PWR_DN_GPIO, 0),
+ [7] = TEGRA_CAMERA_GPIO("cam2_rst_lo", CAM2_RST_L_GPIO, 1),
- [8] = TEGRA_CAMERA_GPIO("cam3_af_pwdn_lo", CAM3_AF_PWR_DN_L_GPIO, false, 0),
- [9] = TEGRA_CAMERA_GPIO("cam3_pwdn", CAM3_PWR_DN_GPIO, false, 0),
- [10] = TEGRA_CAMERA_GPIO("cam3_rst_lo", CAM3_RST_L_GPIO, false, 1),
+ [8] = TEGRA_CAMERA_GPIO("cam3_af_pwdn_lo", CAM3_AF_PWR_DN_L_GPIO, 0),
+ [9] = TEGRA_CAMERA_GPIO("cam3_pwdn", CAM3_PWR_DN_GPIO, 0),
+ [10] = TEGRA_CAMERA_GPIO("cam3_rst_lo", CAM3_RST_L_GPIO, 1),
- [11] = TEGRA_CAMERA_GPIO("cam1_af_pwdn_lo", CAM1_AF_PWR_DN_L_GPIO, false, 0),
- [12] = TEGRA_CAMERA_GPIO("cam1_pwdn", CAM1_PWR_DN_GPIO, false, 0),
- [13] = TEGRA_CAMERA_GPIO("cam1_rst_lo", CAM1_RST_L_GPIO, false, 1),
+ [11] = TEGRA_CAMERA_GPIO("cam1_af_pwdn_lo", CAM1_AF_PWR_DN_L_GPIO, 0),
+ [12] = TEGRA_CAMERA_GPIO("cam1_pwdn", CAM1_PWR_DN_GPIO, 0),
+ [13] = TEGRA_CAMERA_GPIO("cam1_rst_lo", CAM1_RST_L_GPIO, 1),
};
int __init ventana_camera_late_init(void)
@@ -522,10 +515,6 @@ int __init ventana_camera_late_init(void)
i2c_new_device(i2c_get_adapter(3), ventana_i2c3_board_info_tca6416);
for (i = 0; i < ARRAY_SIZE(ventana_camera_gpio_keys); i++) {
-
- if (ventana_camera_gpio_keys[i].tegra_internal_gpio)
- tegra_gpio_enable(ventana_camera_gpio_keys[i].gpio);
-
ret = gpio_request(ventana_camera_gpio_keys[i].gpio,
ventana_camera_gpio_keys[i].name);
if (ret < 0) {
diff --git a/arch/arm/mach-tegra/board-ventana.c b/arch/arm/mach-tegra/board-ventana.c
index 779ffdba0f65..942ca44e2a13 100644
--- a/arch/arm/mach-tegra/board-ventana.c
+++ b/arch/arm/mach-tegra/board-ventana.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-ventana.c
*
- * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2010-2011 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -119,8 +119,6 @@ static struct platform_device ventana_bluesleep_device = {
static void __init ventana_setup_bluesleep(void)
{
platform_device_register(&ventana_bluesleep_device);
- tegra_gpio_enable(TEGRA_GPIO_PU6);
- tegra_gpio_enable(TEGRA_GPIO_PU1);
return;
}
@@ -326,7 +324,8 @@ static int ventana_wakeup_key(void)
unsigned long status =
readl(IO_ADDRESS(TEGRA_PMC_BASE) + PMC_WAKE_STATUS);
- return status & TEGRA_WAKE_GPIO_PV2 ? KEY_POWER : KEY_RESERVED;
+ return (status & (1 << TEGRA_WAKE_GPIO_PV2)) ?
+ KEY_POWER : KEY_RESERVED;
}
static struct gpio_keys_platform_data ventana_keys_platform_data = {
@@ -342,14 +341,6 @@ static struct platform_device ventana_keys_device = {
.platform_data = &ventana_keys_platform_data,
},
};
-
-static void ventana_keys_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ventana_keys); i++)
- tegra_gpio_enable(ventana_keys[i].gpio);
-}
#endif
static struct platform_device tegra_camera = {
@@ -625,10 +616,6 @@ static void __init tegra_ventana_init(void)
ventana_touch_init_panjit();
}
-#ifdef CONFIG_KEYBOARD_GPIO
- ventana_keys_init();
-#endif
-
ventana_usb_init();
ventana_gps_init();
ventana_panel_init();
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.c b/arch/arm/mach-tegra/board-whistler-baseband.c
index eb50fb2f8237..b602cd3f44c1 100644
--- a/arch/arm/mach-tegra/board-whistler-baseband.c
+++ b/arch/arm/mach-tegra/board-whistler-baseband.c
@@ -26,8 +26,9 @@
static void baseband_phy_init(void);
static void baseband_phy_on(void);
-static void baseband_phy_off(void);
-
+static void baseband_pre_phy_off(void);
+static void baseband_post_phy_off(void);
+static bool ap2mdm_ack_gpio_off = false;
static struct wake_lock mdm_wake_lock;
static struct gpio modem_gpios[] = {
@@ -58,13 +59,14 @@ static __initdata struct tegra_pingroup_config whistler_null_ulpi_pinmux[] = {
static struct tegra_usb_phy_platform_ops ulpi_null_plat_ops = {
.init = baseband_phy_init,
- .pre_phy_off = baseband_phy_off,
+ .pre_phy_off = baseband_pre_phy_off,
+ .post_phy_off = baseband_post_phy_off,
.post_phy_on = baseband_phy_on,
};
static struct tegra_usb_platform_data tegra_ehci2_ulpi_null_pdata = {
.port_otg = false,
- .has_hostpc = true,
+ .has_hostpc = false,
.phy_intf = TEGRA_USB_PHY_INTF_ULPI_NULL,
.op_mode = TEGRA_USB_OPMODE_HOST,
.u_data.host = {
@@ -105,6 +107,15 @@ static irqreturn_t mdm_start_thread(int irq, void *data)
return IRQ_HANDLED;
}
+static inline void null_phy_set_tristate(bool enable)
+{
+ int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
+
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
+}
+
static void baseband_phy_init(void)
{
static bool phy_init;
@@ -117,18 +128,51 @@ static void baseband_phy_init(void)
pr_info("%s\n", __func__);
}
-static void baseband_phy_off(void)
+static void baseband_pre_phy_off(void)
{
/* set AP2MDM_ACK2 high */
gpio_set_value(AP2MDM_ACK2, 1);
+ ap2mdm_ack_gpio_off = true;
+}
+
+static void baseband_post_phy_off(void)
+{
+ null_phy_set_tristate(true);
}
-static void baseband_phy_on (void)
+static void baseband_phy_on(void)
{
- /* set AP2MDM_ACK2 low */
- gpio_set_value(AP2MDM_ACK2, 0);
+ if (ap2mdm_ack_gpio_off) {
+
+ /* driving linestate using GPIO */
+ gpio_set_value(ULPI_D0, 0);
+ gpio_set_value(ULPI_D1, 0);
+
+ /* driving DIR high */
+ gpio_set_value(ULPI_DIR, 1);
+
+ /* remove ULPI tristate */
+ null_phy_set_tristate(false);
+
+ gpio_set_value(AP2MDM_ACK2, 0);
+
+ if (gpio_is_valid(MDM2AP_ACK2)) {
+ int retry = 20000;
+ while (retry) {
+ /* poll phy_restore_gpio high */
+ if (gpio_get_value(MDM2AP_ACK2))
+ break;
+ retry--;
+ }
+
+ if (retry == 0)
+ pr_info("phy_restore_gpio timeout\n");
+ }
+ ap2mdm_ack_gpio_off = false;
+ }
}
+
static void baseband_start(void)
{
/*
diff --git a/arch/arm/mach-tegra/board-whistler-power.c b/arch/arm/mach-tegra/board-whistler-power.c
index a0eb6686b0db..67663252e0d9 100644
--- a/arch/arm/mach-tegra/board-whistler-power.c
+++ b/arch/arm/mach-tegra/board-whistler-power.c
@@ -31,7 +31,6 @@
#include "gpio-names.h"
#include "fuse.h"
#include "pm.h"
-#include "wakeups-t2.h"
#include "board.h"
#define PMC_CTRL 0x0
diff --git a/arch/arm/mach-tegra/board-whistler-sdhci.c b/arch/arm/mach-tegra/board-whistler-sdhci.c
index 2d2a9c8c01f8..491688052858 100644
--- a/arch/arm/mach-tegra/board-whistler-sdhci.c
+++ b/arch/arm/mach-tegra/board-whistler-sdhci.c
@@ -168,6 +168,7 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = {
.embedded_sdio = &embedded_sdio_data1,
#endif
.built_in = 0,
+ .ocr_mask = MMC_OCR_1V8_MASK,
},
#ifndef CONFIG_MMC_EMBEDDED_SDIO
.pm_flags = MMC_PM_KEEP_POWER,
diff --git a/arch/arm/mach-tegra/board-whistler.c b/arch/arm/mach-tegra/board-whistler.c
index 874ef18900e7..6156c8a8e51d 100644
--- a/arch/arm/mach-tegra/board-whistler.c
+++ b/arch/arm/mach-tegra/board-whistler.c
@@ -441,7 +441,7 @@ static struct tegra_usb_platform_data tegra_udc_pdata = {
.phy_intf = TEGRA_USB_PHY_INTF_UTMI,
.op_mode = TEGRA_USB_OPMODE_DEVICE,
.u_data.dev = {
- .vbus_pmu_irq = 0,
+ .vbus_pmu_irq = MAX8907C_INT_BASE + MAX8907C_IRQ_VCHG_DC_R,
.vbus_gpio = -1,
.charging_supported = false,
.remote_wakeup_supported = false,
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index 86a0b1364b3d..5b9ac4f770a2 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -230,7 +230,8 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
cpu = tegra_get_slowest_cpu_n();
if (cpu < nr_cpu_ids) {
up = false;
- } else if (!is_lp_cluster() && !no_lp) {
+ } else if (!is_lp_cluster() && !no_lp &&
+ !pm_qos_request(PM_QOS_MIN_ONLINE_CPUS)) {
if(!clk_set_parent(cpu_clk, cpu_lp_clk)) {
hp_stats_update(CONFIG_NR_CPUS, true);
hp_stats_update(0, false);
@@ -299,10 +300,10 @@ static int min_cpus_notify(struct notifier_block *nb, unsigned long n, void *p)
{
mutex_lock(tegra3_cpu_lock);
- if ((n >= 2) && is_lp_cluster()) {
+ if ((n >= 1) && is_lp_cluster()) {
/* make sure cpu rate is within g-mode range before switching */
- unsigned int speed = max(
- tegra_getspeed(0), clk_get_min_rate(cpu_g_clk) / 1000);
+ unsigned int speed = max((unsigned long)tegra_getspeed(0),
+ clk_get_min_rate(cpu_g_clk) / 1000);
tegra_update_cpu_speed(speed);
if (!clk_set_parent(cpu_clk, cpu_g_clk)) {
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 377772ff4291..44afd0e63fe4 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -1166,6 +1166,11 @@ struct platform_device tegra_pcm_device = {
.id = -1,
};
+struct platform_device tegra_tdm_pcm_device = {
+ .name = "tegra-tdm-pcm-audio",
+ .id = -1,
+};
+
static struct resource w1_resources[] = {
[0] = {
.start = INT_OWR,
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 97a0c53ccfce..3d0734d1c688 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -69,6 +69,7 @@ extern struct platform_device spdif_dit_device;
extern struct platform_device bluetooth_dit_device;
extern struct platform_device baseband_dit_device;
extern struct platform_device tegra_pcm_device;
+extern struct platform_device tegra_tdm_pcm_device;
extern struct platform_device tegra_w1_device;
extern struct platform_device tegra_udc_device;
extern struct platform_device tegra_ehci1_device;
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index 71f1be769507..87af9441c28c 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -551,7 +551,6 @@ struct tegra_dc_pwm_params {
void tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg);
int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc, u8 *pdata, u8 data_len);
-void tegra_dc_host_trigger(struct tegra_dc *dc);
int tegra_dc_update_csc(struct tegra_dc *dc, int win_index);
diff --git a/arch/arm/mach-tegra/include/mach/sdhci.h b/arch/arm/mach-tegra/include/mach/sdhci.h
index 5dc8cd2ddf76..e307506eb40b 100644
--- a/arch/arm/mach-tegra/include/mach/sdhci.h
+++ b/arch/arm/mach-tegra/include/mach/sdhci.h
@@ -20,6 +20,14 @@
#include <linux/mmc/host.h>
#include <asm/mach/mmc.h>
+/*
+ * MMC_OCR_1V8_MASK will be used in board sdhci file
+ * Example for cardhu it will be used in board-cardhu-sdhci.c
+ * for built_in = 0 devices enabling ocr_mask to MMC_OCR_1V8_MASK
+ * sets the voltage to 1.8V
+ */
+#define MMC_OCR_1V8_MASK 0x8
+
struct tegra_sdhci_platform_data {
int cd_gpio;
int wp_gpio;
diff --git a/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
index 6bea4e50b915..501d815b881b 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
@@ -35,6 +35,7 @@ struct codec_info_s {
char *cpu_dai_name;
char *codec_name; /* Name of the Codec Driver */
char *name; /* Name of the Codec-Dai-Link */
+ char *pcm_driver; /* Name of the PCM driver */
enum i2s_data_format i2s_format;
int master; /* Codec is Master or Slave */
/* TDM format setttings */
diff --git a/arch/arm/mach-tegra/p852/board-p852.h b/arch/arm/mach-tegra/p852/board-p852.h
index bb43febb4a2c..8e8f1444029c 100644
--- a/arch/arm/mach-tegra/p852/board-p852.h
+++ b/arch/arm/mach-tegra/p852/board-p852.h
@@ -55,7 +55,6 @@
#include "../pm.h"
#include "../devices.h"
#include "../gpio-names.h"
-#include "../wakeups-t2.h"
#define P852_SKU3 0x030000UL
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 80a9a121f193..68e0fda385ae 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -36,6 +36,8 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/workqueue.h>
+#include <linux/gpio.h>
#include <asm/sizes.h>
#include <asm/mach/pci.h>
@@ -308,6 +310,7 @@ struct tegra_pcie_port {
char mem_space_name[16];
char prefetch_space_name[20];
struct resource res[3];
+ struct pci_bus* bus;
};
struct tegra_pcie_info {
@@ -319,6 +322,7 @@ struct tegra_pcie_info {
struct resource res_mmio;
int power_rails_enabled;
int pcie_power_enabled;
+ struct work_struct hotplug_detect;
struct regulator *regulator_hvdd;
struct regulator *regulator_pexio;
@@ -333,8 +337,6 @@ struct tegra_pcie_info {
#define pmc_readl(reg) \
__raw_readl((u32)reg_pmc_base + (reg))
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
static struct tegra_pcie_info tegra_pcie = {
.res_mmio = {
.name = "PCI IO",
@@ -620,6 +622,31 @@ static struct hw_pci tegra_pcie_hw = {
.map_irq = tegra_pcie_map_irq,
};
+static void work_hotplug_handler(struct work_struct *work)
+{
+ struct tegra_pcie_info *pcie_driver =
+ container_of(work, struct tegra_pcie_info, hotplug_detect);
+ int val;
+
+ if (pcie_driver->plat_data->gpio == -1)
+ return;
+ val = gpio_get_value(pcie_driver->plat_data->gpio);
+ if (val == 0) {
+ pr_info("Pcie Dock Connected but hotplug functionality not supported yet\n");
+ } else {
+ struct pci_dev *dev = NULL;
+
+ pr_info("Pcie Dock DisConnected\n");
+ for_each_pci_dev(dev)
+ pci_stop_bus_device(dev);
+ }
+}
+
+static irqreturn_t gpio_pcie_detect_isr(int irq, void *arg)
+{
+ schedule_work(&tegra_pcie.hotplug_detect);
+ return IRQ_HANDLED;
+}
static irqreturn_t tegra_pcie_isr(int irq, void *arg)
{
@@ -1169,6 +1196,8 @@ static int tegra_pcie_init(void)
pcibios_min_mem = 0x03000000ul;
pcibios_min_io = 0x10000000ul;
#endif
+
+ INIT_WORK(&tegra_pcie.hotplug_detect, work_hotplug_handler);
err = tegra_pcie_get_resources();
if (err)
return err;
@@ -1184,11 +1213,36 @@ static int tegra_pcie_init(void)
}
tegra_pcie.pcie_power_enabled = 1;
+ if (tegra_pcie.plat_data->use_dock_detect) {
+ unsigned int irq;
+
+ pr_info("acquiring dock_detect = %d\n",
+ tegra_pcie.plat_data->gpio);
+ gpio_request(tegra_pcie.plat_data->gpio, "pcie_dock_detect");
+ gpio_direction_input(tegra_pcie.plat_data->gpio);
+ irq = gpio_to_irq(tegra_pcie.plat_data->gpio);
+ if (irq < 0) {
+ pr_err("Unable to get irq number for dock_detect\n");
+ goto err_irq;
+ }
+ err = request_irq(irq,
+ gpio_pcie_detect_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "pcie_dock_detect",
+ (void *)tegra_pcie.plat_data);
+ if (err < 0) {
+ pr_err("Unable to claim irq number for dock_detect\n");
+ goto err_irq;
+ }
+ }
+
if (tegra_pcie.num_ports)
pci_common_init(&tegra_pcie_hw);
else
err = tegra_pcie_power_off();
+err_irq:
+
return err;
}
diff --git a/arch/arm/mach-tegra/pinmux-t3-tables.c b/arch/arm/mach-tegra/pinmux-t3-tables.c
index 5e50fede625d..90dbf757b909 100644
--- a/arch/arm/mach-tegra/pinmux-t3-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t3-tables.c
@@ -3,7 +3,7 @@
*
* Common pinmux configurations for Tegra 3 SoCs
*
- * Copyright (C) 2010-2011 NVIDIA Corporation
+ * Copyright (C) 2010-2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,11 +64,16 @@
const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
DEFAULT_DRIVE_PINGROUP(AO1, 0x868),
DEFAULT_DRIVE_PINGROUP(AO2, 0x86c),
- DEFAULT_DRIVE_PINGROUP(AT1, 0x870),
- DEFAULT_DRIVE_PINGROUP(AT2, 0x874),
- DEFAULT_DRIVE_PINGROUP(AT3, 0x878),
- DEFAULT_DRIVE_PINGROUP(AT4, 0x87c),
- DEFAULT_DRIVE_PINGROUP(AT5, 0x880),
+ SET_DRIVE_PINGROUP(AT1, 0x870, 14, 0x1f, 19, 0x1f,
+ 24, 0x3, 28, 0x3),
+ SET_DRIVE_PINGROUP(AT2, 0x874, 14, 0x1f, 19, 0x1f,
+ 24, 0x3, 28, 0x3),
+ SET_DRIVE_PINGROUP(AT3, 0x878, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
+ SET_DRIVE_PINGROUP(AT4, 0x87c, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
+ SET_DRIVE_PINGROUP(AT5, 0x880, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
DEFAULT_DRIVE_PINGROUP(CDEV1, 0x884),
DEFAULT_DRIVE_PINGROUP(CDEV2, 0x888),
DEFAULT_DRIVE_PINGROUP(CSUS, 0x88c),
@@ -101,10 +106,14 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
24, 0xf, 28, 0xf),
SET_DRIVE_PINGROUP(GMD, 0x90c, 14, 0x1f, 19, 0x1f,
24, 0xf, 28, 0xf),
- DEFAULT_DRIVE_PINGROUP(GME, 0x910),
- DEFAULT_DRIVE_PINGROUP(GMF, 0x914),
- DEFAULT_DRIVE_PINGROUP(GMG, 0x918),
- DEFAULT_DRIVE_PINGROUP(GMH, 0x91c),
+ SET_DRIVE_PINGROUP(GME, 0x910, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
+ SET_DRIVE_PINGROUP(GMF, 0x914, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
+ SET_DRIVE_PINGROUP(GMG, 0x918, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
+ SET_DRIVE_PINGROUP(GMH, 0x91c, 14, 0x1f, 19, 0x1f,
+ 28, 0x3, 30, 0x3),
DEFAULT_DRIVE_PINGROUP(OWR, 0x920),
DEFAULT_DRIVE_PINGROUP(UAD, 0x924),
DEFAULT_DRIVE_PINGROUP(GPV, 0x928),
diff --git a/arch/arm/mach-tegra/pm-irq.c b/arch/arm/mach-tegra/pm-irq.c
index 57d21361ca14..9b205f86f8b9 100644
--- a/arch/arm/mach-tegra/pm-irq.c
+++ b/arch/arm/mach-tegra/pm-irq.c
@@ -29,6 +29,7 @@
#include <mach/iomap.h>
#include "pm-irq.h"
+#include "wakeups.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
diff --git a/arch/arm/mach-tegra/pm-irq.h b/arch/arm/mach-tegra/pm-irq.h
index 8e87b4bba246..639bfe9c4cc9 100644
--- a/arch/arm/mach-tegra/pm-irq.h
+++ b/arch/arm/mach-tegra/pm-irq.h
@@ -22,8 +22,6 @@
int tegra_pm_irq_set_wake(int irq, int enable);
int tegra_pm_irq_set_wake_type(int irq, int flow_type);
bool tegra_pm_irq_lp0_allowed(void);
-int tegra_irq_to_wake(int irq);
-int tegra_wake_to_irq(int wake);
#else
static inline int tegra_pm_irq_set_wake_type(int irq, int flow_type)
{
diff --git a/arch/arm/mach-tegra/tegra2_usb_phy.c b/arch/arm/mach-tegra/tegra2_usb_phy.c
index 819721c49a29..7b18333cc77c 100644
--- a/arch/arm/mach-tegra/tegra2_usb_phy.c
+++ b/arch/arm/mach-tegra/tegra2_usb_phy.c
@@ -1545,6 +1545,189 @@ static int ulpi_link_phy_resume(struct tegra_usb_phy *phy)
return status;
}
+
+static int ulpi_null_phy_power_off(struct tegra_usb_phy *phy)
+{
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+
+ if (!phy->phy_clk_on) {
+ DBG("%s(%d) inst:[%d] phy clk is already off\n", __func__,
+ __LINE__, phy->inst);
+ return 0;
+ }
+
+ phy->phy_clk_on = false;
+ phy->hw_accessible = false;
+
+ return 0;
+}
+
+static int ulpi_null_phy_irq(struct tegra_usb_phy *phy)
+{
+ usb_phy_fence_read(phy);
+ return IRQ_HANDLED;
+}
+
+static int ulpi_null_phy_lp0_resume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ val = readl(base + USB_USBCMD);
+ val |= USB_USBCMD_RESET;
+ writel(val, base + USB_USBCMD);
+
+ if (usb_phy_reg_status_wait(base + USB_USBCMD,
+ USB_USBCMD_RESET, 0, 2500) < 0) {
+ pr_err("%s: timeout waiting for reset\n", __func__);
+ }
+
+ val = readl(base + USB_USBMODE_REG_OFFSET);
+ val &= ~USB_USBMODE_MASK;
+ val |= USB_USBMODE_HOST;
+ writel(val, base + USB_USBMODE_REG_OFFSET);
+
+ val = readl(base + USB_USBCMD);
+ val |= USB_USBCMD_RS;
+ writel(val, base + USB_USBCMD);
+ if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS,
+ USB_USBCMD_RS, 2000)) {
+ pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Enable Port Power */
+ val = readl(base + USB_PORTSC);
+ val |= USB_PORTSC_PP;
+ writel(val, base + USB_PORTSC);
+ udelay(10);
+
+ /* disable ULPI pinmux bypass */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val &= ~ULPI_OUTPUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ return 0;
+}
+
+static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+ struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi;
+ static bool cold_boot = true;
+
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ if (phy->phy_clk_on) {
+ DBG("%s(%d) inst:[%d] phy clk is already On\n", __func__,
+ __LINE__, phy->inst);
+ return 0;
+ }
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= UHSIC_RESET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= ULPI_PHY_ENABLE;
+ writel(val, base + USB_SUSP_CTRL);
+ udelay(10);
+
+ /* set timming parameters */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_SHADOW_CLK_LOOPBACK_EN;
+ val |= ULPI_SHADOW_CLK_SEL;
+ val |= ULPI_LBK_PAD_EN;
+ val |= ULPI_SHADOW_CLK_DELAY(config->shadow_clk_delay);
+ val |= ULPI_CLOCK_OUT_DELAY(config->clock_out_delay);
+ val |= ULPI_LBK_PAD_E_INPUT_OR;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ writel(0, base + ULPI_TIMING_CTRL_1);
+ udelay(10);
+
+ /* start internal 60MHz clock */
+ val = readl(base + ULPIS2S_CTRL);
+ val |= ULPIS2S_ENA;
+ val |= ULPIS2S_SUPPORT_DISCONNECT;
+ val |= ULPIS2S_SPARE((phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) ? 3 : 1);
+ val |= ULPIS2S_PLLU_MASTER_BLASTER60;
+ writel(val, base + ULPIS2S_CTRL);
+
+ /* select ULPI_CORE_CLK_SEL to SHADOW_CLK */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_CORE_CLK_SEL;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+ udelay(10);
+
+ /* enable ULPI null phy clock - can't set the trimmers before this */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_CLK_OUT_ENA;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+ udelay(10);
+
+ if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
+ USB_PHY_CLK_VALID, 2500)) {
+ pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* set ULPI trimmers */
+ ulpi_set_trimmer(phy);
+
+ if (cold_boot) {
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_CLK_PADOUT_ENA;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+ cold_boot = false;
+ } else {
+ if (!readl(base + USB_ASYNCLISTADDR))
+ ulpi_null_phy_lp0_resume(phy);
+ }
+ udelay(10);
+
+ phy->phy_clk_on = true;
+ phy->hw_accessible = true;
+
+ return 0;
+}
+
+
+static int ulpi_null_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
+{
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+
+ usb_phy_wait_for_sof(phy);
+ return 0;
+}
+
+static int ulpi_null_phy_resume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ if (!readl(base + USB_ASYNCLISTADDR)) {
+ /* enable ULPI CLK output pad */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_CLK_PADOUT_ENA;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ /* enable ULPI pinmux bypass */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_OUTPUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+ udelay(5);
+ }
+
+ return 0;
+}
+
+
+
static struct tegra_usb_phy_ops utmi_phy_ops = {
.open = utmi_phy_open,
.close = utmi_phy_close,
@@ -1578,7 +1761,14 @@ static struct tegra_usb_phy_ops ulpi_link_phy_ops = {
.resume = ulpi_link_phy_resume,
};
-static struct tegra_usb_phy_ops ulpi_null_phy_ops;
+static struct tegra_usb_phy_ops ulpi_null_phy_ops = {
+ .irq = ulpi_null_phy_irq,
+ .power_on = ulpi_null_phy_power_on,
+ .power_off = ulpi_null_phy_power_off,
+ .pre_resume = ulpi_null_phy_pre_resume,
+ .resume = ulpi_null_phy_resume,
+};
+
static struct tegra_usb_phy_ops icusb_phy_ops;
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index 657a6cfd6510..f36bfa774577 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/tegra3_dvfs.c
*
- * Copyright (C) 2010-2011 NVIDIA Corporation.
+ * Copyright (C) 2010-2012, NVIDIA Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -783,8 +783,6 @@ static void core_cap_update(void)
static void core_cap_enable(bool enable)
{
- int i;
-
if (enable)
tegra3_core_cap.refcnt++;
else if (tegra3_core_cap.refcnt)
diff --git a/arch/arm/mach-tegra/tegra3_usb_phy.c b/arch/arm/mach-tegra/tegra3_usb_phy.c
index 5b3e51974d3b..8ada255cad55 100644
--- a/arch/arm/mach-tegra/tegra3_usb_phy.c
+++ b/arch/arm/mach-tegra/tegra3_usb_phy.c
@@ -888,6 +888,7 @@ static void uhsic_powerup_pmc_wake_detect(struct tegra_usb_phy *phy)
mdelay(1);
}
+#ifdef KERNEL_WARNING
static void usb_phy_power_down_pmc(void)
{
unsigned long val;
@@ -931,6 +932,7 @@ static void usb_phy_power_down_pmc(void)
UHSIC_MASTER_ENABLE_P0;
writel(val, pmc_base + PMC_SLEEP_CFG);
}
+#endif
static int usb_phy_bringup_host_controller(struct tegra_usb_phy *phy)
{
@@ -1142,10 +1144,6 @@ static void utmi_phy_close(struct tegra_usb_phy *phy)
writel(val, base + USB_SUSP_CTRL);
}
- val = readl(base + USB_PORTSC);
- val |= USB_PORTSC_WKCN;
- writel(val, base + USB_PORTSC);
-
clk_put(phy->utmi_pad_clk);
}
@@ -1341,16 +1339,20 @@ static int utmi_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
unsigned int inst = phy->inst;
DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
-
- val = (readl(base + HOSTPC1_DEVLC) >> 25) &
+ phy->port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
HOSTPC1_DEVLC_PSPD_MASK;
- if (val == USB_PHY_PORT_SPEED_HIGH) {
+
+ if (phy->port_speed == USB_PHY_PORT_SPEED_HIGH) {
/* Disable interrupts */
writel(0, base + USB_USBINTR);
/* Clear the run bit to stop SOFs - 2LS WAR */
val = readl(base + USB_USBCMD);
val &= ~USB_USBCMD_RS;
writel(val, base + USB_USBCMD);
+ if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_HCH,
+ USB_USBSTS_HCH, 2000)) {
+ pr_err("%s: timeout waiting for USB_USBSTS_HCH\n", __func__);
+ }
}
val = readl(pmc_base + PMC_SLEEP_CFG);
@@ -1388,6 +1390,21 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
val |= UTMIP_PD_CHRG;
writel(val, base + UTMIP_BAT_CHRG_CFG0);
} else {
+ phy->port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
+ HOSTPC1_DEVLC_PSPD_MASK;
+
+ /* Disable interrupts */
+ writel(0, base + USB_USBINTR);
+
+ /* Clear the run bit to stop SOFs - 2LS WAR */
+ val = readl(base + USB_USBCMD);
+ val &= ~USB_USBCMD_RS;
+ writel(val, base + USB_USBCMD);
+
+ if (usb_phy_reg_status_wait(base + USB_USBSTS, USB_USBSTS_HCH,
+ USB_USBSTS_HCH, 2000)) {
+ pr_err("%s: timeout waiting for USB_USBSTS_HCH\n", __func__);
+ }
utmip_setup_pmc_wake_detect(phy);
}
@@ -1409,9 +1426,6 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
utmi_phy_pad_power_off(phy);
- phy->port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
- HOSTPC1_DEVLC_PSPD_MASK;
-
if (phy->pdata->u_data.host.hot_plug) {
bool enable_hotplug = true;
/* if it is OTG port then make sure to enable hot-plug feature
@@ -1776,7 +1790,7 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
- utmip_powerup_pmc_wake_detect(phy);
+ uhsic_powerup_pmc_wake_detect(phy);
if (phy->phy_clk_on) {
DBG("%s(%d) inst:[%d] phy clk is already On\n",
@@ -1897,7 +1911,7 @@ static int uhsic_phy_power_off(struct tegra_usb_phy *phy)
writel(val, base + USB_SUSP_CTRL);
udelay(30);
- utmip_powerdown_pmc_wake_detect(phy);
+ uhsic_powerdown_pmc_wake_detect(phy);
phy->phy_clk_on = false;
phy->hw_accessible = false;
@@ -2153,31 +2167,6 @@ static void ulpi_set_host(void __iomem *base)
}
-
-static inline void null_phy_set_tristate(bool enable)
-{
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
- int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
- DBG("%s(%d) inst:[%s] FIXME enable pin group +++\n", __func__,
- __LINE__, enable ? "TRISTATE" : "NORMAL");
-
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA0, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA1, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA2, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA3, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA4, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA5, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA6, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DATA7, tristate);
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_NXT, tristate);
-
- if (enable)
- tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, tristate);
-#endif
-
-}
-
-
static int ulpi_null_phy_power_off(struct tegra_usb_phy *phy)
{
DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
@@ -2188,8 +2177,6 @@ static int ulpi_null_phy_power_off(struct tegra_usb_phy *phy)
return 0;
}
- null_phy_set_tristate(true);
-
phy->phy_clk_on = false;
phy->hw_accessible = false;
@@ -2241,6 +2228,52 @@ static int ulpi_null_phy_cmd_reset(struct tegra_usb_phy *phy)
return 0;
}
+static int ulpi_null_phy_lp0_resume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ ulpi_null_phy_init(phy);
+
+ val = readl(base + USB_USBCMD);
+ val |= USB_CMD_RESET;
+ writel(val, base + USB_USBCMD);
+
+ if (usb_phy_reg_status_wait(base + USB_USBCMD,
+ USB_CMD_RESET, 0, 2500) < 0) {
+ pr_err("%s: timeout waiting for reset\n", __func__);
+ }
+
+ val = readl(base + USB_USBMODE);
+ val &= ~USB_USBMODE_MASK;
+ val |= USB_USBMODE_HOST;
+ writel(val, base + USB_USBMODE);
+
+ ulpi_null_phy_cmd_reset(phy);
+
+ val = readl(base + USB_USBCMD);
+ val |= USB_USBCMD_RS;
+ writel(val, base + USB_USBCMD);
+ if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS,
+ USB_USBCMD_RS, 2000)) {
+ pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Enable Port Power */
+ val = readl(base + USB_PORTSC);
+ val |= USB_PORTSC_PP;
+ writel(val, base + USB_PORTSC);
+ udelay(10);
+
+ /* disable ULPI pinmux bypass */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val &= ~ULPI_OUTPUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ return 0;
+}
+
static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy)
{
unsigned long val;
@@ -2334,6 +2367,9 @@ static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy)
val |= ULPI_CLK_PADOUT_ENA;
writel(val, base + ULPI_TIMING_CTRL_0);
cold_boot = false;
+ } else {
+ if (!readl(base + USB_ASYNCLISTADDR))
+ ulpi_null_phy_lp0_resume(phy);
}
udelay(10);
@@ -2352,6 +2388,32 @@ int ulpi_null_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
return 0;
}
+static int ulpi_null_phy_resume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ if (!readl(base + USB_ASYNCLISTADDR)) {
+ /* enable ULPI CLK output pad */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_CLK_PADOUT_ENA;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ /* enable ULPI pinmux bypass */
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_OUTPUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+ udelay(5);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ /* remove DIR tristate */
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_ULPI_DIR, TEGRA_TRI_NORMAL);
+#endif
+ }
+ return 0;
+}
+
+
+
static struct tegra_usb_phy_ops utmi_phy_ops = {
.open = utmi_phy_open,
.close = utmi_phy_close,
@@ -2382,6 +2444,7 @@ static struct tegra_usb_phy_ops ulpi_null_phy_ops = {
.power_on = ulpi_null_phy_power_on,
.power_off = ulpi_null_phy_power_off,
.pre_resume = ulpi_null_phy_pre_resume,
+ .resume = ulpi_null_phy_resume,
.reset = ulpi_null_phy_cmd_reset,
};
diff --git a/arch/arm/mach-tegra/tegra_usb_phy.h b/arch/arm/mach-tegra/tegra_usb_phy.h
index 36b88db94f52..0375b5aac812 100644
--- a/arch/arm/mach-tegra/tegra_usb_phy.h
+++ b/arch/arm/mach-tegra/tegra_usb_phy.h
@@ -89,6 +89,7 @@ struct tegra_usb_phy {
void __iomem *regs;
int inst;
bool phy_clk_on;
+ bool ctrl_clk_on; /* used only for pmu irq */
bool phy_power_on;
bool remote_wakeup;
bool hw_accessible;
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index 6f568fd2cd29..bfb9abae2c94 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -131,15 +131,25 @@ int tegra_usb_phy_init_ops(struct tegra_usb_phy *phy)
static irqreturn_t usb_phy_dev_vbus_pmu_irq_thr(int irq, void *pdata)
{
- /* FIXME : Need to enable pmu vbus handling */
+ struct tegra_usb_phy *phy = pdata;
- return IRQ_NONE;
+ /* clk is disabled during phy power off and not here*/
+ if (!phy->ctrl_clk_on) {
+ clk_enable(phy->ctrlr_clk);
+ phy->ctrl_clk_on = true;
+ }
+
+ return IRQ_HANDLED;
}
static void tegra_usb_phy_release_clocks(struct tegra_usb_phy *phy)
{
clk_put(phy->emc_clk);
clk_put(phy->sys_clk);
+ if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST)
+ if (phy->pdata->u_data.host.hot_plug ||
+ phy->pdata->u_data.host.remote_wakeup_supported)
+ clk_disable(phy->ctrlr_clk);
clk_put(phy->ctrlr_clk);
clk_disable(phy->pllu_clk);
clk_put(phy->pllu_clk);
@@ -164,6 +174,11 @@ static int tegra_usb_phy_get_clocks(struct tegra_usb_phy *phy)
goto fail_ctrlr_clk;
}
+ if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST)
+ if (phy->pdata->u_data.host.hot_plug ||
+ phy->pdata->u_data.host.remote_wakeup_supported)
+ clk_enable(phy->ctrlr_clk);
+
phy->sys_clk = clk_get(&phy->pdev->dev, "sclk");
if (IS_ERR(phy->sys_clk)) {
dev_err(&phy->pdev->dev, "Can't get sclk clock\n");
@@ -273,6 +288,8 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct platform_device *pdev)
phy->inst);
goto fail_init;
}
+ } else {
+ clk_enable(phy->ctrlr_clk);
}
} else {
if (phy->pdata->u_data.host.vbus_reg) {
@@ -365,6 +382,8 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
if (phy->pdata->u_data.dev.vbus_pmu_irq)
free_irq(phy->pdata->u_data.dev.vbus_pmu_irq, phy);
+ else
+ clk_disable(phy->ctrlr_clk);
} else {
usb_host_vbus_enable(phy, false);
@@ -379,8 +398,6 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
}
}
- tegra_usb_phy_release_clocks(phy);
-
if (phy->vdd_reg) {
regulator_disable(phy->vdd_reg);
regulator_put(phy->vdd_reg);
@@ -392,6 +409,8 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
if (phy->pdata->ops && phy->pdata->ops->close)
phy->pdata->ops->close();
+ tegra_usb_phy_release_clocks(phy);
+
kfree(phy->pdata);
kfree(phy);
}
@@ -439,7 +458,19 @@ int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
clk_disable(phy->emc_clk);
clk_disable(phy->sys_clk);
- clk_disable(phy->ctrlr_clk);
+ if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) {
+ if (!phy->pdata->u_data.host.hot_plug &&
+ !phy->pdata->u_data.host.remote_wakeup_supported)
+ clk_disable(phy->ctrlr_clk);
+ } else {
+ /* In device mode clock is turned on by pmu irq handler
+ * if pmu irq is not available clocks will not be turned off/on
+ */
+ if (phy->pdata->u_data.dev.vbus_pmu_irq) {
+ clk_disable(phy->ctrlr_clk);
+ phy->ctrl_clk_on = false;
+ }
+ }
phy->phy_power_on = false;
@@ -455,7 +486,20 @@ int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
if (phy->phy_power_on)
return status;
- clk_enable(phy->ctrlr_clk);
+ /* In device mode clock is turned on by pmu irq handler
+ * if pmu irq is not available clocks will not be turned off/on
+ */
+ if (phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) {
+ if (!phy->pdata->u_data.host.hot_plug &&
+ !phy->pdata->u_data.host.remote_wakeup_supported)
+ clk_enable(phy->ctrlr_clk);
+ } else {
+ if (phy->pdata->u_data.dev.vbus_pmu_irq &&
+ !phy->ctrl_clk_on) {
+ clk_enable(phy->ctrlr_clk);
+ phy->ctrl_clk_on = true;
+ }
+ }
clk_enable(phy->sys_clk);
clk_enable(phy->emc_clk);
@@ -506,11 +550,7 @@ int tegra_usb_phy_suspend(struct tegra_usb_phy *phy)
err = phy->ops->suspend(phy);
if (!err && phy->pdata->u_data.host.power_off_on_suspend) {
- if (phy->pdata->ops && phy->pdata->ops->pre_phy_off)
- phy->pdata->ops->pre_phy_off();
- err = phy->ops->power_off(phy);
- if (phy->pdata->ops && phy->pdata->ops->post_phy_off)
- phy->pdata->ops->post_phy_off();
+ tegra_usb_phy_power_off(phy);
}
return err;
@@ -550,11 +590,7 @@ int tegra_usb_phy_resume(struct tegra_usb_phy *phy)
DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
if (phy->pdata->u_data.host.power_off_on_suspend) {
- if (phy->pdata->ops && phy->pdata->ops->pre_phy_on)
- phy->pdata->ops->pre_phy_on();
- err = phy->ops->power_on(phy);
- if (phy->pdata->ops && phy->pdata->ops->post_phy_on)
- phy->pdata->ops->post_phy_on();
+ tegra_usb_phy_power_on(phy);
}
if (!err && phy->ops && phy->ops->resume)
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c
index 7c5d12ac60d4..8079e6820145 100644
--- a/arch/arm/mach-tegra/wakeups-t2.c
+++ b/arch/arm/mach-tegra/wakeups-t2.c
@@ -22,8 +22,9 @@
#include <mach/gpio.h>
#include "gpio-names.h"
+#include "wakeups.h"
-static int tegra_wake_event_irq[] = {
+static int tegra_wake_event_irq_t2[] = {
[0] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5),
[1] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV3),
[2] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1),
@@ -57,55 +58,5 @@ static int tegra_wake_event_irq[] = {
[30] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2),
};
-int tegra_irq_to_wake(int irq)
-{
- int i;
- int wake_irq;
- int search_gpio;
- static int last_wake = -1;
-
- /* Two level wake irq search for gpio based wakeups -
- * 1. check for GPIO irq(based on tegra_wake_event_irq table)
- * e.g. for a board, wake7 based on GPIO PU6 and irq==358 done first
- * 2. check for gpio bank irq assuming search for GPIO irq
- * preceded this search.
- * e.g. in this step check for gpio bank irq GPIO6 irq==119
- */
- for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
- /* return if step 1 matches */
- if (tegra_wake_event_irq[i] == irq) {
- pr_info("Wake%d for irq=%d\n", i, irq);
- last_wake = i;
- return i;
- }
-
- /* step 2 below uses saved last_wake from step 1
- * in previous call */
- search_gpio = irq_to_gpio(
- tegra_wake_event_irq[i]);
- if (search_gpio < 0)
- continue;
- wake_irq = tegra_gpio_get_bank_int_nr(search_gpio);
- if (wake_irq < 0)
- continue;
- if ((last_wake == i) &&
- (wake_irq == irq)) {
- pr_info("gpio bank wake found: wake%d for irq=%d\n",
- i, irq);
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-int tegra_wake_to_irq(int wake)
-{
- if (wake < 0)
- return -EINVAL;
-
- if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
- return -EINVAL;
-
- return tegra_wake_event_irq[wake];
-}
+int *tegra_wake_event_irq = tegra_wake_event_irq_t2;
+unsigned int tegra_wake_event_irq_size = ARRAY_SIZE(tegra_wake_event_irq_t2);
diff --git a/arch/arm/mach-tegra/wakeups-t2.h b/arch/arm/mach-tegra/wakeups-t2.h
index eb193c0aaf9e..955b351a71fa 100644
--- a/arch/arm/mach-tegra/wakeups-t2.h
+++ b/arch/arm/mach-tegra/wakeups-t2.h
@@ -30,36 +30,36 @@
int tegra_irq_to_wake(int irq);
int tegra_wake_to_irq(int wake);
-#define TEGRA_WAKE_GPIO_PO5 (1 << 0)
-#define TEGRA_WAKE_GPIO_PV3 (1 << 1)
-#define TEGRA_WAKE_GPIO_PL1 (1 << 2)
-#define TEGRA_WAKE_GPIO_PB6 (1 << 3)
-#define TEGRA_WAKE_GPIO_PN7 (1 << 4)
-#define TEGRA_WAKE_GPIO_PA0 (1 << 5)
-#define TEGRA_WAKE_GPIO_PU5 (1 << 6)
-#define TEGRA_WAKE_GPIO_PU6 (1 << 7)
-#define TEGRA_WAKE_GPIO_PC7 (1 << 8)
-#define TEGRA_WAKE_GPIO_PS2 (1 << 9)
-#define TEGRA_WAKE_GPIO_PAA1 (1 << 10)
-#define TEGRA_WAKE_GPIO_PW3 (1 << 11)
-#define TEGRA_WAKE_GPIO_PW2 (1 << 12)
-#define TEGRA_WAKE_GPIO_PY6 (1 << 13)
-#define TEGRA_WAKE_GPIO_PV6 (1 << 14)
-#define TEGRA_WAKE_GPIO_PJ7 (1 << 15)
-#define TEGRA_WAKE_RTC_ALARM (1 << 16)
-#define TEGRA_WAKE_KBC_EVENT (1 << 17)
-#define TEGRA_WAKE_PWR_INT (1 << 18)
-#define TEGRA_WAKE_USB1_VBUS (1 << 19)
-#define TEGRA_WAKE_USB3_VBUS (1 << 20)
-#define TEGRA_WAKE_USB1_ID (1 << 21)
-#define TEGRA_WAKE_USB3_ID (1 << 22)
-#define TEGRA_WAKE_GPIO_PI5 (1 << 23)
-#define TEGRA_WAKE_GPIO_PV2 (1 << 24)
-#define TEGRA_WAKE_GPIO_PS4 (1 << 25)
-#define TEGRA_WAKE_GPIO_PS5 (1 << 26)
-#define TEGRA_WAKE_GPIO_PS0 (1 << 27)
-#define TEGRA_WAKE_GPIO_PQ6 (1 << 28)
-#define TEGRA_WAKE_GPIO_PQ7 (1 << 29)
-#define TEGRA_WAKE_GPIO_PN2 (1 << 30)
+#define TEGRA_WAKE_GPIO_PO5 0
+#define TEGRA_WAKE_GPIO_PV3 1
+#define TEGRA_WAKE_GPIO_PL1 2
+#define TEGRA_WAKE_GPIO_PB6 3
+#define TEGRA_WAKE_GPIO_PN7 4
+#define TEGRA_WAKE_GPIO_PA0 5
+#define TEGRA_WAKE_GPIO_PU5 6
+#define TEGRA_WAKE_GPIO_PU6 7
+#define TEGRA_WAKE_GPIO_PC7 8
+#define TEGRA_WAKE_GPIO_PS2 9
+#define TEGRA_WAKE_GPIO_PAA1 10
+#define TEGRA_WAKE_GPIO_PW3 11
+#define TEGRA_WAKE_GPIO_PW2 12
+#define TEGRA_WAKE_GPIO_PY6 13
+#define TEGRA_WAKE_GPIO_PV6 14
+#define TEGRA_WAKE_GPIO_PJ7 15
+#define TEGRA_WAKE_RTC_ALARM 16
+#define TEGRA_WAKE_KBC_EVENT 17
+#define TEGRA_WAKE_PWR_INT 18
+#define TEGRA_WAKE_USB1_VBUS 19
+#define TEGRA_WAKE_USB3_VBUS 20
+#define TEGRA_WAKE_USB1_ID 21
+#define TEGRA_WAKE_USB3_ID 22
+#define TEGRA_WAKE_GPIO_PI5 23
+#define TEGRA_WAKE_GPIO_PV2 24
+#define TEGRA_WAKE_GPIO_PS4 25
+#define TEGRA_WAKE_GPIO_PS5 26
+#define TEGRA_WAKE_GPIO_PS0 27
+#define TEGRA_WAKE_GPIO_PQ6 28
+#define TEGRA_WAKE_GPIO_PQ7 29
+#define TEGRA_WAKE_GPIO_PN2 30
#endif
diff --git a/arch/arm/mach-tegra/wakeups-t3.c b/arch/arm/mach-tegra/wakeups-t3.c
index 823736204362..33dfb12f7211 100644
--- a/arch/arm/mach-tegra/wakeups-t3.c
+++ b/arch/arm/mach-tegra/wakeups-t3.c
@@ -22,8 +22,9 @@
#include <mach/gpio.h>
#include "gpio-names.h"
+#include "wakeups.h"
-static int tegra_wake_event_irq[] = {
+static int tegra_wake_event_irq_t3[] = {
TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5), /* wake0 */
TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV1), /* wake1 */
TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1), /* wake2 */
@@ -68,55 +69,5 @@ static int tegra_wake_event_irq[] = {
INT_USB3, /* TEGRA_USB3_UTMIP, */ /* wake41 */
};
-int tegra_irq_to_wake(int irq)
-{
- int i;
- int wake_irq;
- int search_gpio;
- static int last_wake = -1;
-
- /* Two level wake irq search for gpio based wakeups -
- * 1. check for GPIO irq(based on tegra_wake_event_irq table)
- * e.g. for a board, wake7 based on GPIO PU6 and irq==390 done first
- * 2. check for gpio bank irq assuming search for GPIO irq
- * preceded this search.
- * e.g. in this step check for gpio bank irq GPIO6 irq==119
- */
- for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
- /* return if step 1 matches */
- if (tegra_wake_event_irq[i] == irq) {
- pr_info("Wake%d for irq=%d\n", i, irq);
- last_wake = i;
- return i;
- }
-
- /* step 2 below uses saved last_wake from step 1
- * in previous call */
- search_gpio = irq_to_gpio(
- tegra_wake_event_irq[i]);
- if (search_gpio < 0)
- continue;
- wake_irq = tegra_gpio_get_bank_int_nr(search_gpio);
- if (wake_irq < 0)
- continue;
- if ((last_wake == i) &&
- (wake_irq == irq)) {
- pr_info("gpio bank wake found: wake%d for irq=%d\n",
- i, irq);
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-int tegra_wake_to_irq(int wake)
-{
- if (wake < 0)
- return -EINVAL;
-
- if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
- return -EINVAL;
-
- return tegra_wake_event_irq[wake];
-}
+int *tegra_wake_event_irq = tegra_wake_event_irq_t3;
+unsigned int tegra_wake_event_irq_size = ARRAY_SIZE(tegra_wake_event_irq_t3);
diff --git a/arch/arm/mach-tegra/wakeups-t3.h b/arch/arm/mach-tegra/wakeups-t3.h
index f811d8939387..6c051270cc93 100644
--- a/arch/arm/mach-tegra/wakeups-t3.h
+++ b/arch/arm/mach-tegra/wakeups-t3.h
@@ -27,45 +27,45 @@
#error "Tegra 3 wakeup sources valid only for CONFIG_ARCH_TEGRA_3x_SOC"
#endif
-#define TEGRA_WAKE_GPIO_PO5 (1ull << 0)
-#define TEGRA_WAKE_GPIO_PV1 (1ull << 1)
-#define TEGRA_WAKE_GPIO_PL1 (1ull << 2)
-#define TEGRA_WAKE_GPIO_PB6 (1ull << 3)
-#define TEGRA_WAKE_GPIO_PN7 (1ull << 4)
-#define TEGRA_WAKE_GPIO_PBB6 (1ull << 5)
-#define TEGRA_WAKE_GPIO_PU5 (1ull << 6)
-#define TEGRA_WAKE_GPIO_PU6 (1ull << 7)
-#define TEGRA_WAKE_GPIO_PC7 (1ull << 8)
-#define TEGRA_WAKE_GPIO_PS2 (1ull << 9)
-#define TEGRA_WAKE_GPIO_PAA1 (1ull << 10)
-#define TEGRA_WAKE_GPIO_PW3 (1ull << 11)
-#define TEGRA_WAKE_GPIO_PW2 (1ull << 12)
-#define TEGRA_WAKE_GPIO_PY6 (1ull << 13)
-#define TEGRA_WAKE_GPIO_PDD3 (1ull << 14)
-#define TEGRA_WAKE_GPIO_PJ2 (1ull << 15)
-#define TEGRA_WAKE_RTC_ALARM (1ull << 16)
-#define TEGRA_WAKE_KBC_EVENT (1ull << 17)
-#define TEGRA_WAKE_PWR_INT (1ull << 18)
-#define TEGRA_WAKE_USB1_VBUS (1ull << 19)
-#define TEGRA_WAKE_USB2_VBUS (1ull << 20)
-#define TEGRA_WAKE_USB1_ID (1ull << 21)
-#define TEGRA_WAKE_USB2_ID (1ull << 22)
-#define TEGRA_WAKE_GPIO_PI5 (1ull << 23)
-#define TEGRA_WAKE_GPIO_PV0 (1ull << 24)
-#define TEGRA_WAKE_GPIO_PS4 (1ull << 25)
-#define TEGRA_WAKE_GPIO_PS5 (1ull << 26)
-#define TEGRA_WAKE_GPIO_PS0 (1ull << 27)
-#define TEGRA_WAKE_GPIO_PS6 (1ull << 28)
-#define TEGRA_WAKE_GPIO_PS7 (1ull << 29)
-#define TEGRA_WAKE_GPIO_PN2 (1ull << 30)
+#define TEGRA_WAKE_GPIO_PO5 0
+#define TEGRA_WAKE_GPIO_PV1 1
+#define TEGRA_WAKE_GPIO_PL1 2
+#define TEGRA_WAKE_GPIO_PB6 3
+#define TEGRA_WAKE_GPIO_PN7 4
+#define TEGRA_WAKE_GPIO_PBB6 5
+#define TEGRA_WAKE_GPIO_PU5 6
+#define TEGRA_WAKE_GPIO_PU6 7
+#define TEGRA_WAKE_GPIO_PC7 8
+#define TEGRA_WAKE_GPIO_PS2 9
+#define TEGRA_WAKE_GPIO_PAA1 10
+#define TEGRA_WAKE_GPIO_PW3 11
+#define TEGRA_WAKE_GPIO_PW2 12
+#define TEGRA_WAKE_GPIO_PY6 13
+#define TEGRA_WAKE_GPIO_PDD3 14
+#define TEGRA_WAKE_GPIO_PJ2 15
+#define TEGRA_WAKE_RTC_ALARM 16
+#define TEGRA_WAKE_KBC_EVENT 17
+#define TEGRA_WAKE_PWR_INT 18
+#define TEGRA_WAKE_USB1_VBUS 19
+#define TEGRA_WAKE_USB2_VBUS 20
+#define TEGRA_WAKE_USB1_ID 21
+#define TEGRA_WAKE_USB2_ID 22
+#define TEGRA_WAKE_GPIO_PI5 23
+#define TEGRA_WAKE_GPIO_PV0 24
+#define TEGRA_WAKE_GPIO_PS4 25
+#define TEGRA_WAKE_GPIO_PS5 26
+#define TEGRA_WAKE_GPIO_PS0 27
+#define TEGRA_WAKE_GPIO_PS6 28
+#define TEGRA_WAKE_GPIO_PS7 29
+#define TEGRA_WAKE_GPIO_PN2 30
/* bit 31 is unused */
-#define TEGRA_WAKE_GPIO_PO4 (1ull << 32)
-#define TEGRA_WAKE_GPIO_PJ0 (1ull << 33)
-#define TEGRA_WAKE_GPIO_PK2 (1ull << 34)
-#define TEGRA_WAKE_GPIO_PI6 (1ull << 35)
-#define TEGRA_WAKE_GPIO_PBB1 (1ull << 36)
-#define TEGRA_WAKE_USB3_ID (1ull << 37)
-#define TEGRA_WAKE_USB3_VBUS (1ull << 38)
+#define TEGRA_WAKE_GPIO_PO4 32
+#define TEGRA_WAKE_GPIO_PJ0 33
+#define TEGRA_WAKE_GPIO_PK2 34
+#define TEGRA_WAKE_GPIO_PI6 35
+#define TEGRA_WAKE_GPIO_PBB1 36
+#define TEGRA_WAKE_USB3_ID 37
+#define TEGRA_WAKE_USB3_VBUS 38
#endif
diff --git a/arch/arm/mach-tegra/wakeups.c b/arch/arm/mach-tegra/wakeups.c
new file mode 100644
index 000000000000..d53563cf22ba
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+
+#include "gpio-names.h"
+#include "wakeups.h"
+
+extern int *tegra_wake_event_irq;
+extern unsigned int tegra_wake_event_irq_size;
+
+int tegra_irq_to_wake(int irq)
+{
+ int i;
+ int wake_irq;
+ int search_gpio;
+ static int last_wake = -1;
+
+ /* Two level wake irq search for gpio based wakeups -
+ * 1. check for GPIO irq(based on tegra_wake_event_irq table)
+ * e.g. for a board, wake7 based on GPIO PU6 and irq==390 done first
+ * 2. check for gpio bank irq assuming search for GPIO irq
+ * preceded this search.
+ * e.g. in this step check for gpio bank irq GPIO6 irq==119
+ */
+ for (i = 0; i < tegra_wake_event_irq_size; i++) {
+ /* return if step 1 matches */
+ if (tegra_wake_event_irq[i] == irq) {
+ pr_info("Wake%d for irq=%d\n", i, irq);
+ last_wake = i;
+ return i;
+ }
+
+ /* step 2 below uses saved last_wake from step 1
+ * in previous call */
+ search_gpio = irq_to_gpio(
+ tegra_wake_event_irq[i]);
+ if (search_gpio < 0)
+ continue;
+ wake_irq = tegra_gpio_get_bank_int_nr(search_gpio);
+ if (wake_irq < 0)
+ continue;
+ if ((last_wake == i) &&
+ (wake_irq == irq)) {
+ pr_info("gpio bank wake found: wake%d for irq=%d\n",
+ i, irq);
+ return i;
+ }
+ }
+
+ return -EINVAL;
+}
+
+int tegra_wake_to_irq(int wake)
+{
+ if (wake < 0)
+ return -EINVAL;
+
+ if (wake >= tegra_wake_event_irq_size)
+ return -EINVAL;
+
+ return tegra_wake_event_irq[wake];
+}
+
diff --git a/arch/arm/mach-tegra/wakeups.h b/arch/arm/mach-tegra/wakeups.h
new file mode 100644
index 000000000000..ab113649d534
--- /dev/null
+++ b/arch/arm/mach-tegra/wakeups.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __WAKEUPS_H_
+#define __WAKEUPS_H_
+
+/*
+ * given irq number returns wake source index or negative value for error
+ */
+int tegra_irq_to_wake(int irq);
+/*
+ * given wake source index, returns irq number or negative value for error
+ */
+int tegra_wake_to_irq(int wake);
+
+#endif /* end __WAKEUPS_H_ */