diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-10-26 03:05:08 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-10-26 03:05:08 -0400 |
commit | 38ab13441c36c0c470b7e4e3b30ec2fb6beba253 (patch) | |
tree | 12d4ef364ec103b85fe0089ca09b7386fad8bfa8 /drivers/sh/intc/dynamic.c | |
parent | 57b813303ab40557aada8f8886400f3a9de3c0f8 (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/sh/intc/dynamic.c')
-rw-r--r-- | drivers/sh/intc/dynamic.c | 82 |
1 files changed, 8 insertions, 74 deletions
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 | */ |
30 | static DECLARE_BITMAP(intc_irq_map, NR_IRQS); | ||
31 | static DEFINE_RAW_SPINLOCK(vector_lock); | ||
32 | 30 | ||
33 | /* | 31 | /* |
34 | * Dynamic IRQ allocation and deallocation | 32 | * Dynamic IRQ allocation and deallocation |
35 | */ | 33 | */ |
36 | unsigned int create_irq_nr(unsigned int irq_want, int node) | 34 | unsigned 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 | |||
68 | out_unlock: | ||
69 | raw_spin_unlock_irqrestore(&vector_lock, flags); | ||
70 | return 0; | ||
71 | } | 42 | } |
72 | 43 | ||
73 | int create_irq(void) | 44 | int 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 | ||
85 | void destroy_irq(unsigned int irq) | 53 | void 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 | |||
96 | int 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 | ||
109 | void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) | 58 | void 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 | |||
120 | void 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 | } |