Commit 9001f285 authored by David S. Miller's avatar David S. Miller

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent a7aacdf9
...@@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, ...@@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp,
return virt_irq; 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 linux_prom64_registers *regs;
struct schizo_irq_data *irq_data; struct schizo_irq_data *irq_data;
...@@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp) ...@@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp)
dp->irq_trans->data = irq_data; dp->irq_trans->data = irq_data;
irq_data->pbm_regs = regs[0].phys_addr; 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->portid = of_getintprop_default(dp, "portid", 0);
irq_data->chip_version = of_getintprop_default(dp, "version#", 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, static unsigned int pci_sun4v_irq_build(struct device_node *dp,
unsigned int devino, unsigned int devino,
void *_data) void *_data)
...@@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = { ...@@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = {
{ "pci108e,8001", schizo_irq_trans_init }, { "pci108e,8001", schizo_irq_trans_init },
{ "SUNW,schizo+", schizo_irq_trans_init }, { "SUNW,schizo+", schizo_irq_trans_init },
{ "pci108e,8002", schizo_irq_trans_init }, { "pci108e,8002", schizo_irq_trans_init },
{ "SUNW,tomatillo", schizo_irq_trans_init }, { "SUNW,tomatillo", tomatillo_irq_trans_init },
{ "pci108e,a801", schizo_irq_trans_init }, { "pci108e,a801", tomatillo_irq_trans_init },
{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
}; };
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment