Commit 024050ec authored by Tom Rini's avatar Tom Rini

ppc32: On PReP, allow for residual data to provide IRQ level/edge info

This adds a function to determine the 8259 level/edge mask word.
With this function we can now (in theory) support any IBM PReP
machine.  We therefore add a little bit more code to fallback
to using residual data if we don't recognise the machine.
Signed-off-by: default avatarLeigh Brown <leigh@solinno.co.uk>
Signed-off-by: default avatarTom Rini <trini@kernel.crashing.org>
parent ad2d538c
......@@ -900,6 +900,17 @@ ibm43p_pci_map_non0(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
void __init
prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
{
if (have_residual_data) {
Motherboard_map_name = res->VitalProductData.PrintableModel;
Motherboard_map = NULL;
Motherboard_routes = NULL;
residual_irq_mask(irq_edge_mask_lo, irq_edge_mask_hi);
}
}
void __init
prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
{
......@@ -1022,10 +1033,13 @@ prep_route_pci_interrupts(void)
}
/* Set up mapping from slots */
for (i = 1; i <= 4; i++)
ibc_pirq[i-1] = Motherboard_routes[i];
/* Enable PCI interrupts */
*ibc_pcicon |= 0x20;
if (Motherboard_routes) {
for (i = 1; i <= 4; i++)
ibc_pirq[i-1] = Motherboard_routes[i];
/* Enable PCI interrupts */
*ibc_pcicon |= 0x20;
}
}
void __init
......
......@@ -79,6 +79,7 @@ extern void prep_find_bridges(void);
int _prep_type;
extern void prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
extern void prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
extern void prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
extern void prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
......@@ -208,6 +209,13 @@ prep_ibm_cpuinfo(struct seq_file *m)
}
}
static int __prep
prep_gen_cpuinfo(struct seq_file *m)
{
prep_ibm_cpuinfo(m);
return 0;
}
static int __prep
prep_sandalfoot_cpuinfo(struct seq_file *m)
{
......@@ -815,7 +823,16 @@ prep_setup_arch(void)
ppc_md.show_cpuinfo = prep_thinkpad_cpuinfo;
break;
default:
printk(" -- unknown! Assuming Carolina");
if (have_residual_data) {
prep_gen_enable_l2();
setup_ibm_pci = prep_residual_setup_pci;
ppc_md.power_off = prep_halt;
ppc_md.show_cpuinfo = prep_gen_cpuinfo;
break;
}
else
printk(" - unknown! Assuming Carolina");
/* fall through */
case PREP_IBM_CAROLINA_IDE_0:
case PREP_IBM_CAROLINA_IDE_1:
case PREP_IBM_CAROLINA_IDE_2:
......
......@@ -887,6 +887,36 @@ residual_pcidev_irq(struct pci_dev *dev)
return (irq < 0) ? 0 : irq;
}
void __init residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
{
PPC_DEVICE *dev;
int i = 0;
unsigned short irq_mask = 0x000; /* default to edge */
while ((dev = residual_find_device(-1, NULL, -1, -1, -1, i++))) {
PnP_TAG_PACKET *pkt;
unsigned short mask;
int size;
int offset = dev->AllocatedOffset;
if (!offset)
continue;
pkt = PnP_find_packet(res->DevicePnPHeap + offset,
IRQFormat, 0);
if (!pkt)
continue;
size = tag_small_count(pkt->S1_Pack.Tag) + 1;
mask = ld_le16((unsigned short *)pkt->S4_Pack.IRQMask);
if (size > 3 && (pkt->S4_Pack.IRQInfo & 0x0c))
irq_mask |= mask;
}
*irq_edge_mask_lo = irq_mask & 0xff;
*irq_edge_mask_hi = irq_mask >> 8;
}
PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
unsigned packet_tag,
int n)
......
......@@ -327,6 +327,7 @@ extern PPC_DEVICE *residual_find_device(unsigned long BusMask,
unsigned char * DevID, int BaseType,
int SubType, int Interface, int n);
extern int residual_pcidev_irq(struct pci_dev *dev);
extern void residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
extern PnP_TAG_PACKET *PnP_find_packet(unsigned char *p, unsigned packet_tag,
int n);
extern PnP_TAG_PACKET *PnP_find_small_vendor_packet(unsigned char *p,
......
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