aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-20 22:30:49 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-20 22:30:49 -0500
commit1091ce6215a1cab60c3a4601a569cb727ca8637a (patch)
tree45038c0ee7cc4f83d268098ce8c91bfa97e63c07 /arch/sparc/kernel
parente5981fd6d77c63c003cac44ab52da72994e7ead3 (diff)
sparc64: Fix IRQ ->set_affinity() methods.
As noted by Benjamin Herrenschmidt, the generic IRQ layer only sets irq_desc[irq].affinity after ->set_affinity() succeeds. So we have to use the passed in cpumask. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r--arch/sparc/kernel/irq_64.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 8d6882bb480a..f2179cce1e4d 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -250,12 +250,12 @@ struct irq_handler_data {
250}; 250};
251 251
252#ifdef CONFIG_SMP 252#ifdef CONFIG_SMP
253static int irq_choose_cpu(unsigned int virt_irq) 253static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
254{ 254{
255 cpumask_t mask; 255 cpumask_t mask;
256 int cpuid; 256 int cpuid;
257 257
258 cpumask_copy(&mask, irq_desc[virt_irq].affinity); 258 cpumask_copy(&mask, affinity);
259 if (cpus_equal(mask, cpu_online_map)) { 259 if (cpus_equal(mask, cpu_online_map)) {
260 cpuid = map_to_cpu(virt_irq); 260 cpuid = map_to_cpu(virt_irq);
261 } else { 261 } else {
@@ -268,7 +268,7 @@ static int irq_choose_cpu(unsigned int virt_irq)
268 return cpuid; 268 return cpuid;
269} 269}
270#else 270#else
271static int irq_choose_cpu(unsigned int virt_irq) 271static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
272{ 272{
273 return real_hard_smp_processor_id(); 273 return real_hard_smp_processor_id();
274} 274}
@@ -282,7 +282,8 @@ static void sun4u_irq_enable(unsigned int virt_irq)
282 unsigned long cpuid, imap, val; 282 unsigned long cpuid, imap, val;
283 unsigned int tid; 283 unsigned int tid;
284 284
285 cpuid = irq_choose_cpu(virt_irq); 285 cpuid = irq_choose_cpu(virt_irq,
286 irq_desc[virt_irq].affinity);
286 imap = data->imap; 287 imap = data->imap;
287 288
288 tid = sun4u_compute_tid(imap, cpuid); 289 tid = sun4u_compute_tid(imap, cpuid);
@@ -299,7 +300,24 @@ static void sun4u_irq_enable(unsigned int virt_irq)
299static int sun4u_set_affinity(unsigned int virt_irq, 300static int sun4u_set_affinity(unsigned int virt_irq,
300 const struct cpumask *mask) 301 const struct cpumask *mask)
301{ 302{
302 sun4u_irq_enable(virt_irq); 303 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
304
305 if (likely(data)) {
306 unsigned long cpuid, imap, val;
307 unsigned int tid;
308
309 cpuid = irq_choose_cpu(virt_irq, mask);
310 imap = data->imap;
311
312 tid = sun4u_compute_tid(imap, cpuid);
313
314 val = upa_readq(imap);
315 val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
316 IMAP_AID_SAFARI | IMAP_NID_SAFARI);
317 val |= tid | IMAP_VALID;
318 upa_writeq(val, imap);
319 upa_writeq(ICLR_IDLE, data->iclr);
320 }
303 321
304 return 0; 322 return 0;
305} 323}
@@ -340,7 +358,8 @@ static void sun4u_irq_eoi(unsigned int virt_irq)
340static void sun4v_irq_enable(unsigned int virt_irq) 358static void sun4v_irq_enable(unsigned int virt_irq)
341{ 359{
342 unsigned int ino = virt_irq_table[virt_irq].dev_ino; 360 unsigned int ino = virt_irq_table[virt_irq].dev_ino;
343 unsigned long cpuid = irq_choose_cpu(virt_irq); 361 unsigned long cpuid = irq_choose_cpu(virt_irq,
362 irq_desc[virt_irq].affinity);
344 int err; 363 int err;
345 364
346 err = sun4v_intr_settarget(ino, cpuid); 365 err = sun4v_intr_settarget(ino, cpuid);
@@ -361,7 +380,7 @@ static int sun4v_set_affinity(unsigned int virt_irq,
361 const struct cpumask *mask) 380 const struct cpumask *mask)
362{ 381{
363 unsigned int ino = virt_irq_table[virt_irq].dev_ino; 382 unsigned int ino = virt_irq_table[virt_irq].dev_ino;
364 unsigned long cpuid = irq_choose_cpu(virt_irq); 383 unsigned long cpuid = irq_choose_cpu(virt_irq, mask);
365 int err; 384 int err;
366 385
367 err = sun4v_intr_settarget(ino, cpuid); 386 err = sun4v_intr_settarget(ino, cpuid);
@@ -403,7 +422,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
403 unsigned long cpuid, dev_handle, dev_ino; 422 unsigned long cpuid, dev_handle, dev_ino;
404 int err; 423 int err;
405 424
406 cpuid = irq_choose_cpu(virt_irq); 425 cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity);
407 426
408 dev_handle = virt_irq_table[virt_irq].dev_handle; 427 dev_handle = virt_irq_table[virt_irq].dev_handle;
409 dev_ino = virt_irq_table[virt_irq].dev_ino; 428 dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -433,7 +452,7 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq,
433 unsigned long cpuid, dev_handle, dev_ino; 452 unsigned long cpuid, dev_handle, dev_ino;
434 int err; 453 int err;
435 454
436 cpuid = irq_choose_cpu(virt_irq); 455 cpuid = irq_choose_cpu(virt_irq, mask);
437 456
438 dev_handle = virt_irq_table[virt_irq].dev_handle; 457 dev_handle = virt_irq_table[virt_irq].dev_handle;
439 dev_ino = virt_irq_table[virt_irq].dev_ino; 458 dev_ino = virt_irq_table[virt_irq].dev_ino;