diff options
Diffstat (limited to 'arch/arm/mach-tegra/pm-irq.c')
-rw-r--r-- | arch/arm/mach-tegra/pm-irq.c | 46 |
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; |