summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorSumit Singh <sumsingh@nvidia.com>2014-03-04 15:34:46 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2014-03-25 06:35:23 -0700
commitee3136bc06a3f7c5b420ac69de52f43fda875964 (patch)
treeabd13fd75e507b32b49455778cee8988d8a9bc22 /drivers/platform
parent6f8dc441dd508a971d4c4c6c60a7bdff4c53dc90 (diff)
ARM: tegra: migrating pm-irq.c to drivers/
Moving pm-irq.c from mach-tegra/ to drivers/platform/tegra/ as codes have to be shared between arm and arm64. Bug 1440573 Change-Id: I91a071eca1fd5c578ae1087b8348e56f417c5bda Signed-off-by: Sumit Singh <sumsingh@nvidia.com> Reviewed-on: http://git-master/r/376552 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/tegra/Makefile2
-rw-r--r--drivers/platform/tegra/pm-irq.c625
-rw-r--r--drivers/platform/tegra/pmc.c11
3 files changed, 625 insertions, 13 deletions
diff --git a/drivers/platform/tegra/Makefile b/drivers/platform/tegra/Makefile
index cabfc5602800..1b5210d8dbc4 100644
--- a/drivers/platform/tegra/Makefile
+++ b/drivers/platform/tegra/Makefile
@@ -13,6 +13,7 @@ endif
endif
obj-y += mc/
+obj-$(CONFIG_PM_SLEEP) += pm-irq.o
obj-y += pmc.o
ifneq ($(CONFIG_ARM64),)
@@ -37,7 +38,6 @@ obj-$(CONFIG_DEBUG_FS) += clocks_stats.o
obj-y += tegra_core_volt_cap.o
obj-$(CONFIG_ARCH_TEGRA_12x_SOC) += wakeups-t12x.o
-obj-$(CONFIG_PM_SLEEP) += pm-irq.o
obj-y += kfuse.o
obj-y += apbio.o
diff --git a/drivers/platform/tegra/pm-irq.c b/drivers/platform/tegra/pm-irq.c
index e3e0606ccecd..c7940d671c7f 100644
--- a/drivers/platform/tegra/pm-irq.c
+++ b/drivers/platform/tegra/pm-irq.c
@@ -1,2 +1,623 @@
-/* Automatically generated file; DO NOT EDIT. */
-#include "../../../arch/arm/mach-tegra/pm-irq.c"
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * Copyright (c) 2012-2014, 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/kobject.h>
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/moduleparam.h>
+#include <linux/seq_file.h>
+#include <linux/syscore_ops.h>
+#include <linux/irqchip/tegra.h>
+#include <linux/tegra-pmc.h>
+
+#define PMC_CTRL 0x0
+#define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
+#define PMC_WAKE_MASK 0xc
+#define PMC_WAKE_LEVEL 0x10
+#define PMC_WAKE_STATUS 0x14
+#define PMC_SW_WAKE_STATUS 0x18
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+#define PMC_WAKE2_MASK 0x160
+#define PMC_WAKE2_LEVEL 0x164
+#define PMC_WAKE2_STATUS 0x168
+#define PMC_SW_WAKE2_STATUS 0x16C
+#endif
+
+#define PMC_MAX_WAKE_COUNT 64
+
+/* wake level/polarity constants */
+enum {
+ WAKE_LEVEL_LO = 0,
+ WAKE_LEVEL_HI,
+ WAKE_LEVEL_ANY
+};
+
+
+static u64 tegra_lp0_wake_enb;
+static u64 tegra_lp0_wake_level;
+static u64 tegra_lp0_wake_level_any;
+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);
+
+static bool warn_prevent_lp0;
+module_param(warn_prevent_lp0, bool, S_IRUGO | S_IWUSR);
+
+bool tegra_pm_irq_lp0_allowed(void)
+{
+ return (tegra_prevent_lp0 == 0);
+}
+
+/* ensures that sufficient time is passed for a register write to
+ * serialize into the 32KHz domain */
+static void pmc_32kwritel(u32 val, unsigned long offs)
+{
+ writel(val, tegra_pmc_base + offs);
+ udelay(130);
+}
+
+static inline void write_pmc_wake_mask(u64 value)
+{
+ pr_info("Wake[31-0] enable=0x%x\n", (u32)(value & 0xFFFFFFFF));
+ writel((u32)value, tegra_pmc_base + PMC_WAKE_MASK);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ pr_info("Tegra3 wake[63-32] enable=0x%x\n", (u32)((value >> 32) &
+ 0xFFFFFFFF));
+ __raw_writel((u32)(value >> 32), tegra_pmc_base + PMC_WAKE2_MASK);
+#endif
+}
+
+static inline u64 read_pmc_wake_level(void)
+{
+ u64 reg;
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ reg = readl(tegra_pmc_base + PMC_WAKE_LEVEL);
+#else
+ reg = __raw_readl(tegra_pmc_base + PMC_WAKE_LEVEL);
+ reg |= ((u64)readl(tegra_pmc_base + PMC_WAKE2_LEVEL)) << 32;
+#endif
+ return reg;
+}
+
+static inline void write_pmc_wake_level(u64 value)
+{
+ pr_info("Wake[31-0] level=0x%x\n", (u32)(value & 0xFFFFFFFF));
+ writel((u32)value, tegra_pmc_base + PMC_WAKE_LEVEL);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ pr_info("Tegra3 wake[63-32] level=0x%x\n", (u32)((value >> 32) &
+ 0xFFFFFFFF));
+ __raw_writel((u32)(value >> 32), tegra_pmc_base + PMC_WAKE2_LEVEL);
+#endif
+}
+
+static inline u64 read_pmc_wake_status(void)
+{
+ u64 reg;
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ reg = readl(tegra_pmc_base + PMC_WAKE_STATUS);
+#else
+ reg = __raw_readl(tegra_pmc_base + PMC_WAKE_STATUS);
+ reg |= ((u64)readl(tegra_pmc_base + PMC_WAKE2_STATUS)) << 32;
+#endif
+ return reg;
+}
+
+u64 tegra_read_pmc_wake_status(void)
+{
+ return read_pmc_wake_status();
+}
+
+static inline u64 read_pmc_sw_wake_status(void)
+{
+ u64 reg;
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ reg = readl(tegra_pmc_base + 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(tegra_pmc_base + 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(tegra_pmc_base + 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;
+}
+
+static inline void clear_pmc_sw_wake_status(void)
+{
+ pmc_32kwritel(0, PMC_SW_WAKE_STATUS);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ pmc_32kwritel(0, PMC_SW_WAKE2_STATUS);
+#endif
+}
+
+int tegra_pm_irq_set_wake(int wake, int enable)
+{
+ if (wake < 0)
+ return -EINVAL;
+
+ if (enable) {
+ tegra_lp0_wake_enb |= 1ull << wake;
+ pr_info("Enabling wake%d\n", wake);
+ } else {
+ tegra_lp0_wake_enb &= ~(1ull << wake);
+ pr_info("Disabling wake%d\n", wake);
+ }
+
+ return 0;
+}
+
+int tegra_pm_irq_set_wake_type(int wake, int flow_type)
+{
+ if (wake < 0)
+ return 0;
+
+ switch (flow_type) {
+ case IRQF_TRIGGER_FALLING:
+ case IRQF_TRIGGER_LOW:
+ tegra_lp0_wake_level &= ~(1ull << wake);
+ tegra_lp0_wake_level_any &= ~(1ull << wake);
+ break;
+ case IRQF_TRIGGER_HIGH:
+ case IRQF_TRIGGER_RISING:
+ tegra_lp0_wake_level |= (1ull << wake);
+ tegra_lp0_wake_level_any &= ~(1ull << wake);
+ break;
+
+ case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING:
+ tegra_lp0_wake_level_any |= (1ull << wake);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* translate lp0 wake sources back into irqs to catch edge triggered wakeups */
+static void tegra_pm_irq_syscore_resume_helper(
+ unsigned long wake_status,
+ unsigned int index)
+{
+ int wake;
+ int irq;
+ struct irq_desc *desc;
+
+ for_each_set_bit(wake, &wake_status, sizeof(wake_status) * 8) {
+ irq = tegra_wake_to_irq(wake + 32 * index);
+ if (!irq) {
+ pr_info("Resume caused by WAKE%d\n",
+ (wake + 32 * index));
+ continue;
+ }
+
+ desc = irq_to_desc(irq);
+ if (!desc || !desc->action || !desc->action->name) {
+ pr_info("Resume caused by WAKE%d, irq %d\n",
+ (wake + 32 * index), irq);
+ continue;
+ }
+
+ pr_info("Resume caused by WAKE%d, %s\n", (wake + 32 * index),
+ desc->action->name);
+
+ tegra_wake_irq_count[wake + 32 * index]++;
+
+ generic_handle_irq(irq);
+ }
+}
+
+static void tegra_pm_irq_syscore_resume(void)
+{
+ unsigned long long wake_status = read_pmc_wake_status();
+
+ pr_info(" legacy wake status=0x%x\n", (u32)wake_status);
+ tegra_pm_irq_syscore_resume_helper((unsigned long)wake_status, 0);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ pr_info(" tegra3 wake status=0x%x\n", (u32)(wake_status >> 32));
+ tegra_pm_irq_syscore_resume_helper(
+ (unsigned long)(wake_status >> 32), 1);
+#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)
+{
+ u32 temp;
+ u64 status;
+ u64 lvl;
+ u64 wake_level;
+ u64 wake_enb;
+ int j;
+
+ clear_pmc_sw_wake_status();
+
+ temp = readl(tegra_pmc_base + PMC_CTRL);
+ temp |= PMC_CTRL_LATCH_WAKEUPS;
+ pmc_32kwritel(temp, PMC_CTRL);
+
+ temp &= ~PMC_CTRL_LATCH_WAKEUPS;
+ pmc_32kwritel(temp, PMC_CTRL);
+
+ status = read_pmc_sw_wake_status();
+
+ lvl = read_pmc_wake_level();
+
+ /* flip the wakeup trigger for any-edge triggered pads
+ * which are currently asserting as wakeups */
+ lvl ^= status;
+
+ lvl &= tegra_lp0_wake_level_any;
+
+ wake_level = lvl | tegra_lp0_wake_level;
+ wake_enb = tegra_lp0_wake_enb;
+
+ if (debug_lp0) {
+ wake_level = lvl ^ status;
+ wake_enb = 0xffffffff;
+ }
+
+ /* Clear PMC Wake Status registers while going to suspend */
+ temp = readl(tegra_pmc_base + PMC_WAKE_STATUS);
+ if (temp)
+ pmc_32kwritel(temp, PMC_WAKE_STATUS);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ temp = readl(tegra_pmc_base + PMC_WAKE2_STATUS);
+ if (temp)
+ 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);
+
+ return 0;
+}
+
+static struct syscore_ops tegra_pm_irq_syscore_ops = {
+ .suspend = tegra_pm_irq_syscore_suspend,
+ .resume = tegra_pm_irq_syscore_resume,
+ .save = tegra_pm_irq_syscore_suspend,
+ .restore = tegra_pm_irq_syscore_resume,
+};
+
+static int tegra_pm_irq_syscore_init(void)
+{
+ register_syscore_ops(&tegra_pm_irq_syscore_ops);
+ return 0;
+}
+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)
+{
+ int wake;
+ int irq;
+ struct irq_desc *desc;
+ const char *irq_name;
+
+ seq_puts(s, "wake irq count name\n");
+ seq_puts(s, "----------------------\n");
+ for (wake = 0; wake < PMC_MAX_WAKE_COUNT; wake++) {
+ irq = tegra_wake_to_irq(wake);
+ if (irq < 0)
+ continue;
+
+ desc = irq_to_desc(irq);
+ if (tegra_wake_irq_count[wake] == 0 && desc->action == NULL)
+ continue;
+
+ irq_name = (desc->action && desc->action->name) ?
+ desc->action->name : "???";
+
+ seq_printf(s, "%4d %3d %5d %s\n",
+ wake, irq, tegra_wake_irq_count[wake], irq_name);
+ }
+ return 0;
+}
+
+static int tegra_pm_irq_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, tegra_pm_irq_debug_show, NULL);
+}
+
+static const struct file_operations tegra_pm_irq_debug_fops = {
+ .open = tegra_pm_irq_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_pm_irq_debug_init(void)
+{
+ struct dentry *d;
+
+ d = debugfs_create_file("wake_irq", S_IRUGO, NULL, NULL,
+ &tegra_pm_irq_debug_fops);
+ if (!d) {
+ pr_err("Failed to create suspend_mode debug file\n");
+ 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;
+}
+
+late_initcall(tegra_pm_irq_debug_init);
+#endif
diff --git a/drivers/platform/tegra/pmc.c b/drivers/platform/tegra/pmc.c
index 0cf55d070a17..4a1c5f4c124f 100644
--- a/drivers/platform/tegra/pmc.c
+++ b/drivers/platform/tegra/pmc.c
@@ -53,7 +53,7 @@ static u8 tegra_cpu_domains[] = {
};
static DEFINE_SPINLOCK(tegra_powergate_lock);
-static void __iomem *tegra_pmc_base;
+void __iomem *tegra_pmc_base;
static bool tegra_pmc_invert_interrupt;
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
static struct clk *tegra_pclk;
@@ -79,21 +79,12 @@ EXPORT_SYMBOL(tegra_get_pm_data);
static inline u32 tegra_pmc_readl(u32 reg)
{
-#if defined(CONFIG_OF)
return readl(tegra_pmc_base + reg);
-#else
- return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
-#endif
}
static inline void tegra_pmc_writel(u32 val, u32 reg)
{
-#if defined(CONFIG_OF)
writel(val, tegra_pmc_base + reg);
-#else
- writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
- return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
-#endif
}
void tegra_pmc_set_dpd_sample()