forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
a7aacdf9ea
commit
9001f2850f
@ -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)
|
|||||||
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;
|
||||||
|
if (is_tomatillo)
|
||||||
irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
|
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[] = {
|
|||||||
{ "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
|
||||||
|
Loading…
Reference in New Issue
Block a user