xref: /linux/kernel/irq/proc.c (revision 367b8112fe2ea5c39a7bb4d263dcdd9b612fae18)
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/seq_file.h>
12 #include <linux/interrupt.h>
13 
14 #include "internals.h"
15 
16 static struct proc_dir_entry *root_irq_dir;
17 
18 #ifdef CONFIG_SMP
19 
20 static int irq_affinity_proc_show(struct seq_file *m, void *v)
21 {
22 	struct irq_desc *desc = irq_to_desc((long)m->private);
23 	cpumask_t *mask = &desc->affinity;
24 
25 #ifdef CONFIG_GENERIC_PENDING_IRQ
26 	if (desc->status & IRQ_MOVE_PENDING)
27 		mask = &desc->pending_mask;
28 #endif
29 	seq_cpumask(m, mask);
30 	seq_putc(m, '\n');
31 	return 0;
32 }
33 
34 #ifndef is_affinity_mask_valid
35 #define is_affinity_mask_valid(val) 1
36 #endif
37 
38 int no_irq_affinity;
39 static ssize_t irq_affinity_proc_write(struct file *file,
40 		const char __user *buffer, size_t count, loff_t *pos)
41 {
42 	unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data;
43 	cpumask_t new_value;
44 	int err;
45 
46 	if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity ||
47 	    irq_balancing_disabled(irq))
48 		return -EIO;
49 
50 	err = cpumask_parse_user(buffer, count, new_value);
51 	if (err)
52 		return err;
53 
54 	if (!is_affinity_mask_valid(new_value))
55 		return -EINVAL;
56 
57 	/*
58 	 * Do not allow disabling IRQs completely - it's a too easy
59 	 * way to make the system unusable accidentally :-) At least
60 	 * one online CPU still has to be targeted.
61 	 */
62 	if (!cpus_intersects(new_value, cpu_online_map))
63 		/* Special case for empty set - allow the architecture
64 		   code to set default SMP affinity. */
65 		return irq_select_affinity(irq) ? -EINVAL : count;
66 
67 	irq_set_affinity(irq, new_value);
68 
69 	return count;
70 }
71 
72 static int irq_affinity_proc_open(struct inode *inode, struct file *file)
73 {
74 	return single_open(file, irq_affinity_proc_show, PDE(inode)->data);
75 }
76 
77 static const struct file_operations irq_affinity_proc_fops = {
78 	.open		= irq_affinity_proc_open,
79 	.read		= seq_read,
80 	.llseek		= seq_lseek,
81 	.release	= single_release,
82 	.write		= irq_affinity_proc_write,
83 };
84 
85 static int default_affinity_show(struct seq_file *m, void *v)
86 {
87 	seq_cpumask(m, &irq_default_affinity);
88 	seq_putc(m, '\n');
89 	return 0;
90 }
91 
92 static ssize_t default_affinity_write(struct file *file,
93 		const char __user *buffer, size_t count, loff_t *ppos)
94 {
95 	cpumask_t new_value;
96 	int err;
97 
98 	err = cpumask_parse_user(buffer, count, new_value);
99 	if (err)
100 		return err;
101 
102 	if (!is_affinity_mask_valid(new_value))
103 		return -EINVAL;
104 
105 	/*
106 	 * Do not allow disabling IRQs completely - it's a too easy
107 	 * way to make the system unusable accidentally :-) At least
108 	 * one online CPU still has to be targeted.
109 	 */
110 	if (!cpus_intersects(new_value, cpu_online_map))
111 		return -EINVAL;
112 
113 	irq_default_affinity = new_value;
114 
115 	return count;
116 }
117 
118 static int default_affinity_open(struct inode *inode, struct file *file)
119 {
120 	return single_open(file, default_affinity_show, NULL);
121 }
122 
123 static const struct file_operations default_affinity_proc_fops = {
124 	.open		= default_affinity_open,
125 	.read		= seq_read,
126 	.llseek		= seq_lseek,
127 	.release	= single_release,
128 	.write		= default_affinity_write,
129 };
130 #endif
131 
132 static int irq_spurious_read(char *page, char **start, off_t off,
133 				  int count, int *eof, void *data)
134 {
135 	struct irq_desc *desc = irq_to_desc((long) data);
136 	return sprintf(page, "count %u\n"
137 			     "unhandled %u\n"
138 			     "last_unhandled %u ms\n",
139 			desc->irq_count,
140 			desc->irqs_unhandled,
141 			jiffies_to_msecs(desc->last_unhandled));
142 }
143 
144 #define MAX_NAMELEN 128
145 
146 static int name_unique(unsigned int irq, struct irqaction *new_action)
147 {
148 	struct irq_desc *desc = irq_to_desc(irq);
149 	struct irqaction *action;
150 	unsigned long flags;
151 	int ret = 1;
152 
153 	spin_lock_irqsave(&desc->lock, flags);
154 	for (action = desc->action ; action; action = action->next) {
155 		if ((action != new_action) && action->name &&
156 				!strcmp(new_action->name, action->name)) {
157 			ret = 0;
158 			break;
159 		}
160 	}
161 	spin_unlock_irqrestore(&desc->lock, flags);
162 	return ret;
163 }
164 
165 void register_handler_proc(unsigned int irq, struct irqaction *action)
166 {
167 	char name [MAX_NAMELEN];
168 	struct irq_desc *desc = irq_to_desc(irq);
169 
170 	if (!desc->dir || action->dir || !action->name ||
171 					!name_unique(irq, action))
172 		return;
173 
174 	memset(name, 0, MAX_NAMELEN);
175 	snprintf(name, MAX_NAMELEN, "%s", action->name);
176 
177 	/* create /proc/irq/1234/handler/ */
178 	action->dir = proc_mkdir(name, desc->dir);
179 }
180 
181 #undef MAX_NAMELEN
182 
183 #define MAX_NAMELEN 10
184 
185 void register_irq_proc(unsigned int irq, struct irq_desc *desc)
186 {
187 	char name [MAX_NAMELEN];
188 	struct proc_dir_entry *entry;
189 
190 	if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
191 		return;
192 
193 	memset(name, 0, MAX_NAMELEN);
194 	sprintf(name, "%d", irq);
195 
196 	/* create /proc/irq/1234 */
197 	desc->dir = proc_mkdir(name, root_irq_dir);
198 
199 #ifdef CONFIG_SMP
200 	/* create /proc/irq/<irq>/smp_affinity */
201 	proc_create_data("smp_affinity", 0600, desc->dir,
202 			 &irq_affinity_proc_fops, (void *)(long)irq);
203 #endif
204 
205 	entry = create_proc_entry("spurious", 0444, desc->dir);
206 	if (entry) {
207 		entry->data = (void *)(long)irq;
208 		entry->read_proc = irq_spurious_read;
209 	}
210 }
211 
212 #undef MAX_NAMELEN
213 
214 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
215 {
216 	if (action->dir) {
217 		struct irq_desc *desc = irq_to_desc(irq);
218 
219 		remove_proc_entry(action->dir->name, desc->dir);
220 	}
221 }
222 
223 static void register_default_affinity_proc(void)
224 {
225 #ifdef CONFIG_SMP
226 	proc_create("irq/default_smp_affinity", 0600, NULL,
227 		    &default_affinity_proc_fops);
228 #endif
229 }
230 
231 void init_irq_proc(void)
232 {
233 	unsigned int irq;
234 	struct irq_desc *desc;
235 
236 	/* create /proc/irq */
237 	root_irq_dir = proc_mkdir("irq", NULL);
238 	if (!root_irq_dir)
239 		return;
240 
241 	register_default_affinity_proc();
242 
243 	/*
244 	 * Create entries for all existing IRQs.
245 	 */
246 	for_each_irq_desc(irq, desc)
247 		register_irq_proc(irq, desc);
248 }
249 
250