linux-bk/kernel/irq/proc.c
<<
>>
Prefs
   1/*
   2 * linux/kernel/irq/proc.c
   3 *
   4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
   5 *
   6 * This file contains the /proc/irq/ handling code.
   7 */
   8
   9#include <linux/irq.h>
  10#include <linux/proc_fs.h>
  11#include <linux/interrupt.h>
  12
  13static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS];
  14
  15#ifdef CONFIG_SMP
  16
  17/*
  18 * The /proc/irq/<irq>/smp_affinity values:
  19 */
  20static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
  21
  22static int irq_affinity_read_proc(char *page, char **start, off_t off,
  23                                  int count, int *eof, void *data)
  24{
  25        int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
  26
  27        if (count - len < 2)
  28                return -EINVAL;
  29        len += sprintf(page + len, "\n");
  30        return len;
  31}
  32
  33int no_irq_affinity;
  34static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
  35                                   unsigned long count, void *data)
  36{
  37        unsigned int irq = (int)(long)data, full_count = count, err;
  38        cpumask_t new_value, tmp;
  39
  40        if (!irq_desc[irq].handler->set_affinity || no_irq_affinity)
  41                return -EIO;
  42
  43        err = cpumask_parse(buffer, count, new_value);
  44        if (err)
  45                return err;
  46
  47        /*
  48         * Do not allow disabling IRQs completely - it's a too easy
  49         * way to make the system unusable accidentally :-) At least
  50         * one online CPU still has to be targeted.
  51         */
  52        cpus_and(tmp, new_value, cpu_online_map);
  53        if (cpus_empty(tmp))
  54                return -EINVAL;
  55
  56        irq_affinity[irq] = new_value;
  57        irq_desc[irq].handler->set_affinity(irq, new_value);
  58
  59        return full_count;
  60}
  61
  62#endif
  63
  64#define MAX_NAMELEN 128
  65
  66static int name_unique(unsigned int irq, struct irqaction *new_action)
  67{
  68        struct irq_desc *desc = irq_desc + irq;
  69        struct irqaction *action;
  70
  71        for (action = desc->action ; action; action = action->next)
  72                if ((action != new_action) && action->name &&
  73                                !strcmp(new_action->name, action->name))
  74                        return 0;
  75        return 1;
  76}
  77
  78void register_handler_proc(unsigned int irq, struct irqaction *action)
  79{
  80        char name [MAX_NAMELEN];
  81
  82        if (!irq_dir[irq] || action->dir || !action->name ||
  83                                        !name_unique(irq, action))
  84                return;
  85
  86        memset(name, 0, MAX_NAMELEN);
  87        snprintf(name, MAX_NAMELEN, "%s", action->name);
  88
  89        /* create /proc/irq/1234/handler/ */
  90        action->dir = proc_mkdir(name, irq_dir[irq]);
  91}
  92
  93#undef MAX_NAMELEN
  94
  95#define MAX_NAMELEN 10
  96
  97void register_irq_proc(unsigned int irq)
  98{
  99        char name [MAX_NAMELEN];
 100
 101        if (!root_irq_dir ||
 102                (irq_desc[irq].handler == &no_irq_type) ||
 103                        irq_dir[irq])
 104                return;
 105
 106        memset(name, 0, MAX_NAMELEN);
 107        sprintf(name, "%d", irq);
 108
 109        /* create /proc/irq/1234 */
 110        irq_dir[irq] = proc_mkdir(name, root_irq_dir);
 111
 112#ifdef CONFIG_SMP
 113        {
 114                struct proc_dir_entry *entry;
 115
 116                /* create /proc/irq/<irq>/smp_affinity */
 117                entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
 118
 119                if (entry) {
 120                        entry->nlink = 1;
 121                        entry->data = (void *)(long)irq;
 122                        entry->read_proc = irq_affinity_read_proc;
 123                        entry->write_proc = irq_affinity_write_proc;
 124                }
 125                smp_affinity_entry[irq] = entry;
 126        }
 127#endif
 128}
 129
 130#undef MAX_NAMELEN
 131
 132void unregister_handler_proc(unsigned int irq, struct irqaction *action)
 133{
 134        if (action->dir)
 135                remove_proc_entry(action->dir->name, irq_dir[irq]);
 136}
 137
 138void init_irq_proc(void)
 139{
 140        int i;
 141
 142        /* create /proc/irq */
 143        root_irq_dir = proc_mkdir("irq", NULL);
 144        if (!root_irq_dir)
 145                return;
 146
 147        /*
 148         * Create entries for all existing IRQs.
 149         */
 150        for (i = 0; i < NR_IRQS; i++)
 151                register_irq_proc(i);
 152}
 153
 154
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.