aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /kernel/irq/chip.c
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/include/asm/pda.h kernel/fork.c
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c114
1 files changed, 57 insertions, 57 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3cd441ebf5d2..6eb3c7952b64 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -27,13 +27,13 @@ void dynamic_irq_init(unsigned int irq)
27 struct irq_desc *desc; 27 struct irq_desc *desc;
28 unsigned long flags; 28 unsigned long flags;
29 29
30 if (irq >= NR_IRQS) { 30 desc = irq_to_desc(irq);
31 if (!desc) {
31 WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); 32 WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
32 return; 33 return;
33 } 34 }
34 35
35 /* Ensure we don't have left over values from a previous use of this irq */ 36 /* Ensure we don't have left over values from a previous use of this irq */
36 desc = irq_desc + irq;
37 spin_lock_irqsave(&desc->lock, flags); 37 spin_lock_irqsave(&desc->lock, flags);
38 desc->status = IRQ_DISABLED; 38 desc->status = IRQ_DISABLED;
39 desc->chip = &no_irq_chip; 39 desc->chip = &no_irq_chip;
@@ -57,15 +57,14 @@ void dynamic_irq_init(unsigned int irq)
57 */ 57 */
58void dynamic_irq_cleanup(unsigned int irq) 58void dynamic_irq_cleanup(unsigned int irq)
59{ 59{
60 struct irq_desc *desc; 60 struct irq_desc *desc = irq_to_desc(irq);
61 unsigned long flags; 61 unsigned long flags;
62 62
63 if (irq >= NR_IRQS) { 63 if (!desc) {
64 WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); 64 WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
65 return; 65 return;
66 } 66 }
67 67
68 desc = irq_desc + irq;
69 spin_lock_irqsave(&desc->lock, flags); 68 spin_lock_irqsave(&desc->lock, flags);
70 if (desc->action) { 69 if (desc->action) {
71 spin_unlock_irqrestore(&desc->lock, flags); 70 spin_unlock_irqrestore(&desc->lock, flags);
@@ -78,6 +77,7 @@ void dynamic_irq_cleanup(unsigned int irq)
78 desc->chip_data = NULL; 77 desc->chip_data = NULL;
79 desc->handle_irq = handle_bad_irq; 78 desc->handle_irq = handle_bad_irq;
80 desc->chip = &no_irq_chip; 79 desc->chip = &no_irq_chip;
80 desc->name = NULL;
81 spin_unlock_irqrestore(&desc->lock, flags); 81 spin_unlock_irqrestore(&desc->lock, flags);
82} 82}
83 83
@@ -89,10 +89,10 @@ void dynamic_irq_cleanup(unsigned int irq)
89 */ 89 */
90int set_irq_chip(unsigned int irq, struct irq_chip *chip) 90int set_irq_chip(unsigned int irq, struct irq_chip *chip)
91{ 91{
92 struct irq_desc *desc; 92 struct irq_desc *desc = irq_to_desc(irq);
93 unsigned long flags; 93 unsigned long flags;
94 94
95 if (irq >= NR_IRQS) { 95 if (!desc) {
96 WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); 96 WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
97 return -EINVAL; 97 return -EINVAL;
98 } 98 }
@@ -100,7 +100,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
100 if (!chip) 100 if (!chip)
101 chip = &no_irq_chip; 101 chip = &no_irq_chip;
102 102
103 desc = irq_desc + irq;
104 spin_lock_irqsave(&desc->lock, flags); 103 spin_lock_irqsave(&desc->lock, flags);
105 irq_chip_set_defaults(chip); 104 irq_chip_set_defaults(chip);
106 desc->chip = chip; 105 desc->chip = chip;
@@ -111,27 +110,28 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
111EXPORT_SYMBOL(set_irq_chip); 110EXPORT_SYMBOL(set_irq_chip);
112 111
113/** 112/**
114 * set_irq_type - set the irq type for an irq 113 * set_irq_type - set the irq trigger type for an irq
115 * @irq: irq number 114 * @irq: irq number
116 * @type: interrupt type - see include/linux/interrupt.h 115 * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
117 */ 116 */
118int set_irq_type(unsigned int irq, unsigned int type) 117int set_irq_type(unsigned int irq, unsigned int type)
119{ 118{
120 struct irq_desc *desc; 119 struct irq_desc *desc = irq_to_desc(irq);
121 unsigned long flags; 120 unsigned long flags;
122 int ret = -ENXIO; 121 int ret = -ENXIO;
123 122
124 if (irq >= NR_IRQS) { 123 if (!desc) {
125 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); 124 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
126 return -ENODEV; 125 return -ENODEV;
127 } 126 }
128 127
129 desc = irq_desc + irq; 128 type &= IRQ_TYPE_SENSE_MASK;
130 if (desc->chip->set_type) { 129 if (type == IRQ_TYPE_NONE)
131 spin_lock_irqsave(&desc->lock, flags); 130 return 0;
132 ret = desc->chip->set_type(irq, type); 131
133 spin_unlock_irqrestore(&desc->lock, flags); 132 spin_lock_irqsave(&desc->lock, flags);
134 } 133 ret = __irq_set_trigger(desc, irq, type);
134 spin_unlock_irqrestore(&desc->lock, flags);
135 return ret; 135 return ret;
136} 136}
137EXPORT_SYMBOL(set_irq_type); 137EXPORT_SYMBOL(set_irq_type);
@@ -145,16 +145,15 @@ EXPORT_SYMBOL(set_irq_type);
145 */ 145 */
146int set_irq_data(unsigned int irq, void *data) 146int set_irq_data(unsigned int irq, void *data)
147{ 147{
148 struct irq_desc *desc; 148 struct irq_desc *desc = irq_to_desc(irq);
149 unsigned long flags; 149 unsigned long flags;
150 150
151 if (irq >= NR_IRQS) { 151 if (!desc) {
152 printk(KERN_ERR 152 printk(KERN_ERR
153 "Trying to install controller data for IRQ%d\n", irq); 153 "Trying to install controller data for IRQ%d\n", irq);
154 return -EINVAL; 154 return -EINVAL;
155 } 155 }
156 156
157 desc = irq_desc + irq;
158 spin_lock_irqsave(&desc->lock, flags); 157 spin_lock_irqsave(&desc->lock, flags);
159 desc->handler_data = data; 158 desc->handler_data = data;
160 spin_unlock_irqrestore(&desc->lock, flags); 159 spin_unlock_irqrestore(&desc->lock, flags);
@@ -171,15 +170,15 @@ EXPORT_SYMBOL(set_irq_data);
171 */ 170 */
172int set_irq_msi(unsigned int irq, struct msi_desc *entry) 171int set_irq_msi(unsigned int irq, struct msi_desc *entry)
173{ 172{
174 struct irq_desc *desc; 173 struct irq_desc *desc = irq_to_desc(irq);
175 unsigned long flags; 174 unsigned long flags;
176 175
177 if (irq >= NR_IRQS) { 176 if (!desc) {
178 printk(KERN_ERR 177 printk(KERN_ERR
179 "Trying to install msi data for IRQ%d\n", irq); 178 "Trying to install msi data for IRQ%d\n", irq);
180 return -EINVAL; 179 return -EINVAL;
181 } 180 }
182 desc = irq_desc + irq; 181
183 spin_lock_irqsave(&desc->lock, flags); 182 spin_lock_irqsave(&desc->lock, flags);
184 desc->msi_desc = entry; 183 desc->msi_desc = entry;
185 if (entry) 184 if (entry)
@@ -197,10 +196,16 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
197 */ 196 */
198int set_irq_chip_data(unsigned int irq, void *data) 197int set_irq_chip_data(unsigned int irq, void *data)
199{ 198{
200 struct irq_desc *desc = irq_desc + irq; 199 struct irq_desc *desc = irq_to_desc(irq);
201 unsigned long flags; 200 unsigned long flags;
202 201
203 if (irq >= NR_IRQS || !desc->chip) { 202 if (!desc) {
203 printk(KERN_ERR
204 "Trying to install chip data for IRQ%d\n", irq);
205 return -EINVAL;
206 }
207
208 if (!desc->chip) {
204 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); 209 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
205 return -EINVAL; 210 return -EINVAL;
206 } 211 }
@@ -218,7 +223,7 @@ EXPORT_SYMBOL(set_irq_chip_data);
218 */ 223 */
219static void default_enable(unsigned int irq) 224static void default_enable(unsigned int irq)
220{ 225{
221 struct irq_desc *desc = irq_desc + irq; 226 struct irq_desc *desc = irq_to_desc(irq);
222 227
223 desc->chip->unmask(irq); 228 desc->chip->unmask(irq);
224 desc->status &= ~IRQ_MASKED; 229 desc->status &= ~IRQ_MASKED;
@@ -236,8 +241,9 @@ static void default_disable(unsigned int irq)
236 */ 241 */
237static unsigned int default_startup(unsigned int irq) 242static unsigned int default_startup(unsigned int irq)
238{ 243{
239 irq_desc[irq].chip->enable(irq); 244 struct irq_desc *desc = irq_to_desc(irq);
240 245
246 desc->chip->enable(irq);
241 return 0; 247 return 0;
242} 248}
243 249
@@ -246,7 +252,7 @@ static unsigned int default_startup(unsigned int irq)
246 */ 252 */
247static void default_shutdown(unsigned int irq) 253static void default_shutdown(unsigned int irq)
248{ 254{
249 struct irq_desc *desc = irq_desc + irq; 255 struct irq_desc *desc = irq_to_desc(irq);
250 256
251 desc->chip->mask(irq); 257 desc->chip->mask(irq);
252 desc->status |= IRQ_MASKED; 258 desc->status |= IRQ_MASKED;
@@ -305,14 +311,13 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
305{ 311{
306 struct irqaction *action; 312 struct irqaction *action;
307 irqreturn_t action_ret; 313 irqreturn_t action_ret;
308 const unsigned int cpu = smp_processor_id();
309 314
310 spin_lock(&desc->lock); 315 spin_lock(&desc->lock);
311 316
312 if (unlikely(desc->status & IRQ_INPROGRESS)) 317 if (unlikely(desc->status & IRQ_INPROGRESS))
313 goto out_unlock; 318 goto out_unlock;
314 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 319 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
315 kstat_cpu(cpu).irqs[irq]++; 320 kstat_incr_irqs_this_cpu(irq, desc);
316 321
317 action = desc->action; 322 action = desc->action;
318 if (unlikely(!action || (desc->status & IRQ_DISABLED))) 323 if (unlikely(!action || (desc->status & IRQ_DISABLED)))
@@ -344,17 +349,17 @@ out_unlock:
344void 349void
345handle_level_irq(unsigned int irq, struct irq_desc *desc) 350handle_level_irq(unsigned int irq, struct irq_desc *desc)
346{ 351{
347 unsigned int cpu = smp_processor_id();
348 struct irqaction *action; 352 struct irqaction *action;
349 irqreturn_t action_ret; 353 irqreturn_t action_ret;
350 354
351 spin_lock(&desc->lock); 355 spin_lock(&desc->lock);
352 mask_ack_irq(desc, irq); 356 mask_ack_irq(desc, irq);
357 desc = irq_remap_to_desc(irq, desc);
353 358
354 if (unlikely(desc->status & IRQ_INPROGRESS)) 359 if (unlikely(desc->status & IRQ_INPROGRESS))
355 goto out_unlock; 360 goto out_unlock;
356 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 361 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
357 kstat_cpu(cpu).irqs[irq]++; 362 kstat_incr_irqs_this_cpu(irq, desc);
358 363
359 /* 364 /*
360 * If its disabled or no action available 365 * If its disabled or no action available
@@ -392,7 +397,6 @@ out_unlock:
392void 397void
393handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) 398handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
394{ 399{
395 unsigned int cpu = smp_processor_id();
396 struct irqaction *action; 400 struct irqaction *action;
397 irqreturn_t action_ret; 401 irqreturn_t action_ret;
398 402
@@ -402,7 +406,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
402 goto out; 406 goto out;
403 407
404 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 408 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
405 kstat_cpu(cpu).irqs[irq]++; 409 kstat_incr_irqs_this_cpu(irq, desc);
406 410
407 /* 411 /*
408 * If its disabled or no action available 412 * If its disabled or no action available
@@ -428,6 +432,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
428 desc->status &= ~IRQ_INPROGRESS; 432 desc->status &= ~IRQ_INPROGRESS;
429out: 433out:
430 desc->chip->eoi(irq); 434 desc->chip->eoi(irq);
435 desc = irq_remap_to_desc(irq, desc);
431 436
432 spin_unlock(&desc->lock); 437 spin_unlock(&desc->lock);
433} 438}
@@ -451,8 +456,6 @@ out:
451void 456void
452handle_edge_irq(unsigned int irq, struct irq_desc *desc) 457handle_edge_irq(unsigned int irq, struct irq_desc *desc)
453{ 458{
454 const unsigned int cpu = smp_processor_id();
455
456 spin_lock(&desc->lock); 459 spin_lock(&desc->lock);
457 460
458 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 461 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -466,13 +469,14 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
466 !desc->action)) { 469 !desc->action)) {
467 desc->status |= (IRQ_PENDING | IRQ_MASKED); 470 desc->status |= (IRQ_PENDING | IRQ_MASKED);
468 mask_ack_irq(desc, irq); 471 mask_ack_irq(desc, irq);
472 desc = irq_remap_to_desc(irq, desc);
469 goto out_unlock; 473 goto out_unlock;
470 } 474 }
471 475 kstat_incr_irqs_this_cpu(irq, desc);
472 kstat_cpu(cpu).irqs[irq]++;
473 476
474 /* Start handling the irq */ 477 /* Start handling the irq */
475 desc->chip->ack(irq); 478 desc->chip->ack(irq);
479 desc = irq_remap_to_desc(irq, desc);
476 480
477 /* Mark the IRQ currently in progress.*/ 481 /* Mark the IRQ currently in progress.*/
478 desc->status |= IRQ_INPROGRESS; 482 desc->status |= IRQ_INPROGRESS;
@@ -524,7 +528,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
524{ 528{
525 irqreturn_t action_ret; 529 irqreturn_t action_ret;
526 530
527 kstat_this_cpu.irqs[irq]++; 531 kstat_incr_irqs_this_cpu(irq, desc);
528 532
529 if (desc->chip->ack) 533 if (desc->chip->ack)
530 desc->chip->ack(irq); 534 desc->chip->ack(irq);
@@ -533,25 +537,25 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
533 if (!noirqdebug) 537 if (!noirqdebug)
534 note_interrupt(irq, desc, action_ret); 538 note_interrupt(irq, desc, action_ret);
535 539
536 if (desc->chip->eoi) 540 if (desc->chip->eoi) {
537 desc->chip->eoi(irq); 541 desc->chip->eoi(irq);
542 desc = irq_remap_to_desc(irq, desc);
543 }
538} 544}
539 545
540void 546void
541__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 547__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
542 const char *name) 548 const char *name)
543{ 549{
544 struct irq_desc *desc; 550 struct irq_desc *desc = irq_to_desc(irq);
545 unsigned long flags; 551 unsigned long flags;
546 552
547 if (irq >= NR_IRQS) { 553 if (!desc) {
548 printk(KERN_ERR 554 printk(KERN_ERR
549 "Trying to install type control for IRQ%d\n", irq); 555 "Trying to install type control for IRQ%d\n", irq);
550 return; 556 return;
551 } 557 }
552 558
553 desc = irq_desc + irq;
554
555 if (!handle) 559 if (!handle)
556 handle = handle_bad_irq; 560 handle = handle_bad_irq;
557 else if (desc->chip == &no_irq_chip) { 561 else if (desc->chip == &no_irq_chip) {
@@ -571,8 +575,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
571 575
572 /* Uninstall? */ 576 /* Uninstall? */
573 if (handle == handle_bad_irq) { 577 if (handle == handle_bad_irq) {
574 if (desc->chip != &no_irq_chip) 578 if (desc->chip != &no_irq_chip) {
575 mask_ack_irq(desc, irq); 579 mask_ack_irq(desc, irq);
580 desc = irq_remap_to_desc(irq, desc);
581 }
576 desc->status |= IRQ_DISABLED; 582 desc->status |= IRQ_DISABLED;
577 desc->depth = 1; 583 desc->depth = 1;
578 } 584 }
@@ -583,7 +589,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
583 desc->status &= ~IRQ_DISABLED; 589 desc->status &= ~IRQ_DISABLED;
584 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; 590 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
585 desc->depth = 0; 591 desc->depth = 0;
586 desc->chip->unmask(irq); 592 desc->chip->startup(irq);
587 } 593 }
588 spin_unlock_irqrestore(&desc->lock, flags); 594 spin_unlock_irqrestore(&desc->lock, flags);
589} 595}
@@ -606,17 +612,14 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
606 612
607void __init set_irq_noprobe(unsigned int irq) 613void __init set_irq_noprobe(unsigned int irq)
608{ 614{
609 struct irq_desc *desc; 615 struct irq_desc *desc = irq_to_desc(irq);
610 unsigned long flags; 616 unsigned long flags;
611 617
612 if (irq >= NR_IRQS) { 618 if (!desc) {
613 printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); 619 printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
614
615 return; 620 return;
616 } 621 }
617 622
618 desc = irq_desc + irq;
619
620 spin_lock_irqsave(&desc->lock, flags); 623 spin_lock_irqsave(&desc->lock, flags);
621 desc->status |= IRQ_NOPROBE; 624 desc->status |= IRQ_NOPROBE;
622 spin_unlock_irqrestore(&desc->lock, flags); 625 spin_unlock_irqrestore(&desc->lock, flags);
@@ -624,17 +627,14 @@ void __init set_irq_noprobe(unsigned int irq)
624 627
625void __init set_irq_probe(unsigned int irq) 628void __init set_irq_probe(unsigned int irq)
626{ 629{
627 struct irq_desc *desc; 630 struct irq_desc *desc = irq_to_desc(irq);
628 unsigned long flags; 631 unsigned long flags;
629 632
630 if (irq >= NR_IRQS) { 633 if (!desc) {
631 printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); 634 printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
632
633 return; 635 return;
634 } 636 }
635 637
636 desc = irq_desc + irq;
637
638 spin_lock_irqsave(&desc->lock, flags); 638 spin_lock_irqsave(&desc->lock, flags);
639 desc->status &= ~IRQ_NOPROBE; 639 desc->status &= ~IRQ_NOPROBE;
640 spin_unlock_irqrestore(&desc->lock, flags); 640 spin_unlock_irqrestore(&desc->lock, flags);