diff options
author | Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> | 2007-07-17 08:22:48 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-07-17 12:57:42 -0400 |
commit | cd378f18cf73d92bf0b6e1e6b5759b5dd729a9f2 (patch) | |
tree | 6960768a1ddecb74e6a5fa1dfc978e5df8635eb2 /arch/ia64/kernel/irq_ia64.c | |
parent | 4994be1b3fe9120c88022ff5c0c33f6312b17adb (diff) |
[IA64] Support irq migration across domain
Add support for IRQ migration across vector domain.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/irq_ia64.c')
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index a3667631ed80..22806b94025a 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -172,15 +172,13 @@ int bind_irq_vector(int irq, int vector, cpumask_t domain) | |||
172 | return ret; | 172 | return ret; |
173 | } | 173 | } |
174 | 174 | ||
175 | static void clear_irq_vector(int irq) | 175 | static void __clear_irq_vector(int irq) |
176 | { | 176 | { |
177 | unsigned long flags; | ||
178 | int vector, cpu, pos; | 177 | int vector, cpu, pos; |
179 | cpumask_t mask; | 178 | cpumask_t mask; |
180 | cpumask_t domain; | 179 | cpumask_t domain; |
181 | struct irq_cfg *cfg = &irq_cfg[irq]; | 180 | struct irq_cfg *cfg = &irq_cfg[irq]; |
182 | 181 | ||
183 | spin_lock_irqsave(&vector_lock, flags); | ||
184 | BUG_ON((unsigned)irq >= NR_IRQS); | 182 | BUG_ON((unsigned)irq >= NR_IRQS); |
185 | BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED); | 183 | BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED); |
186 | vector = cfg->vector; | 184 | vector = cfg->vector; |
@@ -193,6 +191,14 @@ static void clear_irq_vector(int irq) | |||
193 | irq_status[irq] = IRQ_UNUSED; | 191 | irq_status[irq] = IRQ_UNUSED; |
194 | pos = vector - IA64_FIRST_DEVICE_VECTOR; | 192 | pos = vector - IA64_FIRST_DEVICE_VECTOR; |
195 | cpus_andnot(vector_table[pos], vector_table[pos], domain); | 193 | cpus_andnot(vector_table[pos], vector_table[pos], domain); |
194 | } | ||
195 | |||
196 | static void clear_irq_vector(int irq) | ||
197 | { | ||
198 | unsigned long flags; | ||
199 | |||
200 | spin_lock_irqsave(&vector_lock, flags); | ||
201 | __clear_irq_vector(irq); | ||
196 | spin_unlock_irqrestore(&vector_lock, flags); | 202 | spin_unlock_irqrestore(&vector_lock, flags); |
197 | } | 203 | } |
198 | 204 | ||
@@ -275,6 +281,36 @@ void destroy_and_reserve_irq(unsigned int irq) | |||
275 | reserve_irq(irq); | 281 | reserve_irq(irq); |
276 | } | 282 | } |
277 | 283 | ||
284 | static int __reassign_irq_vector(int irq, int cpu) | ||
285 | { | ||
286 | struct irq_cfg *cfg = &irq_cfg[irq]; | ||
287 | int vector; | ||
288 | cpumask_t domain; | ||
289 | |||
290 | if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu)) | ||
291 | return -EINVAL; | ||
292 | if (cpu_isset(cpu, cfg->domain)) | ||
293 | return 0; | ||
294 | domain = vector_allocation_domain(cpu); | ||
295 | vector = find_unassigned_vector(domain); | ||
296 | if (vector < 0) | ||
297 | return -ENOSPC; | ||
298 | __clear_irq_vector(irq); | ||
299 | BUG_ON(__bind_irq_vector(irq, vector, domain)); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | int reassign_irq_vector(int irq, int cpu) | ||
304 | { | ||
305 | unsigned long flags; | ||
306 | int ret; | ||
307 | |||
308 | spin_lock_irqsave(&vector_lock, flags); | ||
309 | ret = __reassign_irq_vector(irq, cpu); | ||
310 | spin_unlock_irqrestore(&vector_lock, flags); | ||
311 | return ret; | ||
312 | } | ||
313 | |||
278 | /* | 314 | /* |
279 | * Dynamic irq allocate and deallocation for MSI | 315 | * Dynamic irq allocate and deallocation for MSI |
280 | */ | 316 | */ |