aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-10-26 03:05:08 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-10-26 03:05:08 -0400
commit38ab13441c36c0c470b7e4e3b30ec2fb6beba253 (patch)
tree12d4ef364ec103b85fe0089ca09b7386fad8bfa8 /drivers
parent57b813303ab40557aada8f8886400f3a9de3c0f8 (diff)
sh: Switch dynamic IRQ creation to generic irq allocator.
Now that the genirq code provides an IRQ bitmap of its own and the necessary API to manipulate it, there's no need to keep our own version around anymore. In the process we kill off some unused IRQ reservation code, with future users now having to tie in to the genirq API as normal. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/sh/intc/core.c2
-rw-r--r--drivers/sh/intc/dynamic.c82
2 files changed, 9 insertions, 75 deletions
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 8f3c27e9f9e2..0801089828e7 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -78,7 +78,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
78 * Register the IRQ position with the global IRQ map, then insert 78 * Register the IRQ position with the global IRQ map, then insert
79 * it in to the radix tree. 79 * it in to the radix tree.
80 */ 80 */
81 reserve_irq_vector(irq); 81 irq_reserve_irqs(irq, 1);
82 82
83 raw_spin_lock_irqsave(&intc_big_lock, flags); 83 raw_spin_lock_irqsave(&intc_big_lock, flags);
84 radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); 84 radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq));
diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c
index e994c7ed916e..4187cce20ffd 100644
--- a/drivers/sh/intc/dynamic.c
+++ b/drivers/sh/intc/dynamic.c
@@ -17,7 +17,7 @@
17#include "internals.h" /* only for activate_irq() damage.. */ 17#include "internals.h" /* only for activate_irq() damage.. */
18 18
19/* 19/*
20 * The intc_irq_map provides a global map of bound IRQ vectors for a 20 * The IRQ bitmap provides a global map of bound IRQ vectors for a
21 * given platform. Allocation of IRQs are either static through the CPU 21 * given platform. Allocation of IRQs are either static through the CPU
22 * vector map, or dynamic in the case of board mux vectors or MSI. 22 * vector map, or dynamic in the case of board mux vectors or MSI.
23 * 23 *
@@ -27,104 +27,38 @@
27 * when dynamically creating IRQs, as well as tying in to otherwise 27 * when dynamically creating IRQs, as well as tying in to otherwise
28 * unused irq_desc positions in the sparse array. 28 * unused irq_desc positions in the sparse array.
29 */ 29 */
30static DECLARE_BITMAP(intc_irq_map, NR_IRQS);
31static DEFINE_RAW_SPINLOCK(vector_lock);
32 30
33/* 31/*
34 * Dynamic IRQ allocation and deallocation 32 * Dynamic IRQ allocation and deallocation
35 */ 33 */
36unsigned int create_irq_nr(unsigned int irq_want, int node) 34unsigned int create_irq_nr(unsigned int irq_want, int node)
37{ 35{
38 unsigned int irq = 0, new; 36 int irq = irq_alloc_desc_at(irq_want, node);
39 unsigned long flags; 37 if (irq < 0)
40
41 raw_spin_lock_irqsave(&vector_lock, flags);
42
43 /*
44 * First try the wanted IRQ
45 */
46 if (test_and_set_bit(irq_want, intc_irq_map) == 0) {
47 new = irq_want;
48 } else {
49 /* .. then fall back to scanning. */
50 new = find_first_zero_bit(intc_irq_map, nr_irqs);
51 if (unlikely(new == nr_irqs))
52 goto out_unlock;
53
54 __set_bit(new, intc_irq_map);
55 }
56
57 raw_spin_unlock_irqrestore(&vector_lock, flags);
58
59 irq = irq_alloc_desc_at(new, node);
60 if (unlikely(irq != new)) {
61 pr_err("can't get irq_desc for %d\n", new);
62 return 0; 38 return 0;
63 }
64 39
65 activate_irq(irq); 40 activate_irq(irq);
66 return 0; 41 return irq;
67
68out_unlock:
69 raw_spin_unlock_irqrestore(&vector_lock, flags);
70 return 0;
71} 42}
72 43
73int create_irq(void) 44int create_irq(void)
74{ 45{
75 int nid = cpu_to_node(smp_processor_id()); 46 int irq = irq_alloc_desc(numa_node_id());
76 int irq; 47 if (irq >= 0)
77 48 activate_irq(irq);
78 irq = create_irq_nr(NR_IRQS_LEGACY, nid);
79 if (irq == 0)
80 irq = -1;
81 49
82 return irq; 50 return irq;
83} 51}
84 52
85void destroy_irq(unsigned int irq) 53void destroy_irq(unsigned int irq)
86{ 54{
87 unsigned long flags;
88
89 irq_free_desc(irq); 55 irq_free_desc(irq);
90
91 raw_spin_lock_irqsave(&vector_lock, flags);
92 __clear_bit(irq, intc_irq_map);
93 raw_spin_unlock_irqrestore(&vector_lock, flags);
94}
95
96int reserve_irq_vector(unsigned int irq)
97{
98 unsigned long flags;
99 int ret = 0;
100
101 raw_spin_lock_irqsave(&vector_lock, flags);
102 if (test_and_set_bit(irq, intc_irq_map))
103 ret = -EBUSY;
104 raw_spin_unlock_irqrestore(&vector_lock, flags);
105
106 return ret;
107} 56}
108 57
109void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) 58void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs)
110{ 59{
111 unsigned long flags;
112 int i; 60 int i;
113 61
114 raw_spin_lock_irqsave(&vector_lock, flags);
115 for (i = 0; i < nr_vecs; i++) 62 for (i = 0; i < nr_vecs; i++)
116 __set_bit(evt2irq(vectors[i].vect), intc_irq_map); 63 irq_reserve_irqs(evt2irq(vectors[i].vect), 1);
117 raw_spin_unlock_irqrestore(&vector_lock, flags);
118}
119
120void reserve_irq_legacy(void)
121{
122 unsigned long flags;
123 int i, j;
124
125 raw_spin_lock_irqsave(&vector_lock, flags);
126 j = find_first_bit(intc_irq_map, nr_irqs);
127 for (i = 0; i < j; i++)
128 __set_bit(i, intc_irq_map);
129 raw_spin_unlock_irqrestore(&vector_lock, flags);
130} 64}