Blame view
kernel/irq/proc.c
11.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 |
/* * linux/kernel/irq/proc.c * * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar * * This file contains the /proc/irq/ handling code. */ #include <linux/irq.h> |
5a0e3ad6a include cleanup: ... |
10 |
#include <linux/gfp.h> |
1da177e4c Linux-2.6.12-rc2 |
11 |
#include <linux/proc_fs.h> |
f18e439d1 genirq: switch /p... |
12 |
#include <linux/seq_file.h> |
1da177e4c Linux-2.6.12-rc2 |
13 |
#include <linux/interrupt.h> |
c78b9b65f genirq: Implement... |
14 |
#include <linux/kernel_stat.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
|
97a41e261 [PATCH] kernel/: ... |
16 |
#include "internals.h" |
c291ee622 genirq: Prevent p... |
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* * Access rules: * * procfs protects read/write of /proc/irq/N/ files against a * concurrent free of the interrupt descriptor. remove_proc_entry() * immediately prevents new read/writes to happen and waits for * already running read/write functions to complete. * * We remove the proc entries first and then delete the interrupt * descriptor from the radix tree and free it. So it is guaranteed * that irq_to_desc(N) is valid as long as the read/writes are * permitted by procfs. * * The read from /proc/interrupts is a different problem because there * is no protection. So the lookup and the access to irqdesc * information must be protected by sparse_irq_lock. */ |
4a733ee12 [PATCH] genirq: c... |
34 |
static struct proc_dir_entry *root_irq_dir; |
1da177e4c Linux-2.6.12-rc2 |
35 36 |
#ifdef CONFIG_SMP |
4b060420a bitmap, irq: add ... |
37 |
static int show_irq_affinity(int type, struct seq_file *m, void *v) |
1da177e4c Linux-2.6.12-rc2 |
38 |
{ |
08678b084 generic: sparse i... |
39 |
struct irq_desc *desc = irq_to_desc((long)m->private); |
6b8ff3120 genirq: Convert c... |
40 |
const struct cpumask *mask = desc->irq_data.affinity; |
42ee2b741 x86_64: Report th... |
41 42 |
#ifdef CONFIG_GENERIC_PENDING_IRQ |
f230b6d5c genirq: Add IRQ_M... |
43 |
if (irqd_is_setaffinity_pending(&desc->irq_data)) |
7f7ace0cd cpumask: update i... |
44 |
mask = desc->pending_mask; |
42ee2b741 x86_64: Report th... |
45 |
#endif |
4b060420a bitmap, irq: add ... |
46 47 48 49 |
if (type) seq_cpumask_list(m, mask); else seq_cpumask(m, mask); |
f18e439d1 genirq: switch /p... |
50 51 52 |
seq_putc(m, ' '); return 0; |
1da177e4c Linux-2.6.12-rc2 |
53 |
} |
e7a297b0d genirq: Add CPU m... |
54 55 56 57 58 |
static int irq_affinity_hint_proc_show(struct seq_file *m, void *v) { struct irq_desc *desc = irq_to_desc((long)m->private); unsigned long flags; cpumask_var_t mask; |
4308ad801 genirq: Clear CPU... |
59 |
if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) |
e7a297b0d genirq: Add CPU m... |
60 61 62 63 64 |
return -ENOMEM; raw_spin_lock_irqsave(&desc->lock, flags); if (desc->affinity_hint) cpumask_copy(mask, desc->affinity_hint); |
e7a297b0d genirq: Add CPU m... |
65 66 67 68 69 70 71 72 73 |
raw_spin_unlock_irqrestore(&desc->lock, flags); seq_cpumask(m, mask); seq_putc(m, ' '); free_cpumask_var(mask); return 0; } |
25d61578d [IA64] SN: valida... |
74 75 76 |
#ifndef is_affinity_mask_valid #define is_affinity_mask_valid(val) 1 #endif |
1da177e4c Linux-2.6.12-rc2 |
77 |
int no_irq_affinity; |
4b060420a bitmap, irq: add ... |
78 79 80 81 82 83 84 85 86 87 88 89 |
static int irq_affinity_proc_show(struct seq_file *m, void *v) { return show_irq_affinity(0, m, v); } static int irq_affinity_list_proc_show(struct seq_file *m, void *v) { return show_irq_affinity(1, m, v); } static ssize_t write_irq_affinity(int type, struct file *file, |
f18e439d1 genirq: switch /p... |
90 |
const char __user *buffer, size_t count, loff_t *pos) |
1da177e4c Linux-2.6.12-rc2 |
91 |
{ |
d9dda78ba procfs: new helpe... |
92 |
unsigned int irq = (int)(long)PDE_DATA(file_inode(file)); |
0de26520c cpumask: make irq... |
93 |
cpumask_var_t new_value; |
f18e439d1 genirq: switch /p... |
94 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
95 |
|
bce43032a genirq: Reuse exi... |
96 |
if (!irq_can_set_affinity(irq) || no_irq_affinity) |
1da177e4c Linux-2.6.12-rc2 |
97 |
return -EIO; |
0de26520c cpumask: make irq... |
98 99 |
if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) return -ENOMEM; |
4b060420a bitmap, irq: add ... |
100 101 102 103 |
if (type) err = cpumask_parselist_user(buffer, count, new_value); else err = cpumask_parse_user(buffer, count, new_value); |
1da177e4c Linux-2.6.12-rc2 |
104 |
if (err) |
0de26520c cpumask: make irq... |
105 |
goto free_cpumask; |
1da177e4c Linux-2.6.12-rc2 |
106 |
|
6bdf197b0 ia64: cpumask fix... |
107 |
if (!is_affinity_mask_valid(new_value)) { |
0de26520c cpumask: make irq... |
108 109 110 |
err = -EINVAL; goto free_cpumask; } |
25d61578d [IA64] SN: valida... |
111 |
|
1da177e4c Linux-2.6.12-rc2 |
112 113 114 115 116 |
/* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ |
0de26520c cpumask: make irq... |
117 |
if (!cpumask_intersects(new_value, cpu_online_mask)) { |
eee45269b [PATCH] Alpha: co... |
118 119 |
/* Special case for empty set - allow the architecture code to set default SMP affinity. */ |
3b8249e75 genirq: Do not co... |
120 |
err = irq_select_affinity_usr(irq, new_value) ? -EINVAL : count; |
0de26520c cpumask: make irq... |
121 122 123 124 125 126 127 128 |
} else { irq_set_affinity(irq, new_value); err = count; } free_cpumask: free_cpumask_var(new_value); return err; |
1da177e4c Linux-2.6.12-rc2 |
129 |
} |
4b060420a bitmap, irq: add ... |
130 131 132 133 134 135 136 137 138 139 140 |
static ssize_t irq_affinity_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { return write_irq_affinity(0, file, buffer, count, pos); } static ssize_t irq_affinity_list_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { return write_irq_affinity(1, file, buffer, count, pos); } |
f18e439d1 genirq: switch /p... |
141 |
static int irq_affinity_proc_open(struct inode *inode, struct file *file) |
184047567 genirq: Expose de... |
142 |
{ |
d9dda78ba procfs: new helpe... |
143 |
return single_open(file, irq_affinity_proc_show, PDE_DATA(inode)); |
184047567 genirq: Expose de... |
144 |
} |
4b060420a bitmap, irq: add ... |
145 146 |
static int irq_affinity_list_proc_open(struct inode *inode, struct file *file) { |
d9dda78ba procfs: new helpe... |
147 |
return single_open(file, irq_affinity_list_proc_show, PDE_DATA(inode)); |
4b060420a bitmap, irq: add ... |
148 |
} |
e7a297b0d genirq: Add CPU m... |
149 150 |
static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file) { |
d9dda78ba procfs: new helpe... |
151 |
return single_open(file, irq_affinity_hint_proc_show, PDE_DATA(inode)); |
e7a297b0d genirq: Add CPU m... |
152 |
} |
f18e439d1 genirq: switch /p... |
153 154 155 156 157 158 159 |
static const struct file_operations irq_affinity_proc_fops = { .open = irq_affinity_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = irq_affinity_proc_write, }; |
e7a297b0d genirq: Add CPU m... |
160 161 162 163 164 165 |
static const struct file_operations irq_affinity_hint_proc_fops = { .open = irq_affinity_hint_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
4b060420a bitmap, irq: add ... |
166 167 168 169 170 171 172 |
static const struct file_operations irq_affinity_list_proc_fops = { .open = irq_affinity_list_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = irq_affinity_list_proc_write, }; |
f18e439d1 genirq: switch /p... |
173 174 |
static int default_affinity_show(struct seq_file *m, void *v) { |
d036e67b4 cpumask: convert ... |
175 |
seq_cpumask(m, irq_default_affinity); |
f18e439d1 genirq: switch /p... |
176 177 178 179 180 181 182 |
seq_putc(m, ' '); return 0; } static ssize_t default_affinity_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
184047567 genirq: Expose de... |
183 |
{ |
d036e67b4 cpumask: convert ... |
184 |
cpumask_var_t new_value; |
f18e439d1 genirq: switch /p... |
185 |
int err; |
184047567 genirq: Expose de... |
186 |
|
d036e67b4 cpumask: convert ... |
187 188 189 190 |
if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) return -ENOMEM; err = cpumask_parse_user(buffer, count, new_value); |
184047567 genirq: Expose de... |
191 |
if (err) |
d036e67b4 cpumask: convert ... |
192 |
goto out; |
184047567 genirq: Expose de... |
193 |
|
d036e67b4 cpumask: convert ... |
194 195 196 197 |
if (!is_affinity_mask_valid(new_value)) { err = -EINVAL; goto out; } |
184047567 genirq: Expose de... |
198 199 200 201 202 203 |
/* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ |
d036e67b4 cpumask: convert ... |
204 205 206 207 |
if (!cpumask_intersects(new_value, cpu_online_mask)) { err = -EINVAL; goto out; } |
184047567 genirq: Expose de... |
208 |
|
d036e67b4 cpumask: convert ... |
209 210 |
cpumask_copy(irq_default_affinity, new_value); err = count; |
184047567 genirq: Expose de... |
211 |
|
d036e67b4 cpumask: convert ... |
212 213 214 |
out: free_cpumask_var(new_value); return err; |
184047567 genirq: Expose de... |
215 |
} |
f18e439d1 genirq: switch /p... |
216 217 218 |
static int default_affinity_open(struct inode *inode, struct file *file) { |
d9dda78ba procfs: new helpe... |
219 |
return single_open(file, default_affinity_show, PDE_DATA(inode)); |
f18e439d1 genirq: switch /p... |
220 221 222 223 224 225 226 227 228 |
} static const struct file_operations default_affinity_proc_fops = { .open = default_affinity_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = default_affinity_write, }; |
92d6b71ab genirq: Expose ir... |
229 230 231 232 |
static int irq_node_proc_show(struct seq_file *m, void *v) { struct irq_desc *desc = irq_to_desc((long) m->private); |
6b8ff3120 genirq: Convert c... |
233 234 |
seq_printf(m, "%d ", desc->irq_data.node); |
92d6b71ab genirq: Expose ir... |
235 236 237 238 239 |
return 0; } static int irq_node_proc_open(struct inode *inode, struct file *file) { |
d9dda78ba procfs: new helpe... |
240 |
return single_open(file, irq_node_proc_show, PDE_DATA(inode)); |
92d6b71ab genirq: Expose ir... |
241 242 243 244 245 246 247 248 |
} static const struct file_operations irq_node_proc_fops = { .open = irq_node_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
1da177e4c Linux-2.6.12-rc2 |
249 |
#endif |
a1afb6371 genirq: switch /p... |
250 |
static int irq_spurious_proc_show(struct seq_file *m, void *v) |
96d97cf03 x86: add /proc/ir... |
251 |
{ |
a1afb6371 genirq: switch /p... |
252 253 254 255 256 257 258 259 260 261 262 263 264 |
struct irq_desc *desc = irq_to_desc((long) m->private); seq_printf(m, "count %u " "unhandled %u " "last_unhandled %u ms ", desc->irq_count, desc->irqs_unhandled, jiffies_to_msecs(desc->last_unhandled)); return 0; } static int irq_spurious_proc_open(struct inode *inode, struct file *file) { |
d9dda78ba procfs: new helpe... |
265 |
return single_open(file, irq_spurious_proc_show, PDE_DATA(inode)); |
96d97cf03 x86: add /proc/ir... |
266 |
} |
a1afb6371 genirq: switch /p... |
267 268 269 270 271 272 |
static const struct file_operations irq_spurious_proc_fops = { .open = irq_spurious_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
1da177e4c Linux-2.6.12-rc2 |
273 274 275 276 |
#define MAX_NAMELEN 128 static int name_unique(unsigned int irq, struct irqaction *new_action) { |
08678b084 generic: sparse i... |
277 |
struct irq_desc *desc = irq_to_desc(irq); |
1da177e4c Linux-2.6.12-rc2 |
278 |
struct irqaction *action; |
d2d9433a4 kernel/irq/proc.c... |
279 280 |
unsigned long flags; int ret = 1; |
1da177e4c Linux-2.6.12-rc2 |
281 |
|
239007b84 genirq: Convert i... |
282 |
raw_spin_lock_irqsave(&desc->lock, flags); |
d2d9433a4 kernel/irq/proc.c... |
283 |
for (action = desc->action ; action; action = action->next) { |
1da177e4c Linux-2.6.12-rc2 |
284 |
if ((action != new_action) && action->name && |
d2d9433a4 kernel/irq/proc.c... |
285 286 287 288 289 |
!strcmp(new_action->name, action->name)) { ret = 0; break; } } |
239007b84 genirq: Convert i... |
290 |
raw_spin_unlock_irqrestore(&desc->lock, flags); |
d2d9433a4 kernel/irq/proc.c... |
291 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
292 293 294 295 296 |
} void register_handler_proc(unsigned int irq, struct irqaction *action) { char name [MAX_NAMELEN]; |
08678b084 generic: sparse i... |
297 |
struct irq_desc *desc = irq_to_desc(irq); |
1da177e4c Linux-2.6.12-rc2 |
298 |
|
08678b084 generic: sparse i... |
299 |
if (!desc->dir || action->dir || !action->name || |
1da177e4c Linux-2.6.12-rc2 |
300 301 302 303 304 305 306 |
!name_unique(irq, action)) return; memset(name, 0, MAX_NAMELEN); snprintf(name, MAX_NAMELEN, "%s", action->name); /* create /proc/irq/1234/handler/ */ |
08678b084 generic: sparse i... |
307 |
action->dir = proc_mkdir(name, desc->dir); |
1da177e4c Linux-2.6.12-rc2 |
308 309 310 311 312 |
} #undef MAX_NAMELEN #define MAX_NAMELEN 10 |
2c6927a38 irq: replace loop... |
313 |
void register_irq_proc(unsigned int irq, struct irq_desc *desc) |
1da177e4c Linux-2.6.12-rc2 |
314 315 |
{ char name [MAX_NAMELEN]; |
6b8ff3120 genirq: Convert c... |
316 |
if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip) || desc->dir) |
1da177e4c Linux-2.6.12-rc2 |
317 318 319 320 321 322 |
return; memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ |
08678b084 generic: sparse i... |
323 |
desc->dir = proc_mkdir(name, root_irq_dir); |
c82a43d40 irq: Do not attem... |
324 325 |
if (!desc->dir) return; |
1da177e4c Linux-2.6.12-rc2 |
326 327 |
#ifdef CONFIG_SMP |
f18e439d1 genirq: switch /p... |
328 |
/* create /proc/irq/<irq>/smp_affinity */ |
bab5c790c genirq: procfs: M... |
329 |
proc_create_data("smp_affinity", 0644, desc->dir, |
f18e439d1 genirq: switch /p... |
330 |
&irq_affinity_proc_fops, (void *)(long)irq); |
92d6b71ab genirq: Expose ir... |
331 |
|
e7a297b0d genirq: Add CPU m... |
332 |
/* create /proc/irq/<irq>/affinity_hint */ |
bab5c790c genirq: procfs: M... |
333 |
proc_create_data("affinity_hint", 0444, desc->dir, |
e7a297b0d genirq: Add CPU m... |
334 |
&irq_affinity_hint_proc_fops, (void *)(long)irq); |
4b060420a bitmap, irq: add ... |
335 |
/* create /proc/irq/<irq>/smp_affinity_list */ |
bab5c790c genirq: procfs: M... |
336 |
proc_create_data("smp_affinity_list", 0644, desc->dir, |
4b060420a bitmap, irq: add ... |
337 |
&irq_affinity_list_proc_fops, (void *)(long)irq); |
92d6b71ab genirq: Expose ir... |
338 339 |
proc_create_data("node", 0444, desc->dir, &irq_node_proc_fops, (void *)(long)irq); |
1da177e4c Linux-2.6.12-rc2 |
340 |
#endif |
96d97cf03 x86: add /proc/ir... |
341 |
|
a1afb6371 genirq: switch /p... |
342 343 |
proc_create_data("spurious", 0444, desc->dir, &irq_spurious_proc_fops, (void *)(long)irq); |
1da177e4c Linux-2.6.12-rc2 |
344 |
} |
13bfe99e0 genirq: Prepare p... |
345 346 347 348 349 350 351 352 353 |
void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) { char name [MAX_NAMELEN]; if (!root_irq_dir || !desc->dir) return; #ifdef CONFIG_SMP remove_proc_entry("smp_affinity", desc->dir); remove_proc_entry("affinity_hint", desc->dir); |
def945eeb irq: Remove smp_a... |
354 |
remove_proc_entry("smp_affinity_list", desc->dir); |
13bfe99e0 genirq: Prepare p... |
355 356 357 358 359 360 361 362 |
remove_proc_entry("node", desc->dir); #endif remove_proc_entry("spurious", desc->dir); memset(name, 0, MAX_NAMELEN); sprintf(name, "%u", irq); remove_proc_entry(name, root_irq_dir); } |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 |
#undef MAX_NAMELEN void unregister_handler_proc(unsigned int irq, struct irqaction *action) { |
a8ca16ea7 proc: Supply a fu... |
367 |
proc_remove(action->dir); |
1da177e4c Linux-2.6.12-rc2 |
368 |
} |
3786fc710 irq: make variabl... |
369 |
static void register_default_affinity_proc(void) |
184047567 genirq: Expose de... |
370 371 |
{ #ifdef CONFIG_SMP |
bab5c790c genirq: procfs: M... |
372 |
proc_create("irq/default_smp_affinity", 0644, NULL, |
f18e439d1 genirq: switch /p... |
373 |
&default_affinity_proc_fops); |
184047567 genirq: Expose de... |
374 375 |
#endif } |
1da177e4c Linux-2.6.12-rc2 |
376 377 |
void init_irq_proc(void) { |
2c6927a38 irq: replace loop... |
378 379 |
unsigned int irq; struct irq_desc *desc; |
1da177e4c Linux-2.6.12-rc2 |
380 381 382 383 384 |
/* create /proc/irq */ root_irq_dir = proc_mkdir("irq", NULL); if (!root_irq_dir) return; |
184047567 genirq: Expose de... |
385 |
register_default_affinity_proc(); |
1da177e4c Linux-2.6.12-rc2 |
386 387 388 |
/* * Create entries for all existing IRQs. */ |
0b8f1efad sparse irq_desc[]... |
389 390 391 |
for_each_irq_desc(irq, desc) { if (!desc) continue; |
2c6927a38 irq: replace loop... |
392 |
register_irq_proc(irq, desc); |
0b8f1efad sparse irq_desc[]... |
393 |
} |
1da177e4c Linux-2.6.12-rc2 |
394 |
} |
c78b9b65f genirq: Implement... |
395 396 397 398 399 400 |
#ifdef CONFIG_GENERIC_IRQ_SHOW int __weak arch_show_interrupts(struct seq_file *p, int prec) { return 0; } |
a6e120ed4 alpha: Use generi... |
401 402 403 |
#ifndef ACTUAL_NR_IRQS # define ACTUAL_NR_IRQS nr_irqs #endif |
c78b9b65f genirq: Implement... |
404 405 406 407 408 409 410 411 |
int show_interrupts(struct seq_file *p, void *v) { static int prec; unsigned long flags, any_count = 0; int i = *(loff_t *) v, j; struct irqaction *action; struct irq_desc *desc; |
a6e120ed4 alpha: Use generi... |
412 |
if (i > ACTUAL_NR_IRQS) |
c78b9b65f genirq: Implement... |
413 |
return 0; |
a6e120ed4 alpha: Use generi... |
414 |
if (i == ACTUAL_NR_IRQS) |
c78b9b65f genirq: Implement... |
415 416 417 418 419 420 421 422 423 424 425 426 427 |
return arch_show_interrupts(p, prec); /* print header and calculate the width of the first column */ if (i == 0) { for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) j *= 10; seq_printf(p, "%*s", prec + 8, ""); for_each_online_cpu(j) seq_printf(p, "CPU%-8d", j); seq_putc(p, ' '); } |
c291ee622 genirq: Prevent p... |
428 |
irq_lock_sparse(); |
c78b9b65f genirq: Implement... |
429 430 |
desc = irq_to_desc(i); if (!desc) |
c291ee622 genirq: Prevent p... |
431 |
goto outsparse; |
c78b9b65f genirq: Implement... |
432 433 434 435 436 437 438 439 440 441 442 |
raw_spin_lock_irqsave(&desc->lock, flags); for_each_online_cpu(j) any_count |= kstat_irqs_cpu(i, j); action = desc->action; if (!action && !any_count) goto out; seq_printf(p, "%*d: ", prec, i); for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
ab7798ffc genirq: Expand ge... |
443 444 445 446 447 448 449 450 451 452 453 |
if (desc->irq_data.chip) { if (desc->irq_data.chip->irq_print_chip) desc->irq_data.chip->irq_print_chip(&desc->irq_data, p); else if (desc->irq_data.chip->name) seq_printf(p, " %8s", desc->irq_data.chip->name); else seq_printf(p, " %8s", "-"); } else { seq_printf(p, " %8s", "None"); } |
c12d2f42a irqdomain: Includ... |
454 455 |
if (desc->irq_data.domain) seq_printf(p, " %*d", prec, (int) desc->irq_data.hwirq); |
94b2c363d genirq: Fix typo ... |
456 |
#ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL |
ab7798ffc genirq: Expand ge... |
457 458 |
seq_printf(p, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge"); #endif |
ee0401ec1 genirq: show_inte... |
459 460 |
if (desc->name) seq_printf(p, "-%-8s", desc->name); |
c78b9b65f genirq: Implement... |
461 462 463 464 465 466 467 468 469 470 471 |
if (action) { seq_printf(p, " %s", action->name); while ((action = action->next) != NULL) seq_printf(p, ", %s", action->name); } seq_putc(p, ' '); out: raw_spin_unlock_irqrestore(&desc->lock, flags); |
c291ee622 genirq: Prevent p... |
472 473 |
outsparse: irq_unlock_sparse(); |
c78b9b65f genirq: Implement... |
474 475 476 |
return 0; } #endif |