aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2015-01-13 16:07:14 -0500
committerAlex Shi <alex.shi@linaro.org>2015-01-21 14:28:17 +0800
commitc409503326a43facbf95d2dccbcc427883b40aab (patch)
tree555b605c659e9f14179b8a29833161a39c47b21c
parentba85736e4f055131253cc74423720f3a6615a440 (diff)
irq_timings: connect timing processing to IRQ events
Signed-off-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> (cherry picked from commit 5486962fa74da5804c2716455f6a1f3fdcb94687) Signed-off-by: Alex Shi <alex.shi@linaro.org> Conflicts: include/linux/irqdesc.h
-rw-r--r--include/linux/irqdesc.h7
-rw-r--r--kernel/irq/internals.h8
-rw-r--r--kernel/irq/timings.c3
3 files changed, 17 insertions, 1 deletions
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 078bc2fc74f..ade27f50228 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -12,11 +12,15 @@ struct irq_affinity_notify;
struct proc_dir_entry;
struct module;
struct irq_desc;
+struct irq_domain;
+struct pt_regs;
+struct irqt_stat;
/**
* struct irq_desc - interrupt descriptor
* @irq_data: per irq and chip data passed down to chip functions
* @kstat_irqs: irq stats per cpu
+ * @irq_timings: irq occurrence timing statistics
* @handle_irq: highlevel irq-events handler
* @preflow_handler: handler called before the flow handler (currently used by sparc)
* @action: the irq action chain
@@ -42,6 +46,9 @@ struct irq_desc;
struct irq_desc {
struct irq_data irq_data;
unsigned int __percpu *kstat_irqs;
+#ifdef CONFIG_IRQ_TIMINGS
+ struct irqt_stat *irq_timings;
+#endif
irq_flow_handler_t handle_irq;
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
irq_preflow_handler_t preflow_handler;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 7fc65c8883a..b253c8c9580 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -101,8 +101,15 @@ static inline void unregister_handler_proc(unsigned int irq,
#ifdef CONFIG_IRQ_TIMINGS
extern void __init irqt_init(void);
+extern void irqt_process(unsigned int irq, struct irqt_stat *s);
+static inline void irqt_event(int irq, struct irq_desc *desc)
+{
+ if (desc->irq_timings)
+ irqt_process(irq, desc->irq_timings);
+}
#else
static inline void irqt_init(void) { }
+static inline void irqt_event(int irq, struct irq_desc *desc) { }
#endif
extern int irq_select_affinity_usr(unsigned int irq, struct cpumask *mask);
@@ -192,4 +199,5 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
{
__this_cpu_inc(*desc->kstat_irqs);
__this_cpu_inc(kstat.irqs_sum);
+ irqt_event(irq, desc);
}
diff --git a/kernel/irq/timings.c b/kernel/irq/timings.c
index 6bc64aa6685..c185d1963ab 100644
--- a/kernel/irq/timings.c
+++ b/kernel/irq/timings.c
@@ -140,7 +140,8 @@ u32 irqt_get_next_prediction(int cpu)
* @irq: the IRQ number
* @stat: the corresponding IRQ timing stats record
*
- * This is assumed to be called in IRQ context with IRQs turned off.
+ * This is assumed to be called in IRQ context with desc->lock held and
+ * IRQs turned off.
*/
void irqt_process(unsigned int irq, struct irqt_stat *s)
{