diff options
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
| -rw-r--r-- | arch/sparc/kernel/irq_64.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index ce996f97855f..e1cbdb94d97b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
| @@ -176,7 +176,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | if (i < NR_IRQS) { | 178 | if (i < NR_IRQS) { |
| 179 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 179 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); |
| 180 | action = irq_desc[i].action; | 180 | action = irq_desc[i].action; |
| 181 | if (!action) | 181 | if (!action) |
| 182 | goto skip; | 182 | goto skip; |
| @@ -195,7 +195,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 195 | 195 | ||
| 196 | seq_putc(p, '\n'); | 196 | seq_putc(p, '\n'); |
| 197 | skip: | 197 | skip: |
| 198 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 198 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
| 199 | } else if (i == NR_IRQS) { | 199 | } else if (i == NR_IRQS) { |
| 200 | seq_printf(p, "NMI: "); | 200 | seq_printf(p, "NMI: "); |
| 201 | for_each_online_cpu(j) | 201 | for_each_online_cpu(j) |
| @@ -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,10 +268,8 @@ 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 | #define irq_choose_cpu(virt_irq, affinity) \ |
| 272 | { | 272 | real_hard_smp_processor_id() |
| 273 | return real_hard_smp_processor_id(); | ||
| 274 | } | ||
| 275 | #endif | 273 | #endif |
| 276 | 274 | ||
| 277 | static void sun4u_irq_enable(unsigned int virt_irq) | 275 | static void sun4u_irq_enable(unsigned int virt_irq) |
| @@ -282,7 +280,8 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
| 282 | unsigned long cpuid, imap, val; | 280 | unsigned long cpuid, imap, val; |
| 283 | unsigned int tid; | 281 | unsigned int tid; |
| 284 | 282 | ||
| 285 | cpuid = irq_choose_cpu(virt_irq); | 283 | cpuid = irq_choose_cpu(virt_irq, |
| 284 | irq_desc[virt_irq].affinity); | ||
| 286 | imap = data->imap; | 285 | imap = data->imap; |
| 287 | 286 | ||
| 288 | tid = sun4u_compute_tid(imap, cpuid); | 287 | tid = sun4u_compute_tid(imap, cpuid); |
| @@ -299,7 +298,24 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
| 299 | static int sun4u_set_affinity(unsigned int virt_irq, | 298 | static int sun4u_set_affinity(unsigned int virt_irq, |
| 300 | const struct cpumask *mask) | 299 | const struct cpumask *mask) |
| 301 | { | 300 | { |
| 302 | sun4u_irq_enable(virt_irq); | 301 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
| 302 | |||
| 303 | if (likely(data)) { | ||
| 304 | unsigned long cpuid, imap, val; | ||
| 305 | unsigned int tid; | ||
| 306 | |||
| 307 | cpuid = irq_choose_cpu(virt_irq, mask); | ||
| 308 | imap = data->imap; | ||
| 309 | |||
| 310 | tid = sun4u_compute_tid(imap, cpuid); | ||
| 311 | |||
| 312 | val = upa_readq(imap); | ||
| 313 | val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS | | ||
| 314 | IMAP_AID_SAFARI | IMAP_NID_SAFARI); | ||
| 315 | val |= tid | IMAP_VALID; | ||
| 316 | upa_writeq(val, imap); | ||
| 317 | upa_writeq(ICLR_IDLE, data->iclr); | ||
| 318 | } | ||
| 303 | 319 | ||
| 304 | return 0; | 320 | return 0; |
| 305 | } | 321 | } |
| @@ -340,7 +356,8 @@ static void sun4u_irq_eoi(unsigned int virt_irq) | |||
| 340 | static void sun4v_irq_enable(unsigned int virt_irq) | 356 | static void sun4v_irq_enable(unsigned int virt_irq) |
| 341 | { | 357 | { |
| 342 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; | 358 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; |
| 343 | unsigned long cpuid = irq_choose_cpu(virt_irq); | 359 | unsigned long cpuid = irq_choose_cpu(virt_irq, |
| 360 | irq_desc[virt_irq].affinity); | ||
| 344 | int err; | 361 | int err; |
| 345 | 362 | ||
| 346 | err = sun4v_intr_settarget(ino, cpuid); | 363 | err = sun4v_intr_settarget(ino, cpuid); |
| @@ -361,7 +378,7 @@ static int sun4v_set_affinity(unsigned int virt_irq, | |||
| 361 | const struct cpumask *mask) | 378 | const struct cpumask *mask) |
| 362 | { | 379 | { |
| 363 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; | 380 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; |
| 364 | unsigned long cpuid = irq_choose_cpu(virt_irq); | 381 | unsigned long cpuid = irq_choose_cpu(virt_irq, mask); |
| 365 | int err; | 382 | int err; |
| 366 | 383 | ||
| 367 | err = sun4v_intr_settarget(ino, cpuid); | 384 | err = sun4v_intr_settarget(ino, cpuid); |
| @@ -403,7 +420,7 @@ static void sun4v_virq_enable(unsigned int virt_irq) | |||
| 403 | unsigned long cpuid, dev_handle, dev_ino; | 420 | unsigned long cpuid, dev_handle, dev_ino; |
| 404 | int err; | 421 | int err; |
| 405 | 422 | ||
| 406 | cpuid = irq_choose_cpu(virt_irq); | 423 | cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity); |
| 407 | 424 | ||
| 408 | dev_handle = virt_irq_table[virt_irq].dev_handle; | 425 | dev_handle = virt_irq_table[virt_irq].dev_handle; |
| 409 | dev_ino = virt_irq_table[virt_irq].dev_ino; | 426 | dev_ino = virt_irq_table[virt_irq].dev_ino; |
| @@ -433,7 +450,7 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq, | |||
| 433 | unsigned long cpuid, dev_handle, dev_ino; | 450 | unsigned long cpuid, dev_handle, dev_ino; |
| 434 | int err; | 451 | int err; |
| 435 | 452 | ||
| 436 | cpuid = irq_choose_cpu(virt_irq); | 453 | cpuid = irq_choose_cpu(virt_irq, mask); |
| 437 | 454 | ||
| 438 | dev_handle = virt_irq_table[virt_irq].dev_handle; | 455 | dev_handle = virt_irq_table[virt_irq].dev_handle; |
| 439 | dev_ino = virt_irq_table[virt_irq].dev_ino; | 456 | dev_ino = virt_irq_table[virt_irq].dev_ino; |
| @@ -785,14 +802,14 @@ void fixup_irqs(void) | |||
| 785 | for (irq = 0; irq < NR_IRQS; irq++) { | 802 | for (irq = 0; irq < NR_IRQS; irq++) { |
| 786 | unsigned long flags; | 803 | unsigned long flags; |
| 787 | 804 | ||
| 788 | spin_lock_irqsave(&irq_desc[irq].lock, flags); | 805 | raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); |
| 789 | if (irq_desc[irq].action && | 806 | if (irq_desc[irq].action && |
| 790 | !(irq_desc[irq].status & IRQ_PER_CPU)) { | 807 | !(irq_desc[irq].status & IRQ_PER_CPU)) { |
| 791 | if (irq_desc[irq].chip->set_affinity) | 808 | if (irq_desc[irq].chip->set_affinity) |
| 792 | irq_desc[irq].chip->set_affinity(irq, | 809 | irq_desc[irq].chip->set_affinity(irq, |
| 793 | irq_desc[irq].affinity); | 810 | irq_desc[irq].affinity); |
| 794 | } | 811 | } |
| 795 | spin_unlock_irqrestore(&irq_desc[irq].lock, flags); | 812 | raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); |
| 796 | } | 813 | } |
| 797 | 814 | ||
| 798 | tick_ops->disable_irq(); | 815 | tick_ops->disable_irq(); |
