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