summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pm-irq.c
diff options
context:
space:
mode:
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;