diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 898dae8ab6d9..09b1e1bbb29b 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/irq.h> | ||
14 | 15 | ||
15 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
16 | #include <asm/io.h> | 17 | #include <asm/io.h> |
@@ -18,7 +19,6 @@ | |||
18 | #include <asm/sections.h> | 19 | #include <asm/sections.h> |
19 | #include <asm/pci-bridge.h> | 20 | #include <asm/pci-bridge.h> |
20 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
21 | #include <asm/irq.h> | ||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/machdep.h> | 23 | #include <asm/machdep.h> |
24 | 24 | ||
@@ -1420,15 +1420,37 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1420 | 1420 | ||
1421 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 1421 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); |
1422 | 1422 | ||
1423 | /* Try to get a mapping from the device-tree */ | ||
1423 | if (of_irq_map_pci(pci_dev, &oirq)) { | 1424 | if (of_irq_map_pci(pci_dev, &oirq)) { |
1424 | DBG(" -> failed !\n"); | 1425 | u8 line, pin; |
1425 | return -1; | 1426 | |
1426 | } | 1427 | /* If that fails, lets fallback to what is in the config |
1428 | * space and map that through the default controller. We | ||
1429 | * also set the type to level low since that's what PCI | ||
1430 | * interrupts are. If your platform does differently, then | ||
1431 | * either provide a proper interrupt tree or don't use this | ||
1432 | * function. | ||
1433 | */ | ||
1434 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) | ||
1435 | return -1; | ||
1436 | if (pin == 0) | ||
1437 | return -1; | ||
1438 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || | ||
1439 | line == 0xff) { | ||
1440 | return -1; | ||
1441 | } | ||
1442 | DBG(" -> no map ! Using irq line %d from PCI config\n", line); | ||
1427 | 1443 | ||
1428 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | 1444 | virq = irq_create_mapping(NULL, line); |
1429 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | 1445 | if (virq != NO_IRQ) |
1446 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | ||
1447 | } else { | ||
1448 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | ||
1449 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | ||
1430 | 1450 | ||
1431 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); | 1451 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
1452 | oirq.size); | ||
1453 | } | ||
1432 | if(virq == NO_IRQ) { | 1454 | if(virq == NO_IRQ) { |
1433 | DBG(" -> failed to map !\n"); | 1455 | DBG(" -> failed to map !\n"); |
1434 | return -1; | 1456 | return -1; |