summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pm-irq.c
diff options
context:
space:
mode:
authorBitan Biswas <bbiswas@nvidia.com>2011-11-15 14:39:02 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:50:16 -0800
commitd42e1fd52adbed786f13bd22dce41fee58146465 (patch)
treefb09283a2f4f41a2dd5f96a7267adcd22d6cf483 /arch/arm/mach-tegra/pm-irq.c
parentc40df1b08359db110ef153d470e3e3da7a5ba575 (diff)
arm: tegra: power: lp0 wake enable modified
GPIO based lp0 wakeup needed to support search for its irq as well as GPIO bank irq in table. This is implemented in this change. lp0 wakeup irq enable using enable_irq_wake needs to be called in specific drivers. Additionally, in some cases wake irq needs to be updated in tegra wakeup table. bug 890309 bug 902114 Change-Id: I983318172ffb020f565763cfe2bb29018223dcd0 Reviewed-on: http://git-master/r/64395 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Rffcadeee341a73f2ea6d62e31d507e9a8dce5a0e
Diffstat (limited to 'arch/arm/mach-tegra/pm-irq.c')
-rw-r--r--arch/arm/mach-tegra/pm-irq.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/arch/arm/mach-tegra/pm-irq.c b/arch/arm/mach-tegra/pm-irq.c
index eda278ccd89c..d66e2cba8546 100644
--- a/arch/arm/mach-tegra/pm-irq.c
+++ b/arch/arm/mach-tegra/pm-irq.c
@@ -43,6 +43,8 @@
#define PMC_SW_WAKE2_STATUS 0x16C
#endif
+#define PMC_MAX_WAKE_COUNT 64
+
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
static u64 tegra_lp0_wake_enb;
@@ -50,7 +52,7 @@ 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[64];
+static unsigned int tegra_wake_irq_count[PMC_MAX_WAKE_COUNT];
static bool debug_lp0;
module_param(debug_lp0, bool, S_IRUGO | S_IWUSR);
@@ -73,8 +75,11 @@ static void pmc_32kwritel(u32 val, unsigned long offs)
static inline void write_pmc_wake_mask(u64 value)
{
+ pr_info("Wake[31-0] enable=0x%x\n", (u32)(value & 0xFFFFFFFF));
writel((u32)value, pmc + 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), pmc + PMC_WAKE2_MASK);
#endif
}
@@ -153,10 +158,13 @@ int tegra_pm_irq_set_wake(int irq, int enable)
return -EINVAL;
}
- if (enable)
+ if (enable) {
tegra_lp0_wake_enb |= 1ull << wake;
- else
+ pr_info("Enabling wake%d\n", wake);
+ } else {
tegra_lp0_wake_enb &= ~(1ull << wake);
+ pr_info("Disabling wake%d\n", wake);
+ }
return 0;
}
@@ -191,29 +199,33 @@ int tegra_pm_irq_set_wake_type(int irq, int flow_type)
}
/* translate lp0 wake sources back into irqs to catch edge triggered wakeups */
-static void tegra_pm_irq_syscore_resume_helper(unsigned long wake_status)
+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);
+ irq = tegra_wake_to_irq(wake + 32 * index);
if (!irq) {
- pr_info("Resume caused by WAKE%d\n", wake);
+ 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, irq);
+ 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,
+ pr_info("Resume caused by WAKE%d, %s\n", (wake + 32 * index),
desc->action->name);
- tegra_wake_irq_count[wake]++;
+ tegra_wake_irq_count[wake + 32 * index]++;
generic_handle_irq(irq);
}
@@ -223,9 +235,12 @@ static void tegra_pm_irq_syscore_resume(void)
{
unsigned long long wake_status = read_pmc_wake_status();
- tegra_pm_irq_syscore_resume_helper((unsigned long)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
- tegra_pm_irq_syscore_resume_helper((unsigned long)(wake_status >> 32));
+ 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
}
@@ -237,6 +252,7 @@ static int tegra_pm_irq_syscore_suspend(void)
u64 lvl;
u64 wake_level;
u64 wake_enb;
+ static bool is_first = true;
clear_pmc_sw_wake_status();
@@ -253,7 +269,11 @@ static int tegra_pm_irq_syscore_suspend(void)
/* flip the wakeup trigger for any-edge triggered pads
* which are currently asserting as wakeups */
- lvl ^= status;
+ if (is_first)
+ is_first = false;
+ else
+ lvl ^= status;
+
lvl &= tegra_lp0_wake_level_any;
wake_level = lvl | tegra_lp0_wake_level;
@@ -294,7 +314,7 @@ static int tegra_pm_irq_debug_show(struct seq_file *s, void *data)
seq_printf(s, "wake irq count name\n");
seq_printf(s, "----------------------\n");
- for (wake = 0; wake < 32; wake++) {
+ for (wake = 0; wake < PMC_MAX_WAKE_COUNT; wake++) {
irq = tegra_wake_to_irq(wake);
if (irq < 0)
continue;