summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBitan Biswas <bbiswas@nvidia.com>2013-05-14 20:42:49 +0530
committerRiham Haidar <rhaidar@nvidia.com>2013-06-11 11:13:19 -0700
commit75e8f1f218422013055c4fbcf96ceab059c933a7 (patch)
tree695d4c7487b39d0fe768642db08073f43cdd3c70
parenta9610dbfdfd8dac35d38183349d4db1193c0425f (diff)
ARM: tegra: USB1 VBUS and ID ANY wake level support
This change enables wakeup from USB cable connect and disconnect for both device(VBUS) and host(ID) cables. - board platform data used to enable the implementation - chip specific wakeups source file added with new API needed to detect VBUS and ID cable connect state - chip specific API exposed to return the USB1_VBUS and USB1_ID wake indices bug 1286802 Change-Id: I59cfca82a907d33190a5bc92f33de5986fada43f Signed-off-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-on: http://git-master/r/231918 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/Makefile6
-rw-r--r--arch/arm/mach-tegra/board.h18
-rw-r--r--arch/arm/mach-tegra/pm-irq.c268
-rw-r--r--arch/arm/mach-tegra/pm-irq.h38
-rw-r--r--arch/arm/mach-tegra/pm.h21
-rw-r--r--arch/arm/mach-tegra/wakeups-t11x.c66
-rw-r--r--arch/arm/mach-tegra/wakeups-t11x.h16
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.c27
-rw-r--r--arch/arm/mach-tegra/wakeups-t2.h16
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.c27
-rw-r--r--arch/arm/mach-tegra/wakeups-t3.h16
11 files changed, 442 insertions, 77 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 53be7130d97c..0cc916537520 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -28,7 +28,7 @@ obj-y += common-t2.o
obj-y += pm-t2.o
obj-y += sleep-t2.o
obj-y += timer-t2.o
-obj-y += wakeups-t2.o
+obj-$(CONFIG_PM_SLEEP) += wakeups-t2.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_PM_SLEEP) += cpuidle-t2.o
endif
@@ -40,9 +40,9 @@ obj-$(CONFIG_DEBUG_FS) += clocks_stats.o
obj-y += timer-t3.o
obj-y += tegra_core_volt_cap.o
ifeq ($(CONFIG_ARCH_TEGRA_3x_SOC),y)
-obj-y += wakeups-t3.o
+obj-$(CONFIG_PM_SLEEP) += wakeups-t3.o
else
-obj-y += wakeups-t11x.o
+obj-$(CONFIG_PM_SLEEP) += wakeups-t11x.o
endif
ifeq ($(CONFIG_CPU_IDLE),y)
ifeq ($(CONFIG_ARCH_TEGRA_3x_SOC),y)
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 59981f09c033..9bacda51ceb8 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -8,15 +8,17 @@
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
*
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * 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 that 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.
+ * 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 __MACH_TEGRA_BOARD_H
@@ -216,4 +218,6 @@ int tegra_get_pmic_rst_reason(void);
#ifdef CONFIG_ANDROID
bool get_androidboot_mode_charger(void);
#endif
+extern void tegra_set_usb_vbus_internal_wake(bool enable);
+extern void tegra_set_usb_id_internal_wake(bool enable);
#endif
diff --git a/arch/arm/mach-tegra/pm-irq.c b/arch/arm/mach-tegra/pm-irq.c
index 5e698ab4397b..a320f4ca7475 100644
--- a/arch/arm/mach-tegra/pm-irq.c
+++ b/arch/arm/mach-tegra/pm-irq.c
@@ -4,17 +4,22 @@
* Author:
* Colin Cross <ccross@android.com>
*
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * This program is distributed in the hope that 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.
+ * 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/kobject.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -45,6 +50,13 @@
#define PMC_MAX_WAKE_COUNT 64
+/* wake level/polarity constants */
+enum {
+ WAKE_LEVEL_LO = 0,
+ WAKE_LEVEL_HI,
+ WAKE_LEVEL_ANY
+};
+
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
static u64 tegra_lp0_wake_enb;
@@ -54,6 +66,27 @@ static int tegra_prevent_lp0;
static unsigned int tegra_wake_irq_count[PMC_MAX_WAKE_COUNT];
+/*
+ * List of internal any wake sources returned from chip-specific
+ * implementation of function tegra_get_internal_any_wake_list
+ * any_wake_count - size of list
+ * any_wake - array of wake index
+ * remote_usb_wake_index - index of USB1 remote wake source
+ */
+static u8 any_wake_count; /* non-zero value indicates any wake support */
+static u8 *any_wake;
+static u8 remote_usb_wake_index;
+
+#ifdef DEBUG_WAKE_SOURCE
+/*
+ * define DEBUG_WAKE_SOURCE to enable -
+ * Code that uses sysfs nodes to test LP0 wake for wake sources
+ * with option to select wake levels: lo-0, hi-1, any-2
+ */
+static long test_wake_src_index = -1;
+static long test_wake_src_polarity;
+#endif
+
static bool debug_lp0;
module_param(debug_lp0, bool, S_IRUGO | S_IWUSR);
@@ -132,9 +165,21 @@ static inline u64 read_pmc_sw_wake_status(void)
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
reg = readl(pmc + PMC_SW_WAKE_STATUS);
+#ifdef DEBUG_WAKE_SOURCE
+ pr_info("PMC_SW_WAKE_STATUS[31-0] level=0x%x\n",
+ (u32)(reg & 0xFFFFFFFF));
+#endif
#else
reg = __raw_readl(pmc + PMC_SW_WAKE_STATUS);
+#ifdef DEBUG_WAKE_SOURCE
+ pr_info("PMC_SW_WAKE_STATUS[31-0] level=0x%x\n",
+ (u32)(reg & 0xFFFFFFFF));
+#endif
reg |= ((u64)readl(pmc + PMC_SW_WAKE2_STATUS)) << 32;
+#ifdef DEBUG_WAKE_SOURCE
+ pr_info("PMC_SW_WAKE_STATUS[63-32] level=0x%x\n",
+ (u32)((reg >> 32) & 0xFFFFFFFF));
+#endif
#endif
return reg;
}
@@ -149,9 +194,8 @@ static inline void clear_pmc_sw_wake_status(void)
int tegra_pm_irq_set_wake(int wake, int enable)
{
- if (wake < 0) {
+ if (wake < 0)
return -EINVAL;
- }
if (enable) {
tegra_lp0_wake_enb |= 1ull << wake;
@@ -237,6 +281,73 @@ static void tegra_pm_irq_syscore_resume(void)
#endif
}
+#ifdef DEBUG_WAKE_SOURCE
+static void print_val64(char *name, u64 val)
+{
+ pr_info("%s[31-0]=%#x\n", name, (u32)(val & 0xFFFFFFFF));
+ pr_info("%s[63-32]=%#x\n", name, (u32)((val >> 32) & 0xFFFFFFFF));
+}
+#endif
+
+/*
+ * static variables - tegra_usb_vbus_internal_wake and
+ * tegra_usb_id_internal_wake are false without need to initialize
+ */
+static bool tegra_usb_vbus_internal_wake; /* support for internal vbus wake */
+static bool tegra_usb_id_internal_wake; /* support for internal id wake */
+void tegra_set_usb_vbus_internal_wake(bool enable)
+{
+ tegra_usb_vbus_internal_wake = enable;
+}
+
+void tegra_set_usb_id_internal_wake(bool enable)
+{
+ tegra_usb_id_internal_wake = enable;
+}
+
+/* handles special case of first time wake for VBUS and ID
+ * We see that in one cable connect mode the wakeup
+ * works when wake level is toggled
+ */
+static void handle_first_wake(u64 *wak_lvl, u64 *wak_enb, u32 indx)
+{
+ u32 lvl_tmp;
+ bool is_vbus_connected;
+ bool is_id_connected;
+ int err;
+
+ /* function to be called only if internal any wake supported */
+ if (!any_wake_count)
+ return;
+
+ err = get_vbus_id_cable_connect_state(&is_vbus_connected,
+ &is_id_connected);
+ if (err)
+ return;
+
+ lvl_tmp = (*wak_lvl & (1ULL << indx)) ? 1 : 0;
+#ifdef DEBUG_WAKE_SOURCE
+ pr_info("%s: wake_src_index=%d, level=%d\n", __func__, indx, lvl_tmp);
+#endif
+ /* ID cable disconnected LP0 entry case */
+ /* or VBUS cable connected LP0 entry case */
+ if ((tegra_usb_id_internal_wake && (indx ==
+ *(any_wake + ANY_WAKE_INDEX_ID)) && !is_id_connected) ||
+ (tegra_usb_vbus_internal_wake && (indx ==
+ *(any_wake + ANY_WAKE_INDEX_VBUS)) &&
+ is_vbus_connected)) {
+ lvl_tmp = !lvl_tmp;
+ /* toggle wake level for these cases */
+ *wak_lvl = *wak_lvl & ~(1ULL << indx);
+ *wak_lvl |= (lvl_tmp << indx);
+ }
+ /* disable WAKE39 as we see repeated wakeups due to WAKE39 */
+ if (is_id_connected)
+ *wak_enb |= (1ULL << remote_usb_wake_index);
+ else
+ *wak_enb &= ~(1ULL << remote_usb_wake_index);
+}
+
/* set up lp0 wake sources */
static int tegra_pm_irq_syscore_suspend(void)
{
@@ -245,6 +356,7 @@ static int tegra_pm_irq_syscore_suspend(void)
u64 lvl;
u64 wake_level;
u64 wake_enb;
+ int j;
clear_pmc_sw_wake_status();
@@ -283,6 +395,75 @@ static int tegra_pm_irq_syscore_suspend(void)
pmc_32kwritel(temp, PMC_WAKE2_STATUS);
#endif
+#ifdef DEBUG_WAKE_SOURCE
+ if ((test_wake_src_index > 0) &&
+ (test_wake_src_index < PMC_MAX_WAKE_COUNT)) {
+ pr_info("%s: wake_src_index=%ld, should wake with wake level=%d as per sw_wake_status\n",
+ __func__, test_wake_src_index,
+ (status & (1ULL << test_wake_src_index)) ? 1 : 0);
+ pr_info("%s: wake_src_index=%ld, desired polarity=%ld, old level=%d\n",
+ __func__, test_wake_src_index, test_wake_src_polarity,
+ ((wake_level & (1ULL << test_wake_src_index)) ? 1 : 0));
+ }
+ print_val64("wake_level", wake_level);
+#endif
+
+ if (!tegra_usb_vbus_internal_wake && !tegra_usb_id_internal_wake) {
+ if (any_wake_count) {
+ /* ensure that WAKE19 and WAKE21 are disabled */
+ wake_enb &= ~(1ULL << *(any_wake +
+ ANY_WAKE_INDEX_VBUS));
+ wake_enb &= ~(1ULL << *(any_wake +
+ ANY_WAKE_INDEX_ID));
+ }
+#ifndef DEBUG_WAKE_SOURCE
+ goto skip_usb_any_wake;
+#endif
+ }
+ /*
+ * ANY polarity for USB1 VBUS and USB1 ID wake is implemented
+ * These are handled as special case here
+ */
+
+ for (j = 0; j < any_wake_count; j++) {
+ if (wake_enb && (1ULL << *(any_wake + j))) {
+#ifdef DEBUG_WAKE_SOURCE
+ pr_info("%s: wake level ANY sources: WAKE%d=%s\n",
+ __func__, *(any_wake + j),
+ ((wake_enb && (1ULL << *(any_wake + j))) ?
+ "enabled" : "disabled"));
+#endif
+ handle_first_wake(&wake_level, &wake_enb,
+ *(any_wake + j));
+ }
+ }
+
+#ifdef DEBUG_WAKE_SOURCE
+ /*
+ * Test code uses sysfs nodes to test LP0 wake for wake sources
+ * with option to select wake levels: lo-0, hi-1, any-2
+ *
+ * moved down in this function so that assumed wake
+ * levels for WAKE19 and WAKE21
+ * could be overridden for debug
+ */
+ if ((test_wake_src_index > 0) &&
+ (test_wake_src_index < PMC_MAX_WAKE_COUNT)) {
+ if (test_wake_src_polarity == WAKE_LEVEL_HI) {
+ pr_info("Test wake level HI\n");
+ wake_level |= (1ULL << test_wake_src_index);
+ } else if (test_wake_src_polarity == WAKE_LEVEL_LO) {
+ pr_info("Test wake level LO\n");
+ wake_level &= ~(1ULL << test_wake_src_index);
+ } else if (test_wake_src_polarity == WAKE_LEVEL_ANY) {
+ pr_info("Test wake level ANY\n");
+ handle_first_wake(&wake_level, &wake_enb,
+ test_wake_src_index);
+ }
+ }
+#else
+skip_usb_any_wake:
+#endif
write_pmc_wake_level(wake_level);
write_pmc_wake_mask(wake_enb);
@@ -303,6 +484,54 @@ static int tegra_pm_irq_syscore_init(void)
}
subsys_initcall(tegra_pm_irq_syscore_init);
+#ifdef DEBUG_WAKE_SOURCE
+static ssize_t wake_index_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%ld\n", test_wake_src_index);
+}
+
+static ssize_t wake_index_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ if (kstrtol(buf, 10, &test_wake_src_index)) {
+ pr_err("\n file: %s, line=%d return %s() ", __FILE__,
+ __LINE__, __func__);
+ return -EINVAL;
+ }
+ return n;
+}
+
+static struct kobj_attribute wake_index_data_attribute =
+ __ATTR(wake_src_index, 0644, wake_index_show, wake_index_store);
+
+static ssize_t wak_polarity_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%ld\n", test_wake_src_polarity);
+}
+
+static ssize_t wak_polarity_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ if (kstrtol(buf, 10, &test_wake_src_polarity)) {
+ pr_err("\n file: %s, line=%d return %s() ", __FILE__,
+ __LINE__, __func__);
+ return -EINVAL;
+ }
+ return n;
+}
+
+static struct kobj_attribute wake_polarity_data_attribute =
+ __ATTR(wake_src_polarity, 0644, wak_polarity_show, wak_polarity_store);
+
+static struct kobject *wake_data_kobj;
+#endif
+
#ifdef CONFIG_DEBUG_FS
static int tegra_pm_irq_debug_show(struct seq_file *s, void *data)
{
@@ -354,6 +583,27 @@ static int __init tegra_pm_irq_debug_init(void)
return -ENOMEM;
}
+#ifdef DEBUG_WAKE_SOURCE
+ wake_data_kobj = kobject_create_and_add("wakedata", kernel_kobj);
+ if (wake_data_kobj) {
+ if (sysfs_create_file(wake_data_kobj, \
+ &wake_index_data_attribute.attr))
+ pr_err("%s: sysfs_create_file wake_index failed!\n",
+ __func__);
+ if (sysfs_create_file(wake_data_kobj, \
+ &wake_polarity_data_attribute.attr))
+ pr_err("%s: sysfs_create_file wake_polarity failed!\n",
+ __func__);
+ }
+#endif
+
+ /*
+ * tegra list of any wake sources needed in functions
+ * accessing any_wake list
+ */
+ tegra_get_internal_any_wake_list(&any_wake_count, &any_wake,
+ &remote_usb_wake_index);
+
return 0;
}
diff --git a/arch/arm/mach-tegra/pm-irq.h b/arch/arm/mach-tegra/pm-irq.h
index 10e00e9e513b..cbb7450ec2f2 100644
--- a/arch/arm/mach-tegra/pm-irq.h
+++ b/arch/arm/mach-tegra/pm-irq.h
@@ -4,15 +4,19 @@
* Author:
* Colin Cross <ccross@android.com>
*
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * This program is distributed in the hope that 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.
+ * 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 _MACH_TERA_PM_IRQ_H_
@@ -46,4 +50,24 @@ static inline int tegra_disable_wake_source(int wake)
}
#endif
void tegra_set_usb_wake_source(void);
+
+/* tegra internal any polarity wake sources */
+enum {
+ ANY_WAKE_INDEX_VBUS = 0,
+ ANY_WAKE_INDEX_ID
+};
+
+/* get chip specific list of internal any polarity wake sources */
+void tegra_get_internal_any_wake_list(u8 *wake_count, u8 **any_wake,
+ u8 *remote_usb_wak_index);
+
+/*
+ * is_vbus_connected - true when VBUS cable is connected
+ * is_id_connected - true when ID cable is connected
+ * returns error if failed to read the status for a chip
+ * or if the API is not supported
+ */
+int get_vbus_id_cable_connect_state(bool *is_vbus_connected,
+ bool *is_id_connected);
+
#endif
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 0ba8fcfe0481..24062bb367dd 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -2,20 +2,23 @@
* arch/arm/mach-tegra/include/mach/pm.h
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@google.com>
*
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * Copyright (c) 2010-2013, 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 that 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.
+ * 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/>.
*/
@@ -81,6 +84,8 @@ struct tegra_suspend_platform_data {
unsigned long min_residency_ncpu_fast;
unsigned long min_residency_crail;
#endif
+ bool usb_vbus_internal_wake; /* support for internal vbus wake */
+ bool usb_id_internal_wake; /* support for internal id wake */
};
/* clears io dpd settings before kernel code */
diff --git a/arch/arm/mach-tegra/wakeups-t11x.c b/arch/arm/mach-tegra/wakeups-t11x.c
index 84f8b8afb037..43a0bdf150ab 100644
--- a/arch/arm/mach-tegra/wakeups-t11x.c
+++ b/arch/arm/mach-tegra/wakeups-t11x.c
@@ -1,15 +1,17 @@
/*
* Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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 that it will be useful, but WITHOUT
+ * 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>
@@ -23,6 +25,17 @@
#include "board.h"
#include "tegra-board-id.h"
#include "gpio-names.h"
+#include "pm-irq.h"
+
+/* Tegra USB1 wake source index */
+#define USB1_VBUS_WAKE 19
+#define USB1_ID_WAKE 21
+#define USB1_REM_WAKE 39
+
+/* constants for USB1 wake sources - VBUS and ID */
+#define USB1_IF_USB_PHY_VBUS_SENSORS_0 0x408
+#define VBUS_WAKEUP_STS_BIT 10
+#define ID_STS_BIT 2
static int tegra_gpio_wakes[] = {
TEGRA_GPIO_PO5, /* wake0 */
@@ -150,6 +163,49 @@ static int tegra_wake_event_irq[] = {
static int last_gpio = -1;
+/* USB1 VBUS and ID wake sources are handled as special case
+ * Note: SD card detect is an ANY wake source but is
+ * mostly a GPIO which can handle any edge wakeup.
+ */
+static u8 any_wake_t11x[] = {
+ /* DO NOT EDIT this list */
+ [ANY_WAKE_INDEX_VBUS] = USB1_VBUS_WAKE,
+ [ANY_WAKE_INDEX_ID] = USB1_ID_WAKE,
+};
+
+void tegra_get_internal_any_wake_list(u8 *wake_count, u8 **any_wake,
+ u8 *remote_usb)
+{
+ *wake_count = ARRAY_SIZE(any_wake_t11x);
+ *any_wake = any_wake_t11x;
+ *remote_usb = USB1_REM_WAKE;
+}
+
+/* Needed on dalmore today hence exposed this API */
+int get_vbus_id_cable_connect_state(bool *is_vbus_connected,
+ bool *is_id_connected)
+{
+ static void __iomem *usb1_base = IO_ADDRESS(TEGRA_USB_BASE);
+ u32 reg;
+
+ reg = readl(usb1_base + USB1_IF_USB_PHY_VBUS_SENSORS_0);
+
+ /* ID bit when 0 - ID cable connected */
+ *is_id_connected = (reg & (1 << ID_STS_BIT)) ? false : true;
+
+ /*
+ * VBUS_WAKEUP_STS_BIT is also set when ID is connected
+ * and we are supplying VBUS, hence below conditional assignment
+ */
+ if (*is_id_connected)
+ *is_vbus_connected = false;
+ else
+ /* VBUS bit when 1 - VBUS cable connected */
+ *is_vbus_connected = (reg & (1 << VBUS_WAKEUP_STS_BIT)) ?
+ true : false;
+ return 0;
+}
+
int tegra_gpio_to_wake(int gpio)
{
int i;
diff --git a/arch/arm/mach-tegra/wakeups-t11x.h b/arch/arm/mach-tegra/wakeups-t11x.h
index 8a604f78ba5d..e61fa362d61d 100644
--- a/arch/arm/mach-tegra/wakeups-t11x.h
+++ b/arch/arm/mach-tegra/wakeups-t11x.h
@@ -3,21 +3,19 @@
*
* Declarations of Tegra 11x LP0 wakeup sources
*
- * Copyright (c) 2013, NVIDIA Corporation.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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 that it will be useful, but WITHOUT
+ * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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 __MACH_TEGRA_WAKEUPS_T11X_H
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c
index 94de69cfb8f0..df7f65cfef49 100644
--- a/arch/arm/mach-tegra/wakeups-t2.c
+++ b/arch/arm/mach-tegra/wakeups-t2.c
@@ -1,15 +1,19 @@
/*
* Copyright (c) 2011, Google, Inc.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
- * This program is distributed in the hope that it will be useful, but WITHOUT
+ * 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>
@@ -22,6 +26,7 @@
#include <mach/irqs.h>
#include "gpio-names.h"
+#include "pm-irq.h"
/* TODO: We could populate the other table from this one at runtime
* instead of always searching twice */
@@ -95,6 +100,18 @@ static int tegra_wake_event_irq[] = {
static int last_gpio = -1;
+inline void tegra_get_internal_any_wake_list(u8 *wake_count,
+ u8 **any_wake, u8 *remote_usb_index)
+{
+ *wake_count = 0;
+}
+
+inline int get_vbus_id_cable_connect_state(bool *is_vbus_connected,
+ bool *is_id_connected)
+{
+ return -EIO;
+}
+
int tegra_gpio_to_wake(int gpio)
{
int i;
diff --git a/arch/arm/mach-tegra/wakeups-t2.h b/arch/arm/mach-tegra/wakeups-t2.h
index 142d4c76558b..0a521396ed2b 100644
--- a/arch/arm/mach-tegra/wakeups-t2.h
+++ b/arch/arm/mach-tegra/wakeups-t2.h
@@ -3,21 +3,19 @@
*
* Declarations of Tegra 2 LP0 wakeup sources
*
- * Copyright (c) 2010, NVIDIA Corporation.
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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 that it will be useful, but WITHOUT
+ * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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 __MACH_TEGRA_WAKEUPS_T2_H
diff --git a/arch/arm/mach-tegra/wakeups-t3.c b/arch/arm/mach-tegra/wakeups-t3.c
index 0bb854c71dc8..3f3e0ae88e7e 100644
--- a/arch/arm/mach-tegra/wakeups-t3.c
+++ b/arch/arm/mach-tegra/wakeups-t3.c
@@ -1,15 +1,17 @@
/*
- * Copyright (c) 2011-2012, NVIDIA Corporation.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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 that it will be useful, but WITHOUT
+ * 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>
@@ -22,6 +24,7 @@
#include <mach/gpio-tegra.h>
#include "gpio-names.h"
+#include "pm-irq.h"
static int tegra_gpio_wakes[] = {
TEGRA_GPIO_PO5, /* wake0 */
@@ -116,6 +119,18 @@ static int tegra_wake_event_irq[] = {
static int last_gpio = -1;
+inline void tegra_get_internal_any_wake_list(u8 *wake_count,
+ u8 **any_wake, u8 *remote_usb_index)
+{
+ *wake_count = 0;
+}
+
+inline int get_vbus_id_cable_connect_state(bool *is_vbus_connected,
+ bool *is_id_connected)
+{
+ return -EIO;
+}
+
int tegra_gpio_to_wake(int gpio)
{
int i;
diff --git a/arch/arm/mach-tegra/wakeups-t3.h b/arch/arm/mach-tegra/wakeups-t3.h
index 6c051270cc93..6c56698a4399 100644
--- a/arch/arm/mach-tegra/wakeups-t3.h
+++ b/arch/arm/mach-tegra/wakeups-t3.h
@@ -3,21 +3,19 @@
*
* Declarations of Tegra 3 LP0 wakeup sources
*
- * Copyright (c) 2010, NVIDIA Corporation.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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 that it will be useful, but WITHOUT
+ * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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 __MACH_TEGRA_WAKEUPS_T3_H