Timer initialization fixed
[cbs-scheduler.git] / kernel / irq / proc.c
blob83006773b707322357f5dda02f3367512f5510a2
1 /*
2 * linux/kernel/irq/proc.c
4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
6 * This file contains the /proc/irq/ handling code.
7 */
9 #include <linux/irq.h>
10 #include <asm/uaccess.h>
11 #include <linux/profile.h>
12 #include <linux/proc_fs.h>
13 #include <linux/seq_file.h>
14 #include <linux/interrupt.h>
16 #include "internals.h"
18 static struct proc_dir_entry *root_irq_dir;
20 #ifdef CONFIG_SMP
22 static int irq_affinity_proc_show(struct seq_file *m, void *v)
24 struct irq_desc *desc = irq_to_desc((long)m->private);
25 const struct cpumask *mask = desc->affinity;
27 #ifdef CONFIG_GENERIC_PENDING_IRQ
28 if (desc->status & IRQ_MOVE_PENDING)
29 mask = desc->pending_mask;
30 #endif
31 seq_cpumask(m, mask);
32 seq_putc(m, '\n');
33 return 0;
36 #ifndef is_affinity_mask_valid
37 #define is_affinity_mask_valid(val) 1
38 #endif
40 int no_irq_affinity;
41 static ssize_t irq_affinity_proc_write(struct file *file,
42 const char __user *buffer, size_t count, loff_t *pos)
44 unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data;
45 cpumask_var_t new_value;
46 int err;
48 if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity ||
49 irq_balancing_disabled(irq))
50 return -EIO;
52 if (!alloc_cpumask_var(&new_value, GFP_KERNEL))
53 return -ENOMEM;
55 err = cpumask_parse_user(buffer, count, new_value);
56 if (err)
57 goto free_cpumask;
59 if (!is_affinity_mask_valid(new_value)) {
60 err = -EINVAL;
61 goto free_cpumask;
65 * Do not allow disabling IRQs completely - it's a too easy
66 * way to make the system unusable accidentally :-) At least
67 * one online CPU still has to be targeted.
69 if (!cpumask_intersects(new_value, cpu_online_mask)) {
70 /* Special case for empty set - allow the architecture
71 code to set default SMP affinity. */
72 err = irq_select_affinity_usr(irq) ? -EINVAL : count;
73 } else {
74 irq_set_affinity(irq, new_value);
75 err = count;
78 free_cpumask:
79 free_cpumask_var(new_value);
80 return err;
83 static int irq_affinity_proc_open(struct inode *inode, struct file *file)
85 return single_open(file, irq_affinity_proc_show, PDE(inode)->data);
88 static const struct file_operations irq_affinity_proc_fops = {
89 .open = irq_affinity_proc_open,
90 .read = seq_read,
91 .llseek = seq_lseek,
92 .release = single_release,
93 .write = irq_affinity_proc_write,
96 static int default_affinity_show(struct seq_file *m, void *v)
98 seq_cpumask(m, irq_default_affinity);
99 seq_putc(m, '\n');
100 return 0;
103 static ssize_t default_affinity_write(struct file *file,
104 const char __user *buffer, size_t count, loff_t *ppos)
106 cpumask_var_t new_value;
107 int err;
109 if (!alloc_cpumask_var(&new_value, GFP_KERNEL))
110 return -ENOMEM;
112 err = cpumask_parse_user(buffer, count, new_value);
113 if (err)
114 goto out;
116 if (!is_affinity_mask_valid(new_value)) {
117 err = -EINVAL;
118 goto out;
121 /* create /proc/irq/prof_cpu_mask */
122 create_prof_cpu_mask(root_irq_dir);
125 * Do not allow disabling IRQs completely - it's a too easy
126 * way to make the system unusable accidentally :-) At least
127 * one online CPU still has to be targeted.
129 if (!cpumask_intersects(new_value, cpu_online_mask)) {
130 err = -EINVAL;
131 goto out;
134 cpumask_copy(irq_default_affinity, new_value);
135 err = count;
137 out:
138 free_cpumask_var(new_value);
139 return err;
142 static int default_affinity_open(struct inode *inode, struct file *file)
144 return single_open(file, default_affinity_show, NULL);
147 static const struct file_operations default_affinity_proc_fops = {
148 .open = default_affinity_open,
149 .read = seq_read,
150 .llseek = seq_lseek,
151 .release = single_release,
152 .write = default_affinity_write,
154 #endif
156 static int irq_spurious_read(char *page, char **start, off_t off,
157 int count, int *eof, void *data)
159 struct irq_desc *desc = irq_to_desc((long) data);
160 return sprintf(page, "count %u\n"
161 "unhandled %u\n"
162 "last_unhandled %u ms\n",
163 desc->irq_count,
164 desc->irqs_unhandled,
165 jiffies_to_msecs(desc->last_unhandled));
168 #define MAX_NAMELEN 10
170 void register_irq_proc(unsigned int irq, struct irq_desc *desc)
172 char name [MAX_NAMELEN];
173 struct proc_dir_entry *entry;
175 if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
176 return;
178 memset(name, 0, MAX_NAMELEN);
179 sprintf(name, "%d", irq);
181 /* create /proc/irq/1234 */
182 desc->dir = proc_mkdir(name, root_irq_dir);
184 #ifdef CONFIG_SMP
185 /* create /proc/irq/<irq>/smp_affinity */
186 proc_create_data("smp_affinity", 0600, desc->dir,
187 &irq_affinity_proc_fops, (void *)(long)irq);
188 #endif
190 entry = create_proc_entry("spurious", 0444, desc->dir);
191 if (entry) {
192 entry->data = (void *)(long)irq;
193 entry->read_proc = irq_spurious_read;
197 #undef MAX_NAMELEN
199 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
201 if (action->threaded)
202 remove_proc_entry(action->threaded->name, action->dir);
203 if (action->dir) {
204 struct irq_desc *desc = irq_to_desc(irq);
206 remove_proc_entry(action->dir->name, desc->dir);
210 static void register_default_affinity_proc(void)
212 #ifdef CONFIG_SMP
213 proc_create("irq/default_smp_affinity", 0600, NULL,
214 &default_affinity_proc_fops);
215 #endif
218 #ifndef CONFIG_PREEMPT_RT
220 static int threaded_read_proc(char *page, char **start, off_t off,
221 int count, int *eof, void *data)
223 return sprintf(page, "%c\n",
224 ((struct irqaction *)data)->flags & IRQF_NODELAY ? '0' : '1');
227 static int threaded_write_proc(struct file *file, const char __user *buffer,
228 unsigned long count, void *data)
230 int c;
231 struct irqaction *action = data;
232 irq_desc_t *desc = irq_to_desc(action->irq);
234 if (get_user(c, buffer))
235 return -EFAULT;
236 if (c != '0' && c != '1')
237 return -EINVAL;
239 spin_lock_irq(&desc->lock);
241 if (c == '0')
242 action->flags |= IRQF_NODELAY;
243 if (c == '1')
244 action->flags &= ~IRQF_NODELAY;
245 recalculate_desc_flags(desc);
247 spin_unlock_irq(&desc->lock);
249 return 1;
252 #endif
254 #define MAX_NAMELEN 128
256 static int name_unique(unsigned int irq, struct irqaction *new_action)
258 struct irq_desc *desc = irq_to_desc(irq);
259 struct irqaction *action;
261 for (action = desc->action ; action; action = action->next)
262 if ((action != new_action) && action->name &&
263 !strcmp(new_action->name, action->name))
264 return 0;
265 return 1;
268 void register_handler_proc(unsigned int irq, struct irqaction *action)
270 char name [MAX_NAMELEN];
271 struct irq_desc *desc = irq_to_desc(irq);
273 if (!desc->dir || action->dir || !action->name ||
274 !name_unique(irq, action))
275 return;
277 memset(name, 0, MAX_NAMELEN);
278 snprintf(name, MAX_NAMELEN, "%s", action->name);
280 /* create /proc/irq/1234/handler/ */
281 action->dir = proc_mkdir(name, desc->dir);
283 if (!action->dir)
284 return;
285 #ifndef CONFIG_PREEMPT_RT
287 struct proc_dir_entry *entry;
288 /* create /proc/irq/1234/handler/threaded */
289 entry = create_proc_entry("threaded", 0600, action->dir);
290 if (!entry)
291 return;
292 entry->nlink = 1;
293 entry->data = (void *)action;
294 entry->read_proc = threaded_read_proc;
295 entry->write_proc = threaded_write_proc;
296 action->threaded = entry;
298 #endif
301 #undef MAX_NAMELEN
303 void init_irq_proc(void)
305 unsigned int irq;
306 struct irq_desc *desc;
308 /* create /proc/irq */
309 root_irq_dir = proc_mkdir("irq", NULL);
310 if (!root_irq_dir)
311 return;
313 register_default_affinity_proc();
316 * Create entries for all existing IRQs.
318 for_each_irq_desc(irq, desc) {
319 if (!desc)
320 continue;
322 register_irq_proc(irq, desc);