aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-02-12 04:37:36 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-19 06:58:23 -0500
commit02725e7471b8dd58fa96f6604bdb5dde45405a2e (patch)
tree7c5243d0a2e33f2165d1531febbe9752fad389c7 /kernel/irq
parentd5eb4ad2dfb2dfae43fd51bc8630b4fc3ef00e92 (diff)
genirq: Use irq_get/put functions
Convert the management functions to use the common irq_get/put function. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/chip.c93
-rw-r--r--kernel/irq/manage.c81
2 files changed, 57 insertions, 117 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c19c0b562c80..3ea6aecd99c0 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -25,22 +25,18 @@
25 */ 25 */
26int irq_set_chip(unsigned int irq, struct irq_chip *chip) 26int irq_set_chip(unsigned int irq, struct irq_chip *chip)
27{ 27{
28 struct irq_desc *desc = irq_to_desc(irq);
29 unsigned long flags; 28 unsigned long flags;
29 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
30 30
31 if (!desc) { 31 if (!desc)
32 WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
33 return -EINVAL; 32 return -EINVAL;
34 }
35 33
36 if (!chip) 34 if (!chip)
37 chip = &no_irq_chip; 35 chip = &no_irq_chip;
38 36
39 raw_spin_lock_irqsave(&desc->lock, flags);
40 irq_chip_set_defaults(chip); 37 irq_chip_set_defaults(chip);
41 desc->irq_data.chip = chip; 38 desc->irq_data.chip = chip;
42 raw_spin_unlock_irqrestore(&desc->lock, flags); 39 irq_put_desc_unlock(desc, flags);
43
44 return 0; 40 return 0;
45} 41}
46EXPORT_SYMBOL(irq_set_chip); 42EXPORT_SYMBOL(irq_set_chip);
@@ -52,24 +48,17 @@ EXPORT_SYMBOL(irq_set_chip);
52 */ 48 */
53int irq_set_irq_type(unsigned int irq, unsigned int type) 49int irq_set_irq_type(unsigned int irq, unsigned int type)
54{ 50{
55 struct irq_desc *desc = irq_to_desc(irq);
56 unsigned long flags; 51 unsigned long flags;
57 int ret = -ENXIO; 52 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
53 int ret = 0;
58 54
59 if (!desc) { 55 if (!desc)
60 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); 56 return -EINVAL;
61 return -ENODEV;
62 }
63 57
64 type &= IRQ_TYPE_SENSE_MASK; 58 type &= IRQ_TYPE_SENSE_MASK;
65 if (type == IRQ_TYPE_NONE) 59 if (type != IRQ_TYPE_NONE)
66 return 0; 60 ret = __irq_set_trigger(desc, irq, type);
67 61 irq_put_desc_busunlock(desc, flags);
68 chip_bus_lock(desc);
69 raw_spin_lock_irqsave(&desc->lock, flags);
70 ret = __irq_set_trigger(desc, irq, type);
71 raw_spin_unlock_irqrestore(&desc->lock, flags);
72 chip_bus_sync_unlock(desc);
73 return ret; 62 return ret;
74} 63}
75EXPORT_SYMBOL(irq_set_irq_type); 64EXPORT_SYMBOL(irq_set_irq_type);
@@ -83,18 +72,13 @@ EXPORT_SYMBOL(irq_set_irq_type);
83 */ 72 */
84int irq_set_handler_data(unsigned int irq, void *data) 73int irq_set_handler_data(unsigned int irq, void *data)
85{ 74{
86 struct irq_desc *desc = irq_to_desc(irq);
87 unsigned long flags; 75 unsigned long flags;
76 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
88 77
89 if (!desc) { 78 if (!desc)
90 printk(KERN_ERR
91 "Trying to install controller data for IRQ%d\n", irq);
92 return -EINVAL; 79 return -EINVAL;
93 }
94
95 raw_spin_lock_irqsave(&desc->lock, flags);
96 desc->irq_data.handler_data = data; 80 desc->irq_data.handler_data = data;
97 raw_spin_unlock_irqrestore(&desc->lock, flags); 81 irq_put_desc_unlock(desc, flags);
98 return 0; 82 return 0;
99} 83}
100EXPORT_SYMBOL(irq_set_handler_data); 84EXPORT_SYMBOL(irq_set_handler_data);
@@ -108,20 +92,15 @@ EXPORT_SYMBOL(irq_set_handler_data);
108 */ 92 */
109int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) 93int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
110{ 94{
111 struct irq_desc *desc = irq_to_desc(irq);
112 unsigned long flags; 95 unsigned long flags;
96 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
113 97
114 if (!desc) { 98 if (!desc)
115 printk(KERN_ERR
116 "Trying to install msi data for IRQ%d\n", irq);
117 return -EINVAL; 99 return -EINVAL;
118 }
119
120 raw_spin_lock_irqsave(&desc->lock, flags);
121 desc->irq_data.msi_desc = entry; 100 desc->irq_data.msi_desc = entry;
122 if (entry) 101 if (entry)
123 entry->irq = irq; 102 entry->irq = irq;
124 raw_spin_unlock_irqrestore(&desc->lock, flags); 103 irq_put_desc_unlock(desc, flags);
125 return 0; 104 return 0;
126} 105}
127 106
@@ -134,24 +113,13 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
134 */ 113 */
135int irq_set_chip_data(unsigned int irq, void *data) 114int irq_set_chip_data(unsigned int irq, void *data)
136{ 115{
137 struct irq_desc *desc = irq_to_desc(irq);
138 unsigned long flags; 116 unsigned long flags;
117 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
139 118
140 if (!desc) { 119 if (!desc)
141 printk(KERN_ERR
142 "Trying to install chip data for IRQ%d\n", irq);
143 return -EINVAL;
144 }
145
146 if (!desc->irq_data.chip) {
147 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
148 return -EINVAL; 120 return -EINVAL;
149 }
150
151 raw_spin_lock_irqsave(&desc->lock, flags);
152 desc->irq_data.chip_data = data; 121 desc->irq_data.chip_data = data;
153 raw_spin_unlock_irqrestore(&desc->lock, flags); 122 irq_put_desc_unlock(desc, flags);
154
155 return 0; 123 return 0;
156} 124}
157EXPORT_SYMBOL(irq_set_chip_data); 125EXPORT_SYMBOL(irq_set_chip_data);
@@ -635,25 +603,19 @@ void
635__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, 603__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
636 const char *name) 604 const char *name)
637{ 605{
638 struct irq_desc *desc = irq_to_desc(irq);
639 unsigned long flags; 606 unsigned long flags;
607 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
640 608
641 if (!desc) { 609 if (!desc)
642 printk(KERN_ERR
643 "Trying to install type control for IRQ%d\n", irq);
644 return; 610 return;
645 }
646 611
647 if (!handle) { 612 if (!handle) {
648 handle = handle_bad_irq; 613 handle = handle_bad_irq;
649 } else { 614 } else {
650 if (WARN_ON(desc->irq_data.chip == &no_irq_chip)) 615 if (WARN_ON(desc->irq_data.chip == &no_irq_chip))
651 return; 616 goto out;
652 } 617 }
653 618
654 chip_bus_lock(desc);
655 raw_spin_lock_irqsave(&desc->lock, flags);
656
657 /* Uninstall? */ 619 /* Uninstall? */
658 if (handle == handle_bad_irq) { 620 if (handle == handle_bad_irq) {
659 if (desc->irq_data.chip != &no_irq_chip) 621 if (desc->irq_data.chip != &no_irq_chip)
@@ -670,8 +632,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
670 irq_settings_set_norequest(desc); 632 irq_settings_set_norequest(desc);
671 irq_startup(desc); 633 irq_startup(desc);
672 } 634 }
673 raw_spin_unlock_irqrestore(&desc->lock, flags); 635out:
674 chip_bus_sync_unlock(desc); 636 irq_put_desc_busunlock(desc, flags);
675} 637}
676EXPORT_SYMBOL_GPL(__set_irq_handler); 638EXPORT_SYMBOL_GPL(__set_irq_handler);
677 639
@@ -693,14 +655,11 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
693 655
694void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) 656void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
695{ 657{
696 struct irq_desc *desc = irq_to_desc(irq);
697 unsigned long flags; 658 unsigned long flags;
659 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
698 660
699 if (!desc) 661 if (!desc)
700 return; 662 return;
701
702 raw_spin_lock_irqsave(&desc->lock, flags);
703
704 irq_settings_clr_and_set(desc, clr, set); 663 irq_settings_clr_and_set(desc, clr, set);
705 664
706 irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU | 665 irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
@@ -714,5 +673,5 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
714 673
715 irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc)); 674 irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc));
716 675
717 raw_spin_unlock_irqrestore(&desc->lock, flags); 676 irq_put_desc_unlock(desc, flags);
718} 677}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 99395a24f432..6cca1956c503 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -172,16 +172,13 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
172 172
173int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) 173int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
174{ 174{
175 struct irq_desc *desc = irq_to_desc(irq);
176 unsigned long flags; 175 unsigned long flags;
176 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
177 177
178 if (!desc) 178 if (!desc)
179 return -EINVAL; 179 return -EINVAL;
180
181 raw_spin_lock_irqsave(&desc->lock, flags);
182 desc->affinity_hint = m; 180 desc->affinity_hint = m;
183 raw_spin_unlock_irqrestore(&desc->lock, flags); 181 irq_put_desc_unlock(desc, flags);
184
185 return 0; 182 return 0;
186} 183}
187EXPORT_SYMBOL_GPL(irq_set_affinity_hint); 184EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
@@ -336,6 +333,18 @@ void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
336 irq_disable(desc); 333 irq_disable(desc);
337} 334}
338 335
336static int __disable_irq_nosync(unsigned int irq)
337{
338 unsigned long flags;
339 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
340
341 if (!desc)
342 return -EINVAL;
343 __disable_irq(desc, irq, false);
344 irq_put_desc_busunlock(desc, flags);
345 return 0;
346}
347
339/** 348/**
340 * disable_irq_nosync - disable an irq without waiting 349 * disable_irq_nosync - disable an irq without waiting
341 * @irq: Interrupt to disable 350 * @irq: Interrupt to disable
@@ -349,17 +358,7 @@ void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
349 */ 358 */
350void disable_irq_nosync(unsigned int irq) 359void disable_irq_nosync(unsigned int irq)
351{ 360{
352 struct irq_desc *desc = irq_to_desc(irq); 361 __disable_irq_nosync(irq);
353 unsigned long flags;
354
355 if (!desc)
356 return;
357
358 chip_bus_lock(desc);
359 raw_spin_lock_irqsave(&desc->lock, flags);
360 __disable_irq(desc, irq, false);
361 raw_spin_unlock_irqrestore(&desc->lock, flags);
362 chip_bus_sync_unlock(desc);
363} 362}
364EXPORT_SYMBOL(disable_irq_nosync); 363EXPORT_SYMBOL(disable_irq_nosync);
365 364
@@ -377,13 +376,7 @@ EXPORT_SYMBOL(disable_irq_nosync);
377 */ 376 */
378void disable_irq(unsigned int irq) 377void disable_irq(unsigned int irq)
379{ 378{
380 struct irq_desc *desc = irq_to_desc(irq); 379 if (!__disable_irq_nosync(irq))
381
382 if (!desc)
383 return;
384
385 disable_irq_nosync(irq);
386 if (desc->action)
387 synchronize_irq(irq); 380 synchronize_irq(irq);
388} 381}
389EXPORT_SYMBOL(disable_irq); 382EXPORT_SYMBOL(disable_irq);
@@ -434,21 +427,18 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
434 */ 427 */
435void enable_irq(unsigned int irq) 428void enable_irq(unsigned int irq)
436{ 429{
437 struct irq_desc *desc = irq_to_desc(irq);
438 unsigned long flags; 430 unsigned long flags;
431 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
439 432
440 if (!desc) 433 if (!desc)
441 return; 434 return;
442
443 if (WARN(!desc->irq_data.chip, 435 if (WARN(!desc->irq_data.chip,
444 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) 436 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
445 return; 437 goto out;
446 438
447 chip_bus_lock(desc);
448 raw_spin_lock_irqsave(&desc->lock, flags);
449 __enable_irq(desc, irq, false); 439 __enable_irq(desc, irq, false);
450 raw_spin_unlock_irqrestore(&desc->lock, flags); 440out:
451 chip_bus_sync_unlock(desc); 441 irq_put_desc_busunlock(desc, flags);
452} 442}
453EXPORT_SYMBOL(enable_irq); 443EXPORT_SYMBOL(enable_irq);
454 444
@@ -477,15 +467,13 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
477 */ 467 */
478int irq_set_irq_wake(unsigned int irq, unsigned int on) 468int irq_set_irq_wake(unsigned int irq, unsigned int on)
479{ 469{
480 struct irq_desc *desc = irq_to_desc(irq);
481 unsigned long flags; 470 unsigned long flags;
471 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
482 int ret = 0; 472 int ret = 0;
483 473
484 /* wakeup-capable irqs can be shared between drivers that 474 /* wakeup-capable irqs can be shared between drivers that
485 * don't need to have the same sleep mode behaviors. 475 * don't need to have the same sleep mode behaviors.
486 */ 476 */
487 chip_bus_lock(desc);
488 raw_spin_lock_irqsave(&desc->lock, flags);
489 if (on) { 477 if (on) {
490 if (desc->wake_depth++ == 0) { 478 if (desc->wake_depth++ == 0) {
491 ret = set_irq_wake_real(irq, on); 479 ret = set_irq_wake_real(irq, on);
@@ -505,9 +493,7 @@ int irq_set_irq_wake(unsigned int irq, unsigned int on)
505 irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE); 493 irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
506 } 494 }
507 } 495 }
508 496 irq_put_desc_busunlock(desc, flags);
509 raw_spin_unlock_irqrestore(&desc->lock, flags);
510 chip_bus_sync_unlock(desc);
511 return ret; 497 return ret;
512} 498}
513EXPORT_SYMBOL(irq_set_irq_wake); 499EXPORT_SYMBOL(irq_set_irq_wake);
@@ -519,25 +505,20 @@ EXPORT_SYMBOL(irq_set_irq_wake);
519 */ 505 */
520int can_request_irq(unsigned int irq, unsigned long irqflags) 506int can_request_irq(unsigned int irq, unsigned long irqflags)
521{ 507{
522 struct irq_desc *desc = irq_to_desc(irq);
523 struct irqaction *action;
524 unsigned long flags; 508 unsigned long flags;
509 struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
510 int canrequest = 0;
525 511
526 if (!desc) 512 if (!desc)
527 return 0; 513 return 0;
528 514
529 if (!irq_settings_can_request(desc)) 515 if (irq_settings_can_request(desc)) {
530 return 0; 516 if (desc->action)
531 517 if (irqflags & desc->action->flags & IRQF_SHARED)
532 raw_spin_lock_irqsave(&desc->lock, flags); 518 canrequest =1;
533 action = desc->action; 519 }
534 if (action) 520 irq_put_desc_unlock(desc, flags);
535 if (irqflags & action->flags & IRQF_SHARED) 521 return canrequest;
536 action = NULL;
537
538 raw_spin_unlock_irqrestore(&desc->lock, flags);
539
540 return !action;
541} 522}
542 523
543int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, 524int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,