diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-20 22:30:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-20 22:30:49 -0500 |
commit | 1091ce6215a1cab60c3a4601a569cb727ca8637a (patch) | |
tree | 45038c0ee7cc4f83d268098ce8c91bfa97e63c07 /arch/sparc/kernel | |
parent | e5981fd6d77c63c003cac44ab52da72994e7ead3 (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.c | 37 |
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 |
253 | static int irq_choose_cpu(unsigned int virt_irq) | 253 | static 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 |
271 | static int irq_choose_cpu(unsigned int virt_irq) | 271 | static 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) | |||
299 | static int sun4u_set_affinity(unsigned int virt_irq, | 300 | static 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) | |||
340 | static void sun4v_irq_enable(unsigned int virt_irq) | 358 | static 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; |