aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sh')
-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}