diff options
Diffstat (limited to 'drivers/sh')
-rw-r--r-- | drivers/sh/intc/core.c | 2 | ||||
-rw-r--r-- | drivers/sh/intc/dynamic.c | 82 |
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 | */ |
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 | } |