summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Aaberg <jonas.aberg@stericsson.com>2011-12-14 10:19:59 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 10:59:31 +0200
commit34ce3c349c77e721d1ac0de047eaa4d61682cce0 (patch)
tree3827a2fb1d5e39f7eae90ae020ee20e0c47eb69e
parentde732c95ae819baa0d1bb90c659e70150b7c1d56 (diff)
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 <jonas.aberg@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42475
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu-debug.h4
-rw-r--r--arch/arm/mach-ux500/prcmu-debug.c150
-rw-r--r--drivers/mfd/db5500-prcmu.c5
-rw-r--r--drivers/mfd/db8500-prcmu.c8
4 files changed, 167 insertions, 0 deletions
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;