ARM: tegra: USB1 VBUS and ID ANY wake level support
Bitan Biswas [Tue, 14 May 2013 15:12:49 +0000 (20:12 +0530)]
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

Moved dummy implementation of USB wake support APIs from chip-specific
source into common file

bug 1286802
bug 1314875

Change-Id: I59cfca82a907d33190a5bc92f33de5986fada43f
Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-on: http://git-master/r/231918
(cherry picked from commit 75e8f1f218422013055c4fbcf96ceab059c933a7)
Reviewed-on: http://git-master/r/241033
(cherry picked from commit 3f65b627372c37b4726084bec1129b9b2dabfe4f)

Change-Id: Iae4db0cec2dbee6feef229b308b2b86340affd17
Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-on: http://git-master/r/242383
(cherry picked from commit ba1bb5314fc5d877ab3bcd4e4530501e4f604dd4)
Reviewed-on: http://git-master/r/243438
(cherry picked from commit 7beaa748094e754c0bf7bd5f946c9a314949d2b9)
Reviewed-on: http://git-master/r/247106
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

13 files changed:
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/pm-irq.c
arch/arm/mach-tegra/pm-irq.h
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/wakeups-t11x.c
arch/arm/mach-tegra/wakeups-t11x.h
arch/arm/mach-tegra/wakeups-t14x.h
arch/arm/mach-tegra/wakeups-t2.c
arch/arm/mach-tegra/wakeups-t2.h
arch/arm/mach-tegra/wakeups-t3.c
arch/arm/mach-tegra/wakeups-t3.h

index 6552e39..83cc352 100644 (file)
@@ -586,6 +586,16 @@ config TEGRA_WAKEUP_MONITOR
          send out wakeup source and uevents which indicate suspend_prepare and
          post_suspend.
 
+config TEGRA_INTERNAL_USB_CABLE_WAKE_SUPPORT
+       bool "Enable Tegra internal USB cable wake support"
+       depends on PM_SLEEP
+       default n
+       help
+         Enables Tegra suspend wakeup with USB cable through Tegra
+         integrated hardware. Enabled for selected Tegra chipsets.
+         This feature allows wakeup from suspend using either
+         device or host type USB cable.
+
 config TEGRA_BB_XMM_POWER
        bool "Enable power driver for XMM modem"
        default n
index 0a2a136..768e765 100644 (file)
@@ -26,7 +26,7 @@ obj-y                                   += common-t2.o
 obj-y                                   += pm-t2.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += sleep-t20.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
@@ -38,16 +38,16 @@ 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
 endif
 ifeq ($(CONFIG_ARCH_TEGRA_14x_SOC),y)
-obj-y                                   += wakeups-t14x.o
+obj-$(CONFIG_PM_SLEEP)                  += wakeups-t14x.o
 endif
 ifeq ($(CONFIG_ARCH_TEGRA_11x_SOC),y)
-obj-y                                   += wakeups-t11x.o
+obj-$(CONFIG_PM_SLEEP)                  += wakeups-t11x.o
 endif
 ifeq ($(CONFIG_ARCH_TEGRA_12x_SOC),y)
-obj-y                                  += wakeups-t12x.o
+obj-$(CONFIG_PM_SLEEP)                 += wakeups-t12x.o
 endif
 
 ifeq ($(CONFIG_CPU_IDLE),y)
index 7b8ba72..43ee6da 100644 (file)
@@ -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
@@ -244,4 +246,7 @@ int tegra_get_cvb_alignment_uV(void);
 int tegra_soc_device_init(const char *machine);
 int get_pwr_i2c_clk_rate(void);
 bool is_pmic_wdt_disabled_at_boot(void);
+
+extern void tegra_set_usb_vbus_internal_wake(bool enable);
+extern void tegra_set_usb_id_internal_wake(bool enable);
 #endif
index eee9a03..1e13446 100644 (file)
@@ -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>
 
 #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;
@@ -53,6 +65,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);
 
@@ -131,9 +164,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;
 }
@@ -148,9 +193,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;
@@ -236,6 +280,87 @@ 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
+
+#ifndef CONFIG_TEGRA_INTERNAL_USB_CABLE_WAKE_SUPPORT
+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;
+}
+#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)
 {
@@ -244,6 +369,7 @@ static int tegra_pm_irq_syscore_suspend(void)
        u64 lvl;
        u64 wake_level;
        u64 wake_enb;
+       int j;
 
        clear_pmc_sw_wake_status();
 
@@ -282,6 +408,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);
@@ -302,6 +497,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)
 {
@@ -353,6 +596,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;
 }
 
index 10e00e9..cbb7450 100644 (file)
@@ -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
index 16ba8a4..2474883 100644 (file)
@@ -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/>.
  */
 
 
@@ -82,6 +85,8 @@ struct tegra_suspend_platform_data {
        unsigned long min_residency_crail;
 #endif
        unsigned long min_residency_mc_clk;
+       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 */
index c34d0fd..0aa1204 100644 (file)
@@ -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>
 #include "tegra-board-id.h"
 #include "gpio-names.h"
 #include "iomap.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,51 @@ static int tegra_wake_event_irq[] = {
 
 static int last_gpio = -1;
 
+#ifdef CONFIG_TEGRA_INTERNAL_USB_CABLE_WAKE_SUPPORT
+/* 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;
+}
+#endif
+
 int tegra_gpio_to_wake(int gpio)
 {
        int i;
index 8a604f7..e61fa36 100644 (file)
@@ -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
index 6d21028..5acc7be 100644 (file)
@@ -3,21 +3,19 @@
  *
  * Declarations of Tegra 14x LP0 wakeup sources
  *
- * Copyright (c) 2013, NVIDIA Corporation.
+ * Copyright (c) 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_T14X_H
index 0410c45..308f511 100644 (file)
@@ -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>
index 142d4c7..0a52139 100644 (file)
@@ -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
index d42fe42..e26606a 100644 (file)
@@ -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>
index 6c05127..6c56698 100644 (file)
@@ -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