powerpc: Make OF irq map code detect more error cases
PATCH 1/1 powerpc: Make OF irq map code detect more error cases
Device-tree bugs on js20 with some versions of SLOF were causing the interrupt for IDE to not be parsed correctly and fail to boot. This patch adds a bit more sanity checking to the parser to detet some of those errors and fail instead of returning bogus informations. The powerpc PCI code can then trigger a fallback that works on those machines.
arch/powerpc/kernel/pci_64.c +9 -2
@@ -1289,6 +1289,9 @@ int pci_read_irq_line(struct pci_dev *pcDBG ("Try to map irq for %s...\n" ,pci_name (pci_dev)); +#ifdef DEBUG +memset (&oirq,0xff ,sizeof (oirq)); +#endif /* Try to get a mapping from the device-tree */ if (of_irq_map_pci (pci_dev, &oirq)) {u8 line, pin;
@@ -1314,8 +1317,9 @@ int pci_read_irq_line(struct pci_dev *pcif (virq !=NO_IRQ )set_irq_type (virq,IRQ_TYPE_LEVEL_LOW ); }else { -DBG (" -> got one, spec %d cells (0x%08x...) on %s\n" , - oirq.size, oirq.specifier[0 ], oirq.controller->full_name); +DBG (" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n" , + oirq.size, oirq.specifier[0 ], oirq.specifier[1 ], + oirq.controller->full_name); virq =irq_create_of_mapping (oirq.controller, oirq.specifier, oirq.size);
@@ -1324,6 +1328,9 @@ int pci_read_irq_line(struct pci_dev *pcDBG (" -> failed to map !\n" );return -1 ; } + +DBG (" -> mapped to linux irq %d\n" , virq); + pci_dev->irq = virq;pci_write_config_byte (pci_dev,PCI_INTERRUPT_LINE , virq);
arch/powerpc/kernel/prom_parse.c +13 -4
@@ -644,14 +644,17 @@ void of_irq_map_init(unsigned int flags) } -int of_irq_map_raw (struct device_node *parent,u32 *intspec,u32 *addr, -struct of_irq *out_irq) +int of_irq_map_raw (struct device_node *parent,u32 *intspec,u32 ointsize, +u32 *addr,struct of_irq *out_irq) {struct device_node *ipar, *tnode, *old =NULL , *newpar =NULL ;u32 *tmp, *imap, *imask;u32 intsize =1 , addrsize, newintsize =0 , newaddrsize =0 ;int imaplen, match, i; +DBG ("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n" , + parent->full_name, intspec[0 ], intspec[1 ], ointsize); + ipar =of_node_get (parent);/* First get the #interrupt-cells property of the current cursor
@@ -675,6 +678,9 @@ int of_irq_map_raw(struct device_node *pDBG ("of_irq_map_raw: ipar=%s, size=%d\n" , ipar->full_name, intsize); +if (ointsize != intsize) +return -EINVAL ; +/* Look for this #address-cells. We have to implement the old linux * trick of looking for the parent here as some device-trees rely on it */
@@ -880,12 +886,15 @@ int of_irq_map_one(struct device_node *d } intsize = *tmp; +DBG (" intsize=%d intlen=%d\n" , intsize, intlen); +/* Check index */ if ((index +1 ) * intsize > intlen)return -EINVAL ;/* Get new specifier and map it */ - res =of_irq_map_raw (p, intspec + index * intsize, addr, out_irq); + res =of_irq_map_raw (p, intspec + index * intsize, intsize, + addr, out_irq);of_node_put (p);return res; }
@@ -964,7 +973,7 @@ int of_irq_map_pci(struct pci_dev *pdev, laddr[0 ] = (pdev->bus->number <<16 ) | (pdev->devfn <<8 ); laddr[1 ] = laddr[2 ] =0 ; -return of_irq_map_raw (ppnode, &lspec, laddr, out_irq); +return of_irq_map_raw (ppnode, &lspec,1 , laddr, out_irq); }EXPORT_SYMBOL_GPL (of_irq_map_pci);
include/asm-powerpc/prom.h +3 -1
@@ -276,6 +276,7 @@ extern void of_irq_map_init(unsigned int* of_irq_map_raw - Low level interrupt tree parsing * @parent: the device interrupt parent * @intspec: interrupt specifier ("interrupts" property of the device) +* @ointsize: size of the passed in interrupt specifier * @addr: address specifier (start of "reg" property of the device) * @out_irq: structure of_irq filled by this function *
@@ -288,7 +289,8 @@ extern void of_irq_map_init(unsigned int* */ -extern int of_irq_map_raw (struct device_node *parent,u32 *intspec,u32 *addr, +extern int of_irq_map_raw (struct device_node *parent,u32 *intspec, +u32 ointsize,u32 *addr,struct of_irq *out_irq);
Quoted 6 lines
Device-tree bugs on js20 with some versions of SLOF were causing the interrupt for IDE to not be parsed correctly and fail to boot. This patch adds a bit more sanity checking to the parser to detet some of those errors and fail instead of returning bogus informations. The powerpc PCI code can then trigger a fallback that works on those machines.
Quite similar to my patch you have been refusing, so I'll just
ACK
it, irrespective of if we need it or not (anymore) -- it's a good, useful, cheap sanity check. The patch looks good, too.
Segher