diff options
Diffstat (limited to 'kernel/irq/proc.c')
-rw-r--r-- | kernel/irq/proc.c | 110 |
1 files changed, 94 insertions, 16 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index c53edad7b459..7f9642a1e267 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -37,19 +37,47 @@ static struct proc_dir_entry *root_irq_dir; | |||
37 | 37 | ||
38 | #ifdef CONFIG_SMP | 38 | #ifdef CONFIG_SMP |
39 | 39 | ||
40 | static int show_irq_affinity(int type, struct seq_file *m, void *v) | 40 | enum { |
41 | AFFINITY, | ||
42 | AFFINITY_LIST, | ||
43 | EFFECTIVE, | ||
44 | EFFECTIVE_LIST, | ||
45 | }; | ||
46 | |||
47 | static int show_irq_affinity(int type, struct seq_file *m) | ||
41 | { | 48 | { |
42 | struct irq_desc *desc = irq_to_desc((long)m->private); | 49 | struct irq_desc *desc = irq_to_desc((long)m->private); |
43 | const struct cpumask *mask = desc->irq_common_data.affinity; | 50 | const struct cpumask *mask; |
44 | 51 | ||
52 | switch (type) { | ||
53 | case AFFINITY: | ||
54 | case AFFINITY_LIST: | ||
55 | mask = desc->irq_common_data.affinity; | ||
45 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 56 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
46 | if (irqd_is_setaffinity_pending(&desc->irq_data)) | 57 | if (irqd_is_setaffinity_pending(&desc->irq_data)) |
47 | mask = desc->pending_mask; | 58 | mask = desc->pending_mask; |
48 | #endif | 59 | #endif |
49 | if (type) | 60 | break; |
61 | case EFFECTIVE: | ||
62 | case EFFECTIVE_LIST: | ||
63 | #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK | ||
64 | mask = desc->irq_common_data.effective_affinity; | ||
65 | break; | ||
66 | #else | ||
67 | return -EINVAL; | ||
68 | #endif | ||
69 | }; | ||
70 | |||
71 | switch (type) { | ||
72 | case AFFINITY_LIST: | ||
73 | case EFFECTIVE_LIST: | ||
50 | seq_printf(m, "%*pbl\n", cpumask_pr_args(mask)); | 74 | seq_printf(m, "%*pbl\n", cpumask_pr_args(mask)); |
51 | else | 75 | break; |
76 | case AFFINITY: | ||
77 | case EFFECTIVE: | ||
52 | seq_printf(m, "%*pb\n", cpumask_pr_args(mask)); | 78 | seq_printf(m, "%*pb\n", cpumask_pr_args(mask)); |
79 | break; | ||
80 | } | ||
53 | return 0; | 81 | return 0; |
54 | } | 82 | } |
55 | 83 | ||
@@ -80,12 +108,12 @@ static int irq_affinity_hint_proc_show(struct seq_file *m, void *v) | |||
80 | int no_irq_affinity; | 108 | int no_irq_affinity; |
81 | static int irq_affinity_proc_show(struct seq_file *m, void *v) | 109 | static int irq_affinity_proc_show(struct seq_file *m, void *v) |
82 | { | 110 | { |
83 | return show_irq_affinity(0, m, v); | 111 | return show_irq_affinity(AFFINITY, m); |
84 | } | 112 | } |
85 | 113 | ||
86 | static int irq_affinity_list_proc_show(struct seq_file *m, void *v) | 114 | static int irq_affinity_list_proc_show(struct seq_file *m, void *v) |
87 | { | 115 | { |
88 | return show_irq_affinity(1, m, v); | 116 | return show_irq_affinity(AFFINITY_LIST, m); |
89 | } | 117 | } |
90 | 118 | ||
91 | 119 | ||
@@ -120,9 +148,11 @@ static ssize_t write_irq_affinity(int type, struct file *file, | |||
120 | * one online CPU still has to be targeted. | 148 | * one online CPU still has to be targeted. |
121 | */ | 149 | */ |
122 | if (!cpumask_intersects(new_value, cpu_online_mask)) { | 150 | if (!cpumask_intersects(new_value, cpu_online_mask)) { |
123 | /* Special case for empty set - allow the architecture | 151 | /* |
124 | code to set default SMP affinity. */ | 152 | * Special case for empty set - allow the architecture code |
125 | err = irq_select_affinity_usr(irq, new_value) ? -EINVAL : count; | 153 | * to set default SMP affinity. |
154 | */ | ||
155 | err = irq_select_affinity_usr(irq) ? -EINVAL : count; | ||
126 | } else { | 156 | } else { |
127 | irq_set_affinity(irq, new_value); | 157 | irq_set_affinity(irq, new_value); |
128 | err = count; | 158 | err = count; |
@@ -183,6 +213,44 @@ static const struct file_operations irq_affinity_list_proc_fops = { | |||
183 | .write = irq_affinity_list_proc_write, | 213 | .write = irq_affinity_list_proc_write, |
184 | }; | 214 | }; |
185 | 215 | ||
216 | #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK | ||
217 | static int irq_effective_aff_proc_show(struct seq_file *m, void *v) | ||
218 | { | ||
219 | return show_irq_affinity(EFFECTIVE, m); | ||
220 | } | ||
221 | |||
222 | static int irq_effective_aff_list_proc_show(struct seq_file *m, void *v) | ||
223 | { | ||
224 | return show_irq_affinity(EFFECTIVE_LIST, m); | ||
225 | } | ||
226 | |||
227 | static int irq_effective_aff_proc_open(struct inode *inode, struct file *file) | ||
228 | { | ||
229 | return single_open(file, irq_effective_aff_proc_show, PDE_DATA(inode)); | ||
230 | } | ||
231 | |||
232 | static int irq_effective_aff_list_proc_open(struct inode *inode, | ||
233 | struct file *file) | ||
234 | { | ||
235 | return single_open(file, irq_effective_aff_list_proc_show, | ||
236 | PDE_DATA(inode)); | ||
237 | } | ||
238 | |||
239 | static const struct file_operations irq_effective_aff_proc_fops = { | ||
240 | .open = irq_effective_aff_proc_open, | ||
241 | .read = seq_read, | ||
242 | .llseek = seq_lseek, | ||
243 | .release = single_release, | ||
244 | }; | ||
245 | |||
246 | static const struct file_operations irq_effective_aff_list_proc_fops = { | ||
247 | .open = irq_effective_aff_list_proc_open, | ||
248 | .read = seq_read, | ||
249 | .llseek = seq_lseek, | ||
250 | .release = single_release, | ||
251 | }; | ||
252 | #endif | ||
253 | |||
186 | static int default_affinity_show(struct seq_file *m, void *v) | 254 | static int default_affinity_show(struct seq_file *m, void *v) |
187 | { | 255 | { |
188 | seq_printf(m, "%*pb\n", cpumask_pr_args(irq_default_affinity)); | 256 | seq_printf(m, "%*pb\n", cpumask_pr_args(irq_default_affinity)); |
@@ -324,6 +392,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
324 | void register_irq_proc(unsigned int irq, struct irq_desc *desc) | 392 | void register_irq_proc(unsigned int irq, struct irq_desc *desc) |
325 | { | 393 | { |
326 | static DEFINE_MUTEX(register_lock); | 394 | static DEFINE_MUTEX(register_lock); |
395 | void __maybe_unused *irqp = (void *)(unsigned long) irq; | ||
327 | char name [MAX_NAMELEN]; | 396 | char name [MAX_NAMELEN]; |
328 | 397 | ||
329 | if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) | 398 | if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) |
@@ -349,20 +418,25 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) | |||
349 | #ifdef CONFIG_SMP | 418 | #ifdef CONFIG_SMP |
350 | /* create /proc/irq/<irq>/smp_affinity */ | 419 | /* create /proc/irq/<irq>/smp_affinity */ |
351 | proc_create_data("smp_affinity", 0644, desc->dir, | 420 | proc_create_data("smp_affinity", 0644, desc->dir, |
352 | &irq_affinity_proc_fops, (void *)(long)irq); | 421 | &irq_affinity_proc_fops, irqp); |
353 | 422 | ||
354 | /* create /proc/irq/<irq>/affinity_hint */ | 423 | /* create /proc/irq/<irq>/affinity_hint */ |
355 | proc_create_data("affinity_hint", 0444, desc->dir, | 424 | proc_create_data("affinity_hint", 0444, desc->dir, |
356 | &irq_affinity_hint_proc_fops, (void *)(long)irq); | 425 | &irq_affinity_hint_proc_fops, irqp); |
357 | 426 | ||
358 | /* create /proc/irq/<irq>/smp_affinity_list */ | 427 | /* create /proc/irq/<irq>/smp_affinity_list */ |
359 | proc_create_data("smp_affinity_list", 0644, desc->dir, | 428 | proc_create_data("smp_affinity_list", 0644, desc->dir, |
360 | &irq_affinity_list_proc_fops, (void *)(long)irq); | 429 | &irq_affinity_list_proc_fops, irqp); |
361 | 430 | ||
362 | proc_create_data("node", 0444, desc->dir, | 431 | proc_create_data("node", 0444, desc->dir, |
363 | &irq_node_proc_fops, (void *)(long)irq); | 432 | &irq_node_proc_fops, irqp); |
433 | # ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK | ||
434 | proc_create_data("effective_affinity", 0444, desc->dir, | ||
435 | &irq_effective_aff_proc_fops, irqp); | ||
436 | proc_create_data("effective_affinity_list", 0444, desc->dir, | ||
437 | &irq_effective_aff_list_proc_fops, irqp); | ||
438 | # endif | ||
364 | #endif | 439 | #endif |
365 | |||
366 | proc_create_data("spurious", 0444, desc->dir, | 440 | proc_create_data("spurious", 0444, desc->dir, |
367 | &irq_spurious_proc_fops, (void *)(long)irq); | 441 | &irq_spurious_proc_fops, (void *)(long)irq); |
368 | 442 | ||
@@ -381,6 +455,10 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) | |||
381 | remove_proc_entry("affinity_hint", desc->dir); | 455 | remove_proc_entry("affinity_hint", desc->dir); |
382 | remove_proc_entry("smp_affinity_list", desc->dir); | 456 | remove_proc_entry("smp_affinity_list", desc->dir); |
383 | remove_proc_entry("node", desc->dir); | 457 | remove_proc_entry("node", desc->dir); |
458 | # ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK | ||
459 | remove_proc_entry("effective_affinity", desc->dir); | ||
460 | remove_proc_entry("effective_affinity_list", desc->dir); | ||
461 | # endif | ||
384 | #endif | 462 | #endif |
385 | remove_proc_entry("spurious", desc->dir); | 463 | remove_proc_entry("spurious", desc->dir); |
386 | 464 | ||