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 | |
| 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>
| -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; |
