]> git.ipfire.org Git - people/ms/linux.git/blame - arch/x86/pci/irq.c
PCI: Replace deprecated __initcall with device_initcall.
[people/ms/linux.git] / arch / x86 / pci / irq.c
CommitLineData
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
25static int broken_hp_bios_irq9;
26static int acer_tm360_irqrouting;
27
28static struct irq_routing_table *pirq_table;
29
30static 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 */
37unsigned int pcibios_irq_mask = 0xfff8;
38
39static int pirq_penalty[16] = {
40 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
41 0, 0, 0, 0, 1000, 100000, 100000, 100000
42};
43
44struct 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
51struct irq_router_handler {
52 u16 vendor;
53 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
54};
55
56int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
87bec66b 57void (*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
64static 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) {