Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Low-Level PCI Support for PC -- Routing of Interrupts | |
3 | * | |
4 | * (c) 1999--2000 Martin Mares <mj@ucw.cz> | |
5 | */ | |
6 | ||
1da177e4 LT |
7 | #include <linux/types.h> |
8 | #include <linux/kernel.h> | |
9 | #include <linux/pci.h> | |
10 | #include <linux/init.h> | |
11 | #include <linux/slab.h> | |
12 | #include <linux/interrupt.h> | |
1da177e4 LT |
13 | #include <linux/dmi.h> |
14 | #include <asm/io.h> | |
15 | #include <asm/smp.h> | |
16 | #include <asm/io_apic.h> | |
b33fa1f3 | 17 | #include <linux/irq.h> |
1da177e4 LT |
18 | #include <linux/acpi.h> |
19 | ||
20 | #include "pci.h" | |
21 | ||
22 | #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) | |
23 | #define PIRQ_VERSION 0x0100 | |
24 | ||
25 | static int broken_hp_bios_irq9; | |
26 | static int acer_tm360_irqrouting; | |
27 | ||
28 | static struct irq_routing_table *pirq_table; | |
29 | ||
30 | static int pirq_enable_irq(struct pci_dev *dev); | |
31 | ||
32 | /* | |
33 | * Never use: 0, 1, 2 (timer, keyboard, and cascade) | |
34 | * Avoid using: 13, 14 and 15 (FP error and IDE). | |
35 | * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse) | |
36 | */ | |
37 | unsigned int pcibios_irq_mask = 0xfff8; | |
38 | ||
39 | static int pirq_penalty[16] = { | |
40 | 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000, | |
41 | 0, 0, 0, 0, 1000, 100000, 100000, 100000 | |
42 | }; | |
43 | ||
44 | struct irq_router { | |
45 | char *name; | |
46 | u16 vendor, device; | |
47 | int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq); | |
48 | int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new); | |
49 | }; | |
50 | ||
51 | struct irq_router_handler { | |
52 | u16 vendor; | |
53 | int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); | |
54 | }; | |
55 | ||
56 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | |
87bec66b | 57 | void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL; |
1da177e4 | 58 | |
120bb424 | 59 | /* |
60 | * Check passed address for the PCI IRQ Routing Table signature | |
61 | * and perform checksum verification. | |
62 | */ | |
63 | ||
64 | static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) | |
65 | { | |
66 | struct irq_routing_table *rt; | |
67 | int i; | |
68 | u8 sum; | |
69 | ||
70 | rt = (struct irq_routing_table *) addr; | |
71 | if (rt->signature != PIRQ_SIGNATURE || | |
72 | rt->version != PIRQ_VERSION || | |
73 | rt->size % 16 || | |
74 | rt->size < sizeof(struct irq_routing_table)) | |
75 | return NULL; | |
76 | sum = 0; | |
77 | for (i=0; i < rt->size; i++) | |
78 | sum += addr[i]; | |
79 | if (!sum) { |