diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_64.c')
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index efc0b5559ee0..2fce7738e9e2 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -21,13 +21,13 @@ | |||
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
24 | #include <linux/irq.h> | ||
24 | 25 | ||
25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
28 | #include <asm/pci-bridge.h> | 29 | #include <asm/pci-bridge.h> |
29 | #include <asm/byteorder.h> | 30 | #include <asm/byteorder.h> |
30 | #include <asm/irq.h> | ||
31 | #include <asm/machdep.h> | 31 | #include <asm/machdep.h> |
32 | #include <asm/ppc-pci.h> | 32 | #include <asm/ppc-pci.h> |
33 | 33 | ||
@@ -1289,15 +1289,37 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1289 | 1289 | ||
1290 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 1290 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); |
1291 | 1291 | ||
1292 | /* Try to get a mapping from the device-tree */ | ||
1292 | if (of_irq_map_pci(pci_dev, &oirq)) { | 1293 | if (of_irq_map_pci(pci_dev, &oirq)) { |
1293 | DBG(" -> failed !\n"); | 1294 | u8 line, pin; |
1294 | return -1; | 1295 | |
1295 | } | 1296 | /* If that fails, lets fallback to what is in the config |
1297 | * space and map that through the default controller. We | ||
1298 | * also set the type to level low since that's what PCI | ||
1299 | * interrupts are. If your platform does differently, then | ||
1300 | * either provide a proper interrupt tree or don't use this | ||
1301 | * function. | ||
1302 | */ | ||
1303 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) | ||
1304 | return -1; | ||
1305 | if (pin == 0) | ||
1306 | return -1; | ||
1307 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || | ||
1308 | line == 0xff) { | ||
1309 | return -1; | ||
1310 | } | ||
1311 | DBG(" -> no map ! Using irq line %d from PCI config\n", line); | ||
1296 | 1312 | ||
1297 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | 1313 | virq = irq_create_mapping(NULL, line); |
1298 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | 1314 | if (virq != NO_IRQ) |
1315 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | ||
1316 | } else { | ||
1317 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | ||
1318 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | ||
1299 | 1319 | ||
1300 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); | 1320 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
1321 | oirq.size); | ||
1322 | } | ||
1301 | if(virq == NO_IRQ) { | 1323 | if(virq == NO_IRQ) { |
1302 | DBG(" -> failed to map !\n"); | 1324 | DBG(" -> failed to map !\n"); |
1303 | return -1; | 1325 | return -1; |