diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2011-02-26 02:01:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-16 21:19:14 -0400 |
commit | 1d05995b0880b23353741d5b2b826f7c2fd6a296 (patch) | |
tree | 47fa622ab354f0fb88a7cb626797de186068d329 /arch/sparc/kernel/sun4d_irq.c | |
parent | bbdc2661eabddd442240533a66b2290f77d89ccc (diff) |
sparc32: introduce build_device_irq
build_device_irq() is used to encapsulate the plaform
specific details when we build an irq.
For now the default is a simple 1:1 but sun4d differs.
This patch refactors functionality - but does not change
the existing functionality.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/sun4d_irq.c')
-rw-r--r-- | arch/sparc/kernel/sun4d_irq.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index fc1c22f121f..77b4a899271 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c | |||
@@ -440,6 +440,56 @@ static void __init sun4d_load_profile_irqs(void) | |||
440 | } | 440 | } |
441 | } | 441 | } |
442 | 442 | ||
443 | unsigned int sun4d_build_device_irq(struct platform_device *op, | ||
444 | unsigned int real_irq) | ||
445 | { | ||
446 | static int pil_to_sbus[] = { | ||
447 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, | ||
448 | }; | ||
449 | struct device_node *dp = op->dev.of_node; | ||
450 | struct device_node *io_unit, *sbi = dp->parent; | ||
451 | const struct linux_prom_registers *regs; | ||
452 | int board, slot; | ||
453 | int sbusl; | ||
454 | |||
455 | while (sbi) { | ||
456 | if (!strcmp(sbi->name, "sbi")) | ||
457 | break; | ||
458 | |||
459 | sbi = sbi->parent; | ||
460 | } | ||
461 | if (!sbi) | ||
462 | goto err_out; | ||
463 | |||
464 | regs = of_get_property(dp, "reg", NULL); | ||
465 | if (!regs) | ||
466 | goto err_out; | ||
467 | |||
468 | slot = regs->which_io; | ||
469 | |||
470 | /* | ||
471 | * If SBI's parent is not io-unit or the io-unit lacks | ||
472 | * a "board#" property, something is very wrong. | ||
473 | */ | ||
474 | if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { | ||
475 | printk("%s: Error, parent is not io-unit.\n", sbi->full_name); | ||
476 | goto err_out; | ||
477 | } | ||
478 | io_unit = sbi->parent; | ||
479 | board = of_getintprop_default(io_unit, "board#", -1); | ||
480 | if (board == -1) { | ||
481 | printk("%s: Error, lacks board# property.\n", io_unit->full_name); | ||
482 | goto err_out; | ||
483 | } | ||
484 | |||
485 | sbusl = pil_to_sbus[real_irq]; | ||
486 | if (sbusl) | ||
487 | return (((board + 1) << 5) + (sbusl << 2) + slot); | ||
488 | |||
489 | err_out: | ||
490 | return real_irq; | ||
491 | } | ||
492 | |||
443 | static void __init sun4d_fixup_trap_table(void) | 493 | static void __init sun4d_fixup_trap_table(void) |
444 | { | 494 | { |
445 | #ifdef CONFIG_SMP | 495 | #ifdef CONFIG_SMP |
@@ -559,6 +609,7 @@ void __init sun4d_init_IRQ(void) | |||
559 | BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); | 609 | BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); |
560 | 610 | ||
561 | sparc_irq_config.init_timers = sun4d_init_timers; | 611 | sparc_irq_config.init_timers = sun4d_init_timers; |
612 | sparc_irq_config.build_device_irq = sun4d_build_device_irq; | ||
562 | 613 | ||
563 | #ifdef CONFIG_SMP | 614 | #ifdef CONFIG_SMP |
564 | BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); | 615 | BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); |