aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/irq_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
-rw-r--r--arch/sparc/kernel/irq_64.c41
1 files changed, 13 insertions, 28 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 5deabe921a47..bd075054942b 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -45,6 +45,7 @@
45#include <asm/cacheflush.h> 45#include <asm/cacheflush.h>
46 46
47#include "entry.h" 47#include "entry.h"
48#include "cpumap.h"
48 49
49#define NUM_IVECS (IMAP_INR + 1) 50#define NUM_IVECS (IMAP_INR + 1)
50 51
@@ -256,35 +257,13 @@ static int irq_choose_cpu(unsigned int virt_irq)
256 int cpuid; 257 int cpuid;
257 258
258 cpumask_copy(&mask, irq_desc[virt_irq].affinity); 259 cpumask_copy(&mask, irq_desc[virt_irq].affinity);
259 if (cpus_equal(mask, CPU_MASK_ALL)) { 260 if (cpus_equal(mask, cpu_online_map)) {
260 static int irq_rover; 261 cpuid = map_to_cpu(virt_irq);
261 static DEFINE_SPINLOCK(irq_rover_lock);
262 unsigned long flags;
263
264 /* Round-robin distribution... */
265 do_round_robin:
266 spin_lock_irqsave(&irq_rover_lock, flags);
267
268 while (!cpu_online(irq_rover)) {
269 if (++irq_rover >= nr_cpu_ids)
270 irq_rover = 0;
271 }
272 cpuid = irq_rover;
273 do {
274 if (++irq_rover >= nr_cpu_ids)
275 irq_rover = 0;
276 } while (!cpu_online(irq_rover));
277
278 spin_unlock_irqrestore(&irq_rover_lock, flags);
279 } else { 262 } else {
280 cpumask_t tmp; 263 cpumask_t tmp;
281 264
282 cpus_and(tmp, cpu_online_map, mask); 265 cpus_and(tmp, cpu_online_map, mask);
283 266 cpuid = cpus_empty(tmp) ? map_to_cpu(virt_irq) : first_cpu(tmp);
284 if (cpus_empty(tmp))
285 goto do_round_robin;
286
287 cpuid = first_cpu(tmp);
288 } 267 }
289 268
290 return cpuid; 269 return cpuid;
@@ -318,10 +297,12 @@ static void sun4u_irq_enable(unsigned int virt_irq)
318 } 297 }
319} 298}
320 299
321static void sun4u_set_affinity(unsigned int virt_irq, 300static int sun4u_set_affinity(unsigned int virt_irq,
322 const struct cpumask *mask) 301 const struct cpumask *mask)
323{ 302{
324 sun4u_irq_enable(virt_irq); 303 sun4u_irq_enable(virt_irq);
304
305 return 0;
325} 306}
326 307
327/* Don't do anything. The desc->status check for IRQ_DISABLED in 308/* Don't do anything. The desc->status check for IRQ_DISABLED in
@@ -377,7 +358,7 @@ static void sun4v_irq_enable(unsigned int virt_irq)
377 ino, err); 358 ino, err);
378} 359}
379 360
380static void sun4v_set_affinity(unsigned int virt_irq, 361static int sun4v_set_affinity(unsigned int virt_irq,
381 const struct cpumask *mask) 362 const struct cpumask *mask)
382{ 363{
383 unsigned int ino = virt_irq_table[virt_irq].dev_ino; 364 unsigned int ino = virt_irq_table[virt_irq].dev_ino;
@@ -388,6 +369,8 @@ static void sun4v_set_affinity(unsigned int virt_irq,
388 if (err != HV_EOK) 369 if (err != HV_EOK)
389 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " 370 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
390 "err(%d)\n", ino, cpuid, err); 371 "err(%d)\n", ino, cpuid, err);
372
373 return 0;
391} 374}
392 375
393static void sun4v_irq_disable(unsigned int virt_irq) 376static void sun4v_irq_disable(unsigned int virt_irq)
@@ -445,7 +428,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
445 dev_handle, dev_ino, err); 428 dev_handle, dev_ino, err);
446} 429}
447 430
448static void sun4v_virt_set_affinity(unsigned int virt_irq, 431static int sun4v_virt_set_affinity(unsigned int virt_irq,
449 const struct cpumask *mask) 432 const struct cpumask *mask)
450{ 433{
451 unsigned long cpuid, dev_handle, dev_ino; 434 unsigned long cpuid, dev_handle, dev_ino;
@@ -461,6 +444,8 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq,
461 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " 444 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
462 "err(%d)\n", 445 "err(%d)\n",
463 dev_handle, dev_ino, cpuid, err); 446 dev_handle, dev_ino, cpuid, err);
447
448 return 0;
464} 449}
465 450
466static void sun4v_virq_disable(unsigned int virt_irq) 451static void sun4v_virq_disable(unsigned int virt_irq)