aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c114
1 files changed, 50 insertions, 64 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 964964baefa..10b5092e9bf 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -24,17 +24,15 @@
24 */ 24 */
25void dynamic_irq_init(unsigned int irq) 25void dynamic_irq_init(unsigned int irq)
26{ 26{
27 struct irq_desc *desc; 27 struct irq_desc *desc = irq_to_desc(irq);
28 unsigned long flags; 28 unsigned long flags;
29 29
30 if (irq >= NR_IRQS) { 30 if (!desc) {
31 printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); 31 WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
32 WARN_ON(1);
33 return; 32 return;
34 } 33 }
35 34
36 /* Ensure we don't have left over values from a previous use of this irq */ 35 /* Ensure we don't have left over values from a previous use of this irq */
37 desc = irq_desc + irq;
38 spin_lock_irqsave(&desc->lock, flags); 36 spin_lock_irqsave(&desc->lock, flags);
39 desc->status = IRQ_DISABLED; 37 desc->status = IRQ_DISABLED;
40 desc->chip = &no_irq_chip; 38 desc->chip = &no_irq_chip;
@@ -58,22 +56,19 @@ void dynamic_irq_init(unsigned int irq)
58 */ 56 */
59void dynamic_irq_cleanup(unsigned int irq) 57void dynamic_irq_cleanup(unsigned int irq)
60{ 58{
61 struct irq_desc *desc; 59 struct irq_desc *desc = irq_to_desc(irq);
62 unsigned long flags; 60 unsigned long flags;
63 61
64 if (irq >= NR_IRQS) { 62 if (!desc) {
65 printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); 63 WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
66 WARN_ON(1);
67 return; 64 return;
68 } 65 }
69 66
70 desc = irq_desc + irq;
71 spin_lock_irqsave(&desc->lock, flags); 67 spin_lock_irqsave(&desc->lock, flags);
72 if (desc->action) { 68 if (desc->action) {
73 spin_unlock_irqrestore(&desc->lock, flags); 69 spin_unlock_irqrestore(&desc->lock, flags);
74 printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n", 70 WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n",
75 irq); 71 irq);
76 WARN_ON(1);
77 return; 72 return;
78 } 73 }
79 desc->msi_desc = NULL; 74 desc->msi_desc = NULL;
@@ -81,6 +76,7 @@ void dynamic_irq_cleanup(unsigned int irq)
81 desc->chip_data = NULL; 76 desc->chip_data = NULL;
82 desc->handle_irq = handle_bad_irq; 77 desc->handle_irq = handle_bad_irq;
83 desc->chip = &no_irq_chip; 78 desc->chip = &no_irq_chip;
79 desc->name = NULL;
84 spin_unlock_irqrestore(&desc->lock, flags); 80 spin_unlock_irqrestore(&desc->lock, flags);
85} 81}
86 82
@@ -92,19 +88,17 @@ void dynamic_irq_cleanup(unsigned int irq)
92 */ 88 */
93int set_irq_chip(unsigned int irq, struct irq_chip *chip) 89int set_irq_chip(unsigned int irq, struct irq_chip *chip)
94{ 90{
95 struct irq_desc *desc; 91 struct irq_desc *desc = irq_to_desc(irq);
96 unsigned long flags; 92 unsigned long flags;
97 93
98 if (irq >= NR_IRQS) { 94 if (!desc) {
99 printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); 95 WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
100 WARN_ON(1);
101 return -EINVAL; 96 return -EINVAL;
102 } 97 }
103 98
104 if (!chip) 99 if (!chip)
105 chip = &no_irq_chip; 100 chip = &no_irq_chip;
106 101
107 desc = irq_desc + irq;
108 spin_lock_irqsave(&desc->lock, flags); 102 spin_lock_irqsave(&desc->lock, flags);
109 irq_chip_set_defaults(chip); 103 irq_chip_set_defaults(chip);
110 desc->chip = chip; 104 desc->chip = chip;
@@ -115,27 +109,27 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
115EXPORT_SYMBOL(set_irq_chip); 109EXPORT_SYMBOL(set_irq_chip);
116 110
117/** 111/**
118 * set_irq_type - set the irq type for an irq 112 * set_irq_type - set the irq trigger type for an irq
119 * @irq: irq number 113 * @irq: irq number
120 * @type: interrupt type - see include/linux/interrupt.h 114 * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
121 */ 115 */
122int set_irq_type(unsigned int irq, unsigned int type) 116int set_irq_type(unsigned int irq, unsigned int type)
123{ 117{
124 struct irq_desc *desc; 118 struct irq_desc *desc = irq_to_desc(irq);
125 unsigned long flags; 119 unsigned long flags;
126 int ret = -ENXIO; 120 int ret = -ENXIO;
127 121
128 if (irq >= NR_IRQS) { 122 if (!desc) {
129 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); 123 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
130 return -ENODEV; 124 return -ENODEV;
131 } 125 }
132 126
133 desc = irq_desc + irq; 127 if (type == IRQ_TYPE_NONE)
134 if (desc->chip->set_type) { 128 return 0;
135 spin_lock_irqsave(&desc->lock, flags); 129
136 ret = desc->chip->set_type(irq, type); 130 spin_lock_irqsave(&desc->lock, flags);
137 spin_unlock_irqrestore(&desc->lock, flags); 131 ret = __irq_set_trigger(desc, irq, type);
138 } 132 spin_unlock_irqrestore(&desc->lock, flags);
139 return ret; 133 return ret;
140} 134}
141EXPORT_SYMBOL(set_irq_type); 135EXPORT_SYMBOL(set_irq_type);
@@ -149,16 +143,15 @@ EXPORT_SYMBOL(set_irq_type);
149 */ 143 */
150int set_irq_data(unsigned int irq, void *data) 144int set_irq_data(unsigned int irq, void *data)
151{ 145{
152 struct irq_desc *desc; 146 struct irq_desc *desc = irq_to_desc(irq);
153 unsigned long flags; 147 unsigned long flags;
154 148
155 if (irq >= NR_IRQS) { 149 if (!desc) {
156 printk(KERN_ERR 150 printk(KERN_ERR
157 "Trying to install controller data for IRQ%d\n", irq); 151 "Trying to install controller data for IRQ%d\n", irq);
158 return -EINVAL; 152 return -EINVAL;
159 } 153 }
160 154
161 desc = irq_desc + irq;
162 spin_lock_irqsave(&desc->lock, flags); 155 spin_lock_irqsave(&desc->lock, flags);
163 desc->handler_data = data; 156 desc->handler_data = data;
164 spin_unlock_irqrestore(&desc->lock, flags); 157 spin_unlock_irqrestore(&desc->lock, flags);
@@ -175,15 +168,15 @@ EXPORT_SYMBOL(set_irq_data);
175 */ 168 */
176int set_irq_msi(unsigned int irq, struct msi_desc *entry) 169int set_irq_msi(unsigned int irq, struct msi_desc *entry)
177{ 170{
178 struct irq_desc *desc; 171 struct irq_desc *desc = irq_to_desc(irq);
179 unsigned long flags; 172 unsigned long flags;
180 173
181 if (irq >= NR_IRQS) { 174 if (!desc) {
182 printk(KERN_ERR 175 printk(KERN_ERR
183 "Trying to install msi data for IRQ%d\n", irq); 176 "Trying to install msi data for IRQ%d\n", irq);
184 return -EINVAL; 177 return -EINVAL;
185 } 178 }
186 desc = irq_desc + irq; 179
187 spin_lock_irqsave(&desc->lock, flags); 180 spin_lock_irqsave(&desc->lock, flags);
188 desc->msi_desc = entry; 181 desc->msi_desc = entry;
189 if (entry) 182 if (entry)
@@ -201,10 +194,16 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
201 */ 194 */
202int set_irq_chip_data(unsigned int irq, void *data) 195int set_irq_chip_data(unsigned int irq, void *data)
203{ 196{
204 struct irq_desc *desc = irq_desc + irq; 197 struct irq_desc *desc = irq_to_desc(irq);
205 unsigned long flags; 198 unsigned long flags;
206 199
207 if (irq >= NR_IRQS || !desc->chip) { 200 if (!desc) {
201 printk(KERN_ERR
202 "Trying to install chip data for IRQ%d\n", irq);
203 return -EINVAL;
204 }
205
206 if (!desc->chip) {
208 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); 207 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
209 return -EINVAL; 208 return -EINVAL;
210 } 209 }
@@ -222,7 +221,7 @@ EXPORT_SYMBOL(set_irq_chip_data);
222 */ 221 */
223static void default_enable(unsigned int irq) 222static void default_enable(unsigned int irq)
224{ 223{
225 struct irq_desc *desc = irq_desc + irq; 224 struct irq_desc *desc = irq_to_desc(irq);
226 225
227 desc->chip->unmask(irq); 226 desc->chip->unmask(irq);
228 desc->status &= ~IRQ_MASKED; 227 desc->status &= ~IRQ_MASKED;
@@ -240,8 +239,9 @@ static void default_disable(unsigned int irq)
240 */ 239 */
241static unsigned int default_startup(unsigned int irq) 240static unsigned int default_startup(unsigned int irq)
242{ 241{
243 irq_desc[irq].chip->enable(irq); 242 struct irq_desc *desc = irq_to_desc(irq);
244 243
244 desc->chip->enable(irq);
245 return 0; 245 return 0;
246} 246}
247 247
@@ -250,7 +250,7 @@ static unsigned int default_startup(unsigned int irq)
250 */ 250 */
251static void default_shutdown(unsigned int irq) 251static void default_shutdown(unsigned int irq)
252{ 252{
253 struct irq_desc *desc = irq_desc + irq; 253 struct irq_desc *desc = irq_to_desc(irq);
254 254
255 desc->chip->mask(irq); 255 desc->chip->mask(irq);
256 desc->status |= IRQ_MASKED; 256 desc->status |= IRQ_MASKED;
@@ -309,14 +309,13 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
309{ 309{
310 struct irqaction *action; 310 struct irqaction *action;
311 irqreturn_t action_ret; 311 irqreturn_t action_ret;
312 const unsigned int cpu = smp_processor_id();
313 312
314 spin_lock(&desc->lock); 313 spin_lock(&desc->lock);
315 314
316 if (unlikely(desc->status & IRQ_INPROGRESS)) 315 if (unlikely(desc->status & IRQ_INPROGRESS))
317 goto out_unlock; 316 goto out_unlock;
318 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 317 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
319 kstat_cpu(cpu).irqs[irq]++; 318 kstat_incr_irqs_this_cpu(irq, desc);
320 319
321 action = desc->action; 320 action = desc->action;
322 if (unlikely(!action || (desc->status & IRQ_DISABLED))) 321 if (unlikely(!action || (desc->status & IRQ_DISABLED)))
@@ -348,7 +347,6 @@ out_unlock:
348void 347void
349handle_level_irq(unsigned int irq, struct irq_desc *desc) 348handle_level_irq(unsigned int irq, struct irq_desc *desc)
350{ 349{
351 unsigned int cpu = smp_processor_id();
352 struct irqaction *action; 350 struct irqaction *action;
353 irqreturn_t action_ret; 351 irqreturn_t action_ret;
354 352
@@ -358,7 +356,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
358 if (unlikely(desc->status & IRQ_INPROGRESS)) 356 if (unlikely(desc->status & IRQ_INPROGRESS))
359 goto out_unlock; 357 goto out_unlock;
360 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 358 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
361 kstat_cpu(cpu).irqs[irq]++; 359 kstat_incr_irqs_this_cpu(irq, desc);
362 360
363 /* 361 /*
364 * If its disabled or no action available 362 * If its disabled or no action available
@@ -396,7 +394,6 @@ out_unlock:
396void 394void
397handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) 395handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
398{ 396{
399 unsigned int cpu = smp_processor_id();
400 struct irqaction *action; 397 struct irqaction *action;
401 irqreturn_t action_ret; 398 irqreturn_t action_ret;
402 399
@@ -406,7 +403,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
406 goto out; 403 goto out;
407 404
408 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 405 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
409 kstat_cpu(cpu).irqs[irq]++; 406 kstat_incr_irqs_this_cpu(irq, desc);
410 407
411 /* 408 /*
412 * If its disabled or no action available 409 * If its disabled or no action available
@@ -455,8 +452,6 @@ out:
455void 452void
456handle_edge_irq(unsigned int irq, struct irq_desc *desc) 453handle_edge_irq(unsigned int irq, struct irq_desc *desc)
457{ 454{
458 const unsigned int cpu = smp_processor_id();
459
460 spin_lock(&desc->lock); 455 spin_lock(&desc->lock);
461 456
462 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 457 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -472,8 +467,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
472 mask_ack_irq(desc, irq); 467 mask_ack_irq(desc, irq);
473 goto out_unlock; 468 goto out_unlock;
474 } 469 }
475 470 kstat_incr_irqs_this_cpu(irq, desc);
476 kstat_cpu(cpu).irqs[irq]++;
477 471
478 /* Start handling the irq */ 472 /* Start handling the irq */
479 desc->chip->ack(irq); 473 desc->chip->ack(irq);
@@ -528,7 +522,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
528{ 522{
529 irqreturn_t action_ret; 523 irqreturn_t action_ret;
530 524
531 kstat_this_cpu.irqs[irq]++; 525 kstat_incr_irqs_this_cpu(irq, desc);
532 526
533 if (desc->chip->ack) 527 if (desc->chip->ack)
534 desc->chip->ack(irq); 528 desc->chip->ack(irq);
@@ -545,17 +539,15 @@ void
545__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 539__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
546 const char *name) 540 const char *name)
547{ 541{
548 struct irq_desc *desc; 542 struct irq_desc *desc = irq_to_desc(irq);
549 unsigned long flags; 543 unsigned long flags;
550 544
551 if (irq >= NR_IRQS) { 545 if (!desc) {
552 printk(KERN_ERR 546 printk(KERN_ERR
553 "Trying to install type control for IRQ%d\n", irq); 547 "Trying to install type control for IRQ%d\n", irq);
554 return; 548 return;
555 } 549 }
556 550
557 desc = irq_desc + irq;
558
559 if (!handle) 551 if (!handle)
560 handle = handle_bad_irq; 552 handle = handle_bad_irq;
561 else if (desc->chip == &no_irq_chip) { 553 else if (desc->chip == &no_irq_chip) {
@@ -587,7 +579,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
587 desc->status &= ~IRQ_DISABLED; 579 desc->status &= ~IRQ_DISABLED;
588 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; 580 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
589 desc->depth = 0; 581 desc->depth = 0;
590 desc->chip->unmask(irq); 582 desc->chip->startup(irq);
591 } 583 }
592 spin_unlock_irqrestore(&desc->lock, flags); 584 spin_unlock_irqrestore(&desc->lock, flags);
593} 585}
@@ -610,17 +602,14 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
610 602
611void __init set_irq_noprobe(unsigned int irq) 603void __init set_irq_noprobe(unsigned int irq)
612{ 604{
613 struct irq_desc *desc; 605 struct irq_desc *desc = irq_to_desc(irq);
614 unsigned long flags; 606 unsigned long flags;
615 607
616 if (irq >= NR_IRQS) { 608 if (!desc) {
617 printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); 609 printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
618
619 return; 610 return;
620 } 611 }
621 612
622 desc = irq_desc + irq;
623
624 spin_lock_irqsave(&desc->lock, flags); 613 spin_lock_irqsave(&desc->lock, flags);
625 desc->status |= IRQ_NOPROBE; 614 desc->status |= IRQ_NOPROBE;
626 spin_unlock_irqrestore(&desc->lock, flags); 615 spin_unlock_irqrestore(&desc->lock, flags);
@@ -628,17 +617,14 @@ void __init set_irq_noprobe(unsigned int irq)
628 617
629void __init set_irq_probe(unsigned int irq) 618void __init set_irq_probe(unsigned int irq)
630{ 619{
631 struct irq_desc *desc; 620 struct irq_desc *desc = irq_to_desc(irq);
632 unsigned long flags; 621 unsigned long flags;
633 622
634 if (irq >= NR_IRQS) { 623 if (!desc) {
635 printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); 624 printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
636
637 return; 625 return;
638 } 626 }
639 627
640 desc = irq_desc + irq;
641
642 spin_lock_irqsave(&desc->lock, flags); 628 spin_lock_irqsave(&desc->lock, flags);
643 desc->status &= ~IRQ_NOPROBE; 629 desc->status &= ~IRQ_NOPROBE;
644 spin_unlock_irqrestore(&desc->lock, flags); 630 spin_unlock_irqrestore(&desc->lock, flags);