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/of_device_32.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/of_device_32.c')
-rw-r--r-- | arch/sparc/kernel/of_device_32.c | 59 |
1 files changed, 5 insertions, 54 deletions
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 2d055a1e9cc2..a312af40ea84 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/leon_amba.h> | 13 | #include <asm/leon_amba.h> |
14 | 14 | ||
15 | #include "of_device_common.h" | 15 | #include "of_device_common.h" |
16 | #include "irq.h" | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * PCI bus specific translator | 19 | * PCI bus specific translator |
@@ -355,7 +356,8 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, | |||
355 | if (intr) { | 356 | if (intr) { |
356 | op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); | 357 | op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); |
357 | for (i = 0; i < op->archdata.num_irqs; i++) | 358 | for (i = 0; i < op->archdata.num_irqs; i++) |
358 | op->archdata.irqs[i] = intr[i].pri; | 359 | op->archdata.irqs[i] = |
360 | sparc_irq_config.build_device_irq(op, intr[i].pri); | ||
359 | } else { | 361 | } else { |
360 | const unsigned int *irq = | 362 | const unsigned int *irq = |
361 | of_get_property(dp, "interrupts", &len); | 363 | of_get_property(dp, "interrupts", &len); |
@@ -363,64 +365,13 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, | |||
363 | if (irq) { | 365 | if (irq) { |
364 | op->archdata.num_irqs = len / sizeof(unsigned int); | 366 | op->archdata.num_irqs = len / sizeof(unsigned int); |
365 | for (i = 0; i < op->archdata.num_irqs; i++) | 367 | for (i = 0; i < op->archdata.num_irqs; i++) |
366 | op->archdata.irqs[i] = irq[i]; | 368 | op->archdata.irqs[i] = |
369 | sparc_irq_config.build_device_irq(op, irq[i]); | ||
367 | } else { | 370 | } else { |
368 | op->archdata.num_irqs = 0; | 371 | op->archdata.num_irqs = 0; |
369 | } | 372 | } |
370 | } | 373 | } |
371 | if (sparc_cpu_model == sun4d) { | ||
372 | static int pil_to_sbus[] = { | ||
373 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, | ||
374 | }; | ||
375 | struct device_node *io_unit, *sbi = dp->parent; | ||
376 | const struct linux_prom_registers *regs; | ||
377 | int board, slot; | ||
378 | |||
379 | while (sbi) { | ||
380 | if (!strcmp(sbi->name, "sbi")) | ||
381 | break; | ||
382 | |||
383 | sbi = sbi->parent; | ||
384 | } | ||
385 | if (!sbi) | ||
386 | goto build_resources; | ||
387 | |||
388 | regs = of_get_property(dp, "reg", NULL); | ||
389 | if (!regs) | ||
390 | goto build_resources; | ||
391 | |||
392 | slot = regs->which_io; | ||
393 | |||
394 | /* If SBI's parent is not io-unit or the io-unit lacks | ||
395 | * a "board#" property, something is very wrong. | ||
396 | */ | ||
397 | if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { | ||
398 | printk("%s: Error, parent is not io-unit.\n", | ||
399 | sbi->full_name); | ||
400 | goto build_resources; | ||
401 | } | ||
402 | io_unit = sbi->parent; | ||
403 | board = of_getintprop_default(io_unit, "board#", -1); | ||
404 | if (board == -1) { | ||
405 | printk("%s: Error, lacks board# property.\n", | ||
406 | io_unit->full_name); | ||
407 | goto build_resources; | ||
408 | } | ||
409 | |||
410 | for (i = 0; i < op->archdata.num_irqs; i++) { | ||
411 | int this_irq = op->archdata.irqs[i]; | ||
412 | int sbusl = pil_to_sbus[this_irq]; | ||
413 | |||
414 | if (sbusl) | ||
415 | this_irq = (((board + 1) << 5) + | ||
416 | (sbusl << 2) + | ||
417 | slot); | ||
418 | |||
419 | op->archdata.irqs[i] = this_irq; | ||
420 | } | ||
421 | } | ||
422 | 374 | ||
423 | build_resources: | ||
424 | build_device_resources(op, parent); | 375 | build_device_resources(op, parent); |
425 | 376 | ||
426 | op->dev.parent = parent; | 377 | op->dev.parent = parent; |