aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-06-20 13:14:31 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-06-20 13:14:31 -0400
commitf05218651be1ac6a6088e226bd7350fb6c154414 (patch)
tree204ee38c859f08e7e76ea4b6913cdea52cb25d56
parent62a993df31f795d87bcb4c6cb005d36f32f6ad55 (diff)
parenta614a610ac9b28f195d790d25be72d26f345c53a (diff)
Merge branch 'irq/for-x86' into irq/core
Get the infrastructure patches which are required for x86/apic into core
-rw-r--r--include/linux/irq.h71
-rw-r--r--include/linux/irqdesc.h12
-rw-r--r--kernel/irq/internals.h17
-rw-r--r--kernel/irq/irqdesc.c9
-rw-r--r--kernel/irq/irqdomain.c4
-rw-r--r--kernel/irq/manage.c2
-rw-r--r--kernel/irq/migration.c15
-rw-r--r--kernel/irq/proc.c2
8 files changed, 88 insertions, 44 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 42861d28fc2a..812149160d3b 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -126,13 +126,21 @@ struct msi_desc;
126struct irq_domain; 126struct irq_domain;
127 127
128/** 128/**
129 * struct irq_data - per irq and irq chip data passed down to chip functions 129 * struct irq_common_data - per irq data shared by all irqchips
130 * @state_use_accessors: status information for irq chip functions.
131 * Use accessor functions to deal with it
132 */
133struct irq_common_data {
134 unsigned int state_use_accessors;
135};
136
137/**
138 * struct irq_data - per irq chip data passed down to chip functions
130 * @mask: precomputed bitmask for accessing the chip registers 139 * @mask: precomputed bitmask for accessing the chip registers
131 * @irq: interrupt number 140 * @irq: interrupt number
132 * @hwirq: hardware interrupt number, local to the interrupt domain 141 * @hwirq: hardware interrupt number, local to the interrupt domain
133 * @node: node index useful for balancing 142 * @node: node index useful for balancing
134 * @state_use_accessors: status information for irq chip functions. 143 * @common: point to data shared by all irqchips
135 * Use accessor functions to deal with it
136 * @chip: low level interrupt hardware access 144 * @chip: low level interrupt hardware access
137 * @domain: Interrupt translation domain; responsible for mapping 145 * @domain: Interrupt translation domain; responsible for mapping
138 * between hwirq number and linux irq number. 146 * between hwirq number and linux irq number.
@@ -153,7 +161,7 @@ struct irq_data {
153 unsigned int irq; 161 unsigned int irq;
154 unsigned long hwirq; 162 unsigned long hwirq;
155 unsigned int node; 163 unsigned int node;
156 unsigned int state_use_accessors; 164 struct irq_common_data *common;
157 struct irq_chip *chip; 165 struct irq_chip *chip;
158 struct irq_domain *domain; 166 struct irq_domain *domain;
159#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 167#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -166,7 +174,7 @@ struct irq_data {
166}; 174};
167 175
168/* 176/*
169 * Bit masks for irq_data.state 177 * Bit masks for irq_common_data.state_use_accessors
170 * 178 *
171 * IRQD_TRIGGER_MASK - Mask for the trigger type bits 179 * IRQD_TRIGGER_MASK - Mask for the trigger type bits
172 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending 180 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
@@ -198,34 +206,36 @@ enum {
198 IRQD_WAKEUP_ARMED = (1 << 19), 206 IRQD_WAKEUP_ARMED = (1 << 19),
199}; 207};
200 208
209#define __irqd_to_state(d) ((d)->common->state_use_accessors)
210
201static inline bool irqd_is_setaffinity_pending(struct irq_data *d) 211static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
202{ 212{
203 return d->state_use_accessors & IRQD_SETAFFINITY_PENDING; 213 return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
204} 214}
205 215
206static inline bool irqd_is_per_cpu(struct irq_data *d) 216static inline bool irqd_is_per_cpu(struct irq_data *d)
207{ 217{
208 return d->state_use_accessors & IRQD_PER_CPU; 218 return __irqd_to_state(d) & IRQD_PER_CPU;
209} 219}
210 220
211static inline bool irqd_can_balance(struct irq_data *d) 221static inline bool irqd_can_balance(struct irq_data *d)
212{ 222{
213 return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING)); 223 return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
214} 224}
215 225
216static inline bool irqd_affinity_was_set(struct irq_data *d) 226static inline bool irqd_affinity_was_set(struct irq_data *d)
217{ 227{
218 return d->state_use_accessors & IRQD_AFFINITY_SET; 228 return __irqd_to_state(d) & IRQD_AFFINITY_SET;
219} 229}
220 230
221static inline void irqd_mark_affinity_was_set(struct irq_data *d) 231static inline void irqd_mark_affinity_was_set(struct irq_data *d)
222{ 232{
223 d->state_use_accessors |= IRQD_AFFINITY_SET; 233 __irqd_to_state(d) |= IRQD_AFFINITY_SET;
224} 234}
225 235
226static inline u32 irqd_get_trigger_type(struct irq_data *d) 236static inline u32 irqd_get_trigger_type(struct irq_data *d)
227{ 237{
228 return d->state_use_accessors & IRQD_TRIGGER_MASK; 238 return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
229} 239}
230 240
231/* 241/*
@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
233 */ 243 */
234static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) 244static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
235{ 245{
236 d->state_use_accessors &= ~IRQD_TRIGGER_MASK; 246 __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
237 d->state_use_accessors |= type & IRQD_TRIGGER_MASK; 247 __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
238} 248}
239 249
240static inline bool irqd_is_level_type(struct irq_data *d) 250static inline bool irqd_is_level_type(struct irq_data *d)
241{ 251{
242 return d->state_use_accessors & IRQD_LEVEL; 252 return __irqd_to_state(d) & IRQD_LEVEL;
243} 253}
244 254
245static inline bool irqd_is_wakeup_set(struct irq_data *d) 255static inline bool irqd_is_wakeup_set(struct irq_data *d)
246{ 256{
247 return d->state_use_accessors & IRQD_WAKEUP_STATE; 257 return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
248} 258}
249 259
250static inline bool irqd_can_move_in_process_context(struct irq_data *d) 260static inline bool irqd_can_move_in_process_context(struct irq_data *d)
251{ 261{
252 return d->state_use_accessors & IRQD_MOVE_PCNTXT; 262 return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
253} 263}
254 264
255static inline bool irqd_irq_disabled(struct irq_data *d) 265static inline bool irqd_irq_disabled(struct irq_data *d)
256{ 266{
257 return d->state_use_accessors & IRQD_IRQ_DISABLED; 267 return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
258} 268}
259 269
260static inline bool irqd_irq_masked(struct irq_data *d) 270static inline bool irqd_irq_masked(struct irq_data *d)
261{ 271{
262 return d->state_use_accessors & IRQD_IRQ_MASKED; 272 return __irqd_to_state(d) & IRQD_IRQ_MASKED;
263} 273}
264 274
265static inline bool irqd_irq_inprogress(struct irq_data *d) 275static inline bool irqd_irq_inprogress(struct irq_data *d)
266{ 276{
267 return d->state_use_accessors & IRQD_IRQ_INPROGRESS; 277 return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
268} 278}
269 279
270static inline bool irqd_is_wakeup_armed(struct irq_data *d) 280static inline bool irqd_is_wakeup_armed(struct irq_data *d)
271{ 281{
272 return d->state_use_accessors & IRQD_WAKEUP_ARMED; 282 return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
273} 283}
274 284
275 285
@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
280 */ 290 */
281static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) 291static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
282{ 292{
283 d->state_use_accessors |= IRQD_IRQ_INPROGRESS; 293 __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
284} 294}
285 295
286static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) 296static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
287{ 297{
288 d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; 298 __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
289} 299}
290 300
291static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 301static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -641,6 +651,23 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
641 return d ? irqd_get_trigger_type(d) : 0; 651 return d ? irqd_get_trigger_type(d) : 0;
642} 652}
643 653
654static inline int irq_data_get_node(struct irq_data *d)
655{
656 return d->node;
657}
658
659static inline struct cpumask *irq_get_affinity_mask(int irq)
660{
661 struct irq_data *d = irq_get_irq_data(irq);
662
663 return d ? d->affinity : NULL;
664}
665
666static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
667{
668 return d->affinity;
669}
670
644unsigned int arch_dynirq_lower_bound(unsigned int from); 671unsigned int arch_dynirq_lower_bound(unsigned int from);
645 672
646int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, 673int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index dd1109fb241e..c52d1480f272 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,7 +17,7 @@ struct pt_regs;
17 17
18/** 18/**
19 * struct irq_desc - interrupt descriptor 19 * struct irq_desc - interrupt descriptor
20 * @irq_data: per irq and chip data passed down to chip functions 20 * @irq_common_data: per irq and chip data passed down to chip functions
21 * @kstat_irqs: irq stats per cpu 21 * @kstat_irqs: irq stats per cpu
22 * @handle_irq: highlevel irq-events handler 22 * @handle_irq: highlevel irq-events handler
23 * @preflow_handler: handler called before the flow handler (currently used by sparc) 23 * @preflow_handler: handler called before the flow handler (currently used by sparc)
@@ -47,6 +47,7 @@ struct pt_regs;
47 * @name: flow handler name for /proc/interrupts output 47 * @name: flow handler name for /proc/interrupts output
48 */ 48 */
49struct irq_desc { 49struct irq_desc {
50 struct irq_common_data irq_common_data;
50 struct irq_data irq_data; 51 struct irq_data irq_data;
51 unsigned int __percpu *kstat_irqs; 52 unsigned int __percpu *kstat_irqs;
52 irq_flow_handler_t handle_irq; 53 irq_flow_handler_t handle_irq;
@@ -93,6 +94,15 @@ struct irq_desc {
93extern struct irq_desc irq_desc[NR_IRQS]; 94extern struct irq_desc irq_desc[NR_IRQS];
94#endif 95#endif
95 96
97static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
98{
99#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
100 return irq_to_desc(data->irq);
101#else
102 return container_of(data, struct irq_desc, irq_data);
103#endif
104}
105
96static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc) 106static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
97{ 107{
98 return &desc->irq_data; 108 return &desc->irq_data;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index df553b0af936..4834ee828c41 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -59,8 +59,6 @@ enum {
59#include "debug.h" 59#include "debug.h"
60#include "settings.h" 60#include "settings.h"
61 61
62#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
63
64extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, 62extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
65 unsigned long flags); 63 unsigned long flags);
66extern void __disable_irq(struct irq_desc *desc, unsigned int irq); 64extern void __disable_irq(struct irq_desc *desc, unsigned int irq);
@@ -170,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
170 */ 168 */
171static inline void irqd_set_move_pending(struct irq_data *d) 169static inline void irqd_set_move_pending(struct irq_data *d)
172{ 170{
173 d->state_use_accessors |= IRQD_SETAFFINITY_PENDING; 171 __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
174} 172}
175 173
176static inline void irqd_clr_move_pending(struct irq_data *d) 174static inline void irqd_clr_move_pending(struct irq_data *d)
177{ 175{
178 d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING; 176 __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
179} 177}
180 178
181static inline void irqd_clear(struct irq_data *d, unsigned int mask) 179static inline void irqd_clear(struct irq_data *d, unsigned int mask)
182{ 180{
183 d->state_use_accessors &= ~mask; 181 __irqd_to_state(d) &= ~mask;
184} 182}
185 183
186static inline void irqd_set(struct irq_data *d, unsigned int mask) 184static inline void irqd_set(struct irq_data *d, unsigned int mask)
187{ 185{
188 d->state_use_accessors |= mask; 186 __irqd_to_state(d) |= mask;
189} 187}
190 188
191static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) 189static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
192{ 190{
193 return d->state_use_accessors & mask; 191 return __irqd_to_state(d) & mask;
194} 192}
195 193
196static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) 194static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
@@ -199,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
199 __this_cpu_inc(kstat.irqs_sum); 197 __this_cpu_inc(kstat.irqs_sum);
200} 198}
201 199
200static inline int irq_desc_get_node(struct irq_desc *desc)
201{
202 return irq_data_get_node(&desc->irq_data);
203}
204
202#ifdef CONFIG_PM_SLEEP 205#ifdef CONFIG_PM_SLEEP
203bool irq_pm_check_wakeup(struct irq_desc *desc); 206bool irq_pm_check_wakeup(struct irq_desc *desc);
204void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action); 207void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 73a76e2ee936..4afc457613dd 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node)
59#endif 59#endif
60} 60}
61 61
62static inline int desc_node(struct irq_desc *desc)
63{
64 return desc->irq_data.node;
65}
66
67#else 62#else
68static inline int 63static inline int
69alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; } 64alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
70static inline void desc_smp_init(struct irq_desc *desc, int node) { } 65static inline void desc_smp_init(struct irq_desc *desc, int node) { }
71static inline int desc_node(struct irq_desc *desc) { return 0; }
72#endif 66#endif
73 67
74static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, 68static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
@@ -76,6 +70,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
76{ 70{
77 int cpu; 71 int cpu;
78 72
73 desc->irq_data.common = &desc->irq_common_data;
79 desc->irq_data.irq = irq; 74 desc->irq_data.irq = irq;
80 desc->irq_data.chip = &no_irq_chip; 75 desc->irq_data.chip = &no_irq_chip;
81 desc->irq_data.chip_data = NULL; 76 desc->irq_data.chip_data = NULL;
@@ -299,7 +294,7 @@ static void free_desc(unsigned int irq)
299 unsigned long flags; 294 unsigned long flags;
300 295
301 raw_spin_lock_irqsave(&desc->lock, flags); 296 raw_spin_lock_irqsave(&desc->lock, flags);
302 desc_set_defaults(irq, desc, desc_node(desc), NULL); 297 desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
303 raw_spin_unlock_irqrestore(&desc->lock, flags); 298 raw_spin_unlock_irqrestore(&desc->lock, flags);
304} 299}
305 300
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 41bf6dc49f59..8c3577fef78c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -830,10 +830,12 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
830{ 830{
831 struct irq_data *irq_data; 831 struct irq_data *irq_data;
832 832
833 irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node); 833 irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
834 irq_data_get_node(child));
834 if (irq_data) { 835 if (irq_data) {
835 child->parent_data = irq_data; 836 child->parent_data = irq_data;
836 irq_data->irq = child->irq; 837 irq_data->irq = child->irq;
838 irq_data->common = child->common;
837 irq_data->node = child->node; 839 irq_data->node = child->node;
838 irq_data->domain = domain; 840 irq_data->domain = domain;
839 } 841 }
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b1c7e8f46bfb..f9744853b656 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -363,7 +363,7 @@ static int
363setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) 363setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
364{ 364{
365 struct cpumask *set = irq_default_affinity; 365 struct cpumask *set = irq_default_affinity;
366 int node = desc->irq_data.node; 366 int node = irq_desc_get_node(desc);
367 367
368 /* Excludes PER_CPU and NO_BALANCE interrupts */ 368 /* Excludes PER_CPU and NO_BALANCE interrupts */
369 if (!irq_can_set_affinity(irq)) 369 if (!irq_can_set_affinity(irq))
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ca3f4aaff707..37ddb7bda651 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -7,21 +7,21 @@
7void irq_move_masked_irq(struct irq_data *idata) 7void irq_move_masked_irq(struct irq_data *idata)
8{ 8{
9 struct irq_desc *desc = irq_data_to_desc(idata); 9 struct irq_desc *desc = irq_data_to_desc(idata);
10 struct irq_chip *chip = idata->chip; 10 struct irq_chip *chip = desc->irq_data.chip;
11 11
12 if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) 12 if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
13 return; 13 return;
14 14
15 irqd_clr_move_pending(&desc->irq_data);
16
15 /* 17 /*
16 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway. 18 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway.
17 */ 19 */
18 if (!irqd_can_balance(&desc->irq_data)) { 20 if (irqd_is_per_cpu(&desc->irq_data)) {
19 WARN_ON(1); 21 WARN_ON(1);
20 return; 22 return;
21 } 23 }
22 24
23 irqd_clr_move_pending(&desc->irq_data);
24
25 if (unlikely(cpumask_empty(desc->pending_mask))) 25 if (unlikely(cpumask_empty(desc->pending_mask)))
26 return; 26 return;
27 27
@@ -52,6 +52,13 @@ void irq_move_irq(struct irq_data *idata)
52{ 52{
53 bool masked; 53 bool masked;
54 54
55 /*
56 * Get top level irq_data when CONFIG_IRQ_DOMAIN_HIERARCHY is enabled,
57 * and it should be optimized away when CONFIG_IRQ_DOMAIN_HIERARCHY is
58 * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here.
59 */
60 idata = irq_desc_get_irq_data(irq_data_to_desc(idata));
61
55 if (likely(!irqd_is_setaffinity_pending(idata))) 62 if (likely(!irqd_is_setaffinity_pending(idata)))
56 return; 63 return;
57 64
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index df2f4642d1e7..0e97c142ce40 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
241{ 241{
242 struct irq_desc *desc = irq_to_desc((long) m->private); 242 struct irq_desc *desc = irq_to_desc((long) m->private);
243 243
244 seq_printf(m, "%d\n", desc->irq_data.node); 244 seq_printf(m, "%d\n", irq_desc_get_node(desc));
245 return 0; 245 return 0;
246} 246}
247 247