diff options
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
-rw-r--r-- | arch/sparc/kernel/irq_64.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 8d6882bb480a..e1cbdb94d97b 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,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; |