From 34ce3c349c77e721d1ac0de047eaa4d61682cce0 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Wed, 14 Dec 2011 10:19:59 +0100 Subject: ARM: ux500: prcmu-debug: display interrupt types Adds a debugfs entry named prcmu/interrupts that displays the different kinds of prcmu interrupts. It shows a summary of how many calls to the different mailboxes and for mailbox0 the different events. ST-Ericsson Linux next: - ST-Ericsson ID: 370799 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I049e85c23a8344bf317043f3a532ce764d5e3b39 Signed-off-by: Jonas Aaberg Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42475 --- arch/arm/mach-ux500/include/mach/prcmu-debug.h | 4 + arch/arm/mach-ux500/prcmu-debug.c | 150 +++++++++++++++++++++++++ drivers/mfd/db5500-prcmu.c | 5 + drivers/mfd/db8500-prcmu.c | 8 ++ 4 files changed, 167 insertions(+) diff --git a/arch/arm/mach-ux500/include/mach/prcmu-debug.h b/arch/arm/mach-ux500/include/mach/prcmu-debug.h index df71df49f2d..38f5ad94864 100644 --- a/arch/arm/mach-ux500/include/mach/prcmu-debug.h +++ b/arch/arm/mach-ux500/include/mach/prcmu-debug.h @@ -17,11 +17,15 @@ void prcmu_debug_ddr_opp_log(u8 opp); void prcmu_debug_arm_opp_log(u32 value); void prcmu_debug_dump_data_mem(void); void prcmu_debug_dump_regs(void); +void prcmu_debug_register_interrupt(u32 mailbox); +void prcmu_debug_register_mbox0_event(u32 ev, u32 mask); #else static inline void prcmu_debug_ape_opp_log(u8 opp) {} static inline void prcmu_debug_ddr_opp_log(u8 opp) {} static inline void prcmu_debug_arm_opp_log(u32 value) {} static inline void prcmu_debug_dump_data_mem(void) {} static inline void prcmu_debug_dump_regs(void) {} +static inline void prcmu_debug_register_interrupt(u32 mailbox) {} +static inline void prcmu_debug_register_mbox0_event(u32 ev, u32 mask) {} #endif #endif diff --git a/arch/arm/mach-ux500/prcmu-debug.c b/arch/arm/mach-ux500/prcmu-debug.c index 0fb8025b34a..372756b5301 100644 --- a/arch/arm/mach-ux500/prcmu-debug.c +++ b/arch/arm/mach-ux500/prcmu-debug.c @@ -647,6 +647,137 @@ static int prcmu_debugfs_regs_read(struct seq_file *s, void *p) return 0; } +/* Interrupt debugging */ + +/* There are eight mailboxes */ +#define NUM_MAILBOXES 8 +#define NUM_MAILBOX0_EVENTS 32 +static u32 num_mailbox_interrupts[NUM_MAILBOXES]; +static u32 num_mailbox0_events[NUM_MAILBOX0_EVENTS]; +static u32 num_mailbox0_events_garbage[NUM_MAILBOX0_EVENTS]; + +void prcmu_debug_register_interrupt(u32 mailbox) +{ + if (mailbox < NUM_MAILBOXES) + num_mailbox_interrupts[mailbox]++; +} + +void prcmu_debug_register_mbox0_event(u32 ev, u32 mask) +{ + int i; + + for (i = 0 ; i < NUM_MAILBOX0_EVENTS; i++) + if (ev & (1 << i)) { + if (mask & (1 << i)) + num_mailbox0_events[i]++; + else + num_mailbox0_events_garbage[i]++; + } +} + +static int interrupt_read(struct seq_file *s, void *p) +{ + int i; + char **mbox0names; + + static char *mbox0names_u8500[] = { + "RTC", + "RTT0", + "RTT1", + "HSI0", + "HSI1", + "CA_WAKE", + "USB", + "ABB", + "ABB_FIFO", + "SYSCLK_OK", + "CA_SLEE", + "AC_WAKE_ACK", + "SIDE_TONE_OK", + "ANC_OK", + "SW_ERROR", + "AC_SLEEP_ACK", + NULL, + "ARM", + "HOTMON_LOW", + "HOTMON_HIGH", + "MODEM_SW_RESET_REQ", + NULL, + NULL, + "GPIO0", + "GPIO1", + "GPIO2", + "GPIO3", + "GPIO4", + "GPIO5", + "GPIO6", + "GPIO7", + "GPIO8"}; + static char *mbox0names_u5500[] = { + "RTC", + "RTT0", + "RTT1", + "CD_IRQ", + "SRP_TIM", + "APE_REQ", + "USB", + "ABB", + "LOW_POWER_AUDIO", + "TEMP_SENSOR_LOW", + "ARM", + "AC_WAKE_ACK", + NULL, + "TEMP_SENSOR_HIGH", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "MODEM_SW_RESET_REQ", + NULL, + NULL, + "GPIO0", + "GPIO1", + "GPIO2", + "GPIO3", + "GPIO4", + "GPIO5", + "GPIO6", + "GPIO7", + "AC_REL_ACK"}; + + if (cpu_is_u8500()) { + mbox0names = mbox0names_u8500; + } else if (cpu_is_u5500()) { + mbox0names = mbox0names_u5500; + } else { + seq_printf(s, "Unknown ASIC!\n"); + return 0; + } + + seq_printf(s, "mailbox0: %d\n", num_mailbox_interrupts[0]); + + for (i = 0; i < NUM_MAILBOX0_EVENTS; i++) + if (mbox0names[i]) { + seq_printf(s, " %20s %d ", mbox0names[i], + num_mailbox0_events[i] + ); + if (num_mailbox0_events_garbage[i]) + seq_printf(s, "unwanted: %d", + num_mailbox0_events_garbage[i]); + seq_printf(s, "\n"); + } else if (num_mailbox0_events[i]) { + seq_printf(s, " unknown (%d) %d\n", + i, num_mailbox0_events[i]); + } + + for (i = 1 ; i < NUM_MAILBOXES; i++) + seq_printf(s, "mailbox%d: %d\n", i, num_mailbox_interrupts[i]); + return 0; +} + static int opp_open_file(struct inode *inode, struct file *file) { return single_open(file, opp_read, inode->i_private); @@ -720,6 +851,11 @@ static int prcmu_regs_open_file(struct inode *inode, struct file *file) return err; } +static int interrupt_open_file(struct inode *inode, struct file *file) +{ + return single_open(file, interrupt_read, inode->i_private); +} + static const struct file_operations opp_fops = { .open = opp_open_file, .write = opp_write, @@ -798,6 +934,14 @@ static const struct file_operations prcmu_regs_fops = { .owner = THIS_MODULE, }; +static const struct file_operations interrupts_fops = { + .open = interrupt_open_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + static int setup_debugfs(void) { struct dentry *dir; @@ -868,6 +1012,12 @@ static int setup_debugfs(void) if (IS_ERR_OR_NULL(file)) goto fail; + file = debugfs_create_file("interrupts", + (S_IRUGO), + dir, NULL, &interrupts_fops); + if (IS_ERR_OR_NULL(file)) + goto fail; + return 0; fail: if (!IS_ERR_OR_NULL(dir)) diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c index feb1ad1a328..b106632d03c 100644 --- a/drivers/mfd/db5500-prcmu.c +++ b/drivers/mfd/db5500-prcmu.c @@ -1929,6 +1929,10 @@ static bool read_mailbox_0(void) else ev = readl(PRCM_ACK_MB0_WAKEUP_0_DBB); + prcmu_debug_register_mbox0_event(ev, + (mb0_transfer.req.dbb_irqs | + mb0_transfer.req.dbb_wakeups)); + ev &= mb0_transfer.req.dbb_irqs; for (n = 0; n < NUM_DB5500_PRCMU_WAKEUPS; n++) { @@ -2124,6 +2128,7 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) bits -= MBOX_BIT(n); if (read_mailbox[n]()) r = IRQ_WAKE_THREAD; + prcmu_debug_register_interrupt(n); } } return r; diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 3435126de97..48eaa0763a0 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -2436,6 +2436,13 @@ static bool read_mailbox_0(void) if (ev & WAKEUP_BIT_SYSCLK_OK) complete(&mb3_transfer.sysclk_work); + prcmu_debug_register_mbox0_event(ev, + (mb0_transfer.req.dbb_irqs | + mb0_transfer.req.dbb_wakeups | + WAKEUP_BIT_AC_WAKE_ACK | + WAKEUP_BIT_AC_SLEEP_ACK | + WAKEUP_BIT_SYSCLK_OK)); + ev &= mb0_transfer.req.dbb_irqs; for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { @@ -2560,6 +2567,7 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) bits -= MBOX_BIT(n); if (read_mailbox[n]()) r = IRQ_WAKE_THREAD; + prcmu_debug_register_interrupt(n); } } return r; -- cgit v1.2.3