diff options
Diffstat (limited to 'kernel/irq/proc.c')
| -rw-r--r-- | kernel/irq/proc.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 6c8a2a9f8a7..4cc2e5ed0be 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/proc_fs.h> | 11 | #include <linux/proc_fs.h> |
| 12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
| 13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 14 | #include <linux/kernel_stat.h> | ||
| 14 | 15 | ||
| 15 | #include "internals.h" | 16 | #include "internals.h" |
| 16 | 17 | ||
| @@ -24,7 +25,7 @@ static int irq_affinity_proc_show(struct seq_file *m, void *v) | |||
| 24 | const struct cpumask *mask = desc->irq_data.affinity; | 25 | const struct cpumask *mask = desc->irq_data.affinity; |
| 25 | 26 | ||
| 26 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 27 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 27 | if (desc->status & IRQ_MOVE_PENDING) | 28 | if (irqd_is_setaffinity_pending(&desc->irq_data)) |
| 28 | mask = desc->pending_mask; | 29 | mask = desc->pending_mask; |
| 29 | #endif | 30 | #endif |
| 30 | seq_cpumask(m, mask); | 31 | seq_cpumask(m, mask); |
| @@ -65,8 +66,7 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
| 65 | cpumask_var_t new_value; | 66 | cpumask_var_t new_value; |
| 66 | int err; | 67 | int err; |
| 67 | 68 | ||
| 68 | if (!irq_to_desc(irq)->irq_data.chip->irq_set_affinity || no_irq_affinity || | 69 | if (!irq_can_set_affinity(irq) || no_irq_affinity) |
| 69 | irq_balancing_disabled(irq)) | ||
| 70 | return -EIO; | 70 | return -EIO; |
| 71 | 71 | ||
| 72 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) | 72 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) |
| @@ -89,7 +89,7 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
| 89 | if (!cpumask_intersects(new_value, cpu_online_mask)) { | 89 | if (!cpumask_intersects(new_value, cpu_online_mask)) { |
| 90 | /* Special case for empty set - allow the architecture | 90 | /* Special case for empty set - allow the architecture |
| 91 | code to set default SMP affinity. */ | 91 | code to set default SMP affinity. */ |
| 92 | err = irq_select_affinity_usr(irq) ? -EINVAL : count; | 92 | err = irq_select_affinity_usr(irq, new_value) ? -EINVAL : count; |
| 93 | } else { | 93 | } else { |
| 94 | irq_set_affinity(irq, new_value); | 94 | irq_set_affinity(irq, new_value); |
| 95 | err = count; | 95 | err = count; |
| @@ -357,3 +357,65 @@ void init_irq_proc(void) | |||
| 357 | } | 357 | } |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | #ifdef CONFIG_GENERIC_IRQ_SHOW | ||
| 361 | |||
| 362 | int __weak arch_show_interrupts(struct seq_file *p, int prec) | ||
| 363 | { | ||
| 364 | return 0; | ||
| 365 | } | ||
| 366 | |||
| 367 | int show_interrupts(struct seq_file *p, void *v) | ||
| 368 | { | ||
| 369 | static int prec; | ||
| 370 | |||
| 371 | unsigned long flags, any_count = 0; | ||
| 372 | int i = *(loff_t *) v, j; | ||
| 373 | struct irqaction *action; | ||
| 374 | struct irq_desc *desc; | ||
| 375 | |||
| 376 | if (i > nr_irqs) | ||
| 377 | return 0; | ||
| 378 | |||
| 379 | if (i == nr_irqs) | ||
| 380 | return arch_show_interrupts(p, prec); | ||
| 381 | |||
| 382 | /* print header and calculate the width of the first column */ | ||
| 383 | if (i == 0) { | ||
| 384 | for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) | ||
| 385 | j *= 10; | ||
| 386 | |||
| 387 | seq_printf(p, "%*s", prec + 8, ""); | ||
| 388 | for_each_online_cpu(j) | ||
| 389 | seq_printf(p, "CPU%-8d", j); | ||
| 390 | seq_putc(p, '\n'); | ||
| 391 | } | ||
| 392 | |||
| 393 | desc = irq_to_desc(i); | ||
| 394 | if (!desc) | ||
| 395 | return 0; | ||
| 396 | |||
| 397 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
| 398 | for_each_online_cpu(j) | ||
| 399 | any_count |= kstat_irqs_cpu(i, j); | ||
| 400 | action = desc->action; | ||
| 401 | if (!action && !any_count) | ||
| 402 | goto out; | ||
| 403 | |||
| 404 | seq_printf(p, "%*d: ", prec, i); | ||
| 405 | for_each_online_cpu(j) | ||
| 406 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
| 407 | seq_printf(p, " %8s", desc->irq_data.chip->name); | ||
| 408 | seq_printf(p, "-%-8s", desc->name); | ||
| 409 | |||
| 410 | if (action) { | ||
| 411 | seq_printf(p, " %s", action->name); | ||
| 412 | while ((action = action->next) != NULL) | ||
| 413 | seq_printf(p, ", %s", action->name); | ||
| 414 | } | ||
| 415 | |||
| 416 | seq_putc(p, '\n'); | ||
| 417 | out: | ||
| 418 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | #endif | ||
