diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-10-29 16:32:31 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-10-30 19:33:33 -0800 |
commit | 9001f2850ff92b52d7654379e7b7feb72f78f161 (patch) | |
tree | 2482fa3e7653f633dad7b0e864ade020d390d719 | |
parent | a7aacdf9ea45bf6139cfd750e558a3dcbc6f16c3 (diff) | |
download | op-kernel-dev-9001f2850ff92b52d7654379e7b7feb72f78f161.zip op-kernel-dev-9001f2850ff92b52d7654379e7b7feb72f78f161.tar.gz |
[SPARC64]: Fix Tomatillo/Schizo IRQ handling.
The code in schizo_irq_trans_init() should set irq_data->sync_reg
to the location of the SYNC register if this is Tomatillo, and set
it to zero otherwise. But that is not what it is doing.
As a result, non-Tomatillo systems were trying to access a
non-existent register resulting in bus errors at the first
PCI interrupt.
Thanks to Roland Stigge for the bug report.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/prom.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c60efb3..0917c24 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void schizo_irq_trans_init(struct device_node *dp) +static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) { struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp) dp->irq_trans->data = irq_data; irq_data->pbm_regs = regs[0].phys_addr; - irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + if (is_tomatillo) + irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + else + irq_data->sync_reg = 0UL; irq_data->portid = of_getintprop_default(dp, "portid", 0); irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } +static void schizo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 0); +} + +static void tomatillo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 1); +} + static unsigned int pci_sun4v_irq_build(struct device_node *dp, unsigned int devino, void *_data) @@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = { { "pci108e,8001", schizo_irq_trans_init }, { "SUNW,schizo+", schizo_irq_trans_init }, { "pci108e,8002", schizo_irq_trans_init }, - { "SUNW,tomatillo", schizo_irq_trans_init }, - { "pci108e,a801", schizo_irq_trans_init }, + { "SUNW,tomatillo", tomatillo_irq_trans_init }, + { "pci108e,a801", tomatillo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, }; #endif |