Skip to content

Commit

Permalink
sparc32: introduce build_device_irq
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
sravnborg authored and davem330 committed Mar 17, 2011
1 parent bbdc266 commit 1d05995
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 54 deletions.
4 changes: 4 additions & 0 deletions arch/sparc/kernel/irq.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <linux/platform_device.h>

#include <asm/btfixup.h>

/*
Expand All @@ -7,6 +9,8 @@
*/
struct sparc_irq_config {
void (*init_timers)(irq_handler_t);
unsigned int (*build_device_irq)(struct platform_device *op,
unsigned int real_irq);
};
extern struct sparc_irq_config sparc_irq_config;

Expand Down
8 changes: 8 additions & 0 deletions arch/sparc/kernel/irq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,12 @@ int probe_irq_off(unsigned long mask)
}
EXPORT_SYMBOL(probe_irq_off);

static unsigned int build_device_irq(struct platform_device *op,
unsigned int real_irq)
{
return real_irq;
}

/* djhr
* This could probably be made indirect too and assigned in the CPU
* bits of the code. That would be much nicer I think and would also
Expand All @@ -592,6 +598,8 @@ EXPORT_SYMBOL(probe_irq_off);

void __init init_IRQ(void)
{
sparc_irq_config.build_device_irq = build_device_irq;

switch (sparc_cpu_model) {
case sun4c:
case sun4:
Expand Down
59 changes: 5 additions & 54 deletions arch/sparc/kernel/of_device_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <asm/leon_amba.h>

#include "of_device_common.h"
#include "irq.h"

/*
* PCI bus specific translator
Expand Down Expand Up @@ -355,72 +356,22 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
if (intr) {
op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] = intr[i].pri;
op->archdata.irqs[i] =
sparc_irq_config.build_device_irq(op, intr[i].pri);
} else {
const unsigned int *irq =
of_get_property(dp, "interrupts", &len);

if (irq) {
op->archdata.num_irqs = len / sizeof(unsigned int);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] = irq[i];
op->archdata.irqs[i] =
sparc_irq_config.build_device_irq(op, irq[i]);
} else {
op->archdata.num_irqs = 0;
}
}
if (sparc_cpu_model == sun4d) {
static int pil_to_sbus[] = {
0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
};
struct device_node *io_unit, *sbi = dp->parent;
const struct linux_prom_registers *regs;
int board, slot;

while (sbi) {
if (!strcmp(sbi->name, "sbi"))
break;

sbi = sbi->parent;
}
if (!sbi)
goto build_resources;

regs = of_get_property(dp, "reg", NULL);
if (!regs)
goto build_resources;

slot = regs->which_io;

/* If SBI's parent is not io-unit or the io-unit lacks
* a "board#" property, something is very wrong.
*/
if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
printk("%s: Error, parent is not io-unit.\n",
sbi->full_name);
goto build_resources;
}
io_unit = sbi->parent;
board = of_getintprop_default(io_unit, "board#", -1);
if (board == -1) {
printk("%s: Error, lacks board# property.\n",
io_unit->full_name);
goto build_resources;
}

for (i = 0; i < op->archdata.num_irqs; i++) {
int this_irq = op->archdata.irqs[i];
int sbusl = pil_to_sbus[this_irq];

if (sbusl)
this_irq = (((board + 1) << 5) +
(sbusl << 2) +
slot);

op->archdata.irqs[i] = this_irq;
}
}

build_resources:
build_device_resources(op, parent);

op->dev.parent = parent;
Expand Down
51 changes: 51 additions & 0 deletions arch/sparc/kernel/sun4d_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,56 @@ static void __init sun4d_load_profile_irqs(void)
}
}

unsigned int sun4d_build_device_irq(struct platform_device *op,
unsigned int real_irq)
{
static int pil_to_sbus[] = {
0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
};
struct device_node *dp = op->dev.of_node;
struct device_node *io_unit, *sbi = dp->parent;
const struct linux_prom_registers *regs;
int board, slot;
int sbusl;

while (sbi) {
if (!strcmp(sbi->name, "sbi"))
break;

sbi = sbi->parent;
}
if (!sbi)
goto err_out;

regs = of_get_property(dp, "reg", NULL);
if (!regs)
goto err_out;

slot = regs->which_io;

/*
* If SBI's parent is not io-unit or the io-unit lacks
* a "board#" property, something is very wrong.
*/
if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
printk("%s: Error, parent is not io-unit.\n", sbi->full_name);
goto err_out;
}
io_unit = sbi->parent;
board = of_getintprop_default(io_unit, "board#", -1);
if (board == -1) {
printk("%s: Error, lacks board# property.\n", io_unit->full_name);
goto err_out;
}

sbusl = pil_to_sbus[real_irq];
if (sbusl)
return (((board + 1) << 5) + (sbusl << 2) + slot);

err_out:
return real_irq;
}

static void __init sun4d_fixup_trap_table(void)
{
#ifdef CONFIG_SMP
Expand Down Expand Up @@ -559,6 +609,7 @@ void __init sun4d_init_IRQ(void)
BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);

sparc_irq_config.init_timers = sun4d_init_timers;
sparc_irq_config.build_device_irq = sun4d_build_device_irq;

#ifdef CONFIG_SMP
BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM);
Expand Down

0 comments on commit 1d05995

Please sign in to comment.