Merge branch 'for-6.4/nintendo' into for-linus
[linux-block.git] / arch / x86 / pci / irq.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * Low-Level PCI Support for PC -- Routing of Interrupts
4 *
5 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
6 */
7
1da177e4
LT
8#include <linux/types.h>
9#include <linux/kernel.h>
10#include <linux/pci.h>
11#include <linux/init.h>
1da177e4 12#include <linux/interrupt.h>
1da177e4 13#include <linux/dmi.h>
7058b061
PC
14#include <linux/io.h>
15#include <linux/smp.h>
1ce849c7 16#include <linux/spinlock.h>
1da177e4 17#include <asm/io_apic.h>
b33fa1f3 18#include <linux/irq.h>
1da177e4 19#include <linux/acpi.h>
1ce849c7 20
d2531661 21#include <asm/i8259.h>
1ce849c7 22#include <asm/pc-conf-reg.h>
82487711 23#include <asm/pci_x86.h>
1da177e4
LT
24
25#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
26#define PIRQ_VERSION 0x0100
27
b584db0c
MR
28#define IRT_SIGNATURE (('$' << 0) + ('I' << 8) + ('R' << 16) + ('T' << 24))
29
1da177e4
LT
30static int broken_hp_bios_irq9;
31static int acer_tm360_irqrouting;
32
33static struct irq_routing_table *pirq_table;
34
35static int pirq_enable_irq(struct pci_dev *dev);
c03b3b07 36static void pirq_disable_irq(struct pci_dev *dev);
1da177e4
LT
37
38/*
39 * Never use: 0, 1, 2 (timer, keyboard, and cascade)
40 * Avoid using: 13, 14 and 15 (FP error and IDE).
41 * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
42 */
43unsigned int pcibios_irq_mask = 0xfff8;
44
45static int pirq_penalty[16] = {
46 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
47 0, 0, 0, 0, 1000, 100000, 100000, 100000
48};
49
50struct irq_router {
51 char *name;
52 u16 vendor, device;
53 int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
273c1127
MV
54 int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq,
55 int new);
1ce849c7
MR
56 int (*lvl)(struct pci_dev *router, struct pci_dev *dev, int pirq,
57 int irq);
1da177e4
LT
58};
59
60struct irq_router_handler {
61 u16 vendor;
62 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
63};
64
ab3b3793 65int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
c03b3b07 66void (*pcibios_disable_irq)(struct pci_dev *dev) = pirq_disable_irq;
1da177e4 67
120bb424 68/*
69 * Check passed address for the PCI IRQ Routing Table signature
70 * and perform checksum verification.
71 */
72
5d64089a
MR
73static inline struct irq_routing_table *pirq_check_routing_table(u8 *addr,
74 u8 *limit)
120bb424 75{
76 struct irq_routing_table *rt;
77 int i;
78 u8 sum;
79
c25f2345 80 rt = (struct irq_routing_table *)addr;
120bb424 81 if (rt->signature != PIRQ_SIGNATURE ||
82 rt->version != PIRQ_VERSION ||
83 rt->size % 16 ||
5d64089a
MR
84 rt->size < sizeof(struct irq_routing_table) ||
85 (limit && rt->size > limit - addr))
120bb424 86 return NULL;
87 sum = 0;
7058b061 88 for (i = 0; i < rt->size; i++)
120bb424 89 sum += addr[i];
90 if (!sum) {
613fa6e2
MR
91 DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%lx\n",
92 __pa(rt));
120bb424 93 return rt;
94 }
95 return NULL;
96}
97
b584db0c
MR
98/*
99 * Handle the $IRT PCI IRQ Routing Table format used by AMI for its BCP
100 * (BIOS Configuration Program) external tool meant for tweaking BIOS
101 * structures without the need to rebuild it from sources. The $IRT
102 * format has been invented by AMI before Microsoft has come up with its
103 * $PIR format and a $IRT table is therefore there in some systems that
104 * lack a $PIR table.
105 *
106 * It uses the same PCI BIOS 2.1 format for interrupt routing entries
107 * themselves but has a different simpler header prepended instead,
108 * occupying 8 bytes, where a `$IRT' signature is followed by one byte
109 * specifying the total number of interrupt routing entries allocated in
110 * the table, then one byte specifying the actual number of entries used
111 * (which the BCP tool can take advantage of when modifying the table),
112 * and finally a 16-bit word giving the IRQs devoted exclusively to PCI.
113 * Unlike with the $PIR table there is no alignment guarantee.
114 *
115 * Given the similarity of the two formats the $IRT one is trivial to
116 * convert to the $PIR one, which we do here, except that obviously we
117 * have no information as to the router device to use, but we can handle
118 * it by matching PCI device IDs actually seen on the bus against ones
119 * that our individual routers recognise.
120 *
121 * Reportedly there is another $IRT table format where a 16-bit word
122 * follows the header instead that points to interrupt routing entries
123 * in a $PIR table provided elsewhere. In that case this code will not
124 * be reached though as the $PIR table will have been chosen instead.
125 */
126static inline struct irq_routing_table *pirq_convert_irt_table(u8 *addr,
127 u8 *limit)
128{
129 struct irt_routing_table *ir;
130 struct irq_routing_table *rt;
131 u16 size;
132 u8 sum;
133 int i;
134
135 ir = (struct irt_routing_table *)addr;
136 if (ir->signature != IRT_SIGNATURE || !ir->used || ir->size < ir->used)
137 return NULL;
138
139 size = sizeof(*ir) + ir->used * sizeof(ir->slots[0]);
140 if (size > limit - addr)
141 return NULL;
142
143 DBG(KERN_DEBUG "PCI: $IRT Interrupt Routing Table found at 0x%lx\n",
144 __pa(ir));
145
146 size = sizeof(*rt) + ir->used * sizeof(rt->slots[0]);
147 rt = kzalloc(size, GFP_KERNEL);
148 if (!rt)
149 return NULL;
120bb424 150
b584db0c
MR
151 rt->signature = PIRQ_SIGNATURE;
152 rt->version = PIRQ_VERSION;
153 rt->size = size;
154 rt->exclusive_irqs = ir->exclusive_irqs;
155 for (i = 0; i < ir->used; i++)
156 rt->slots[i] = ir->slots[i];
157
158 addr = (u8 *)rt;
159 sum = 0;
160 for (i = 0; i < size; i++)
161 sum += addr[i];
162 rt->checksum = -sum;
163
164 return rt;
165}
120bb424 166
1da177e4
LT
167/*
168 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
169 */
170
171static struct irq_routing_table * __init pirq_find_routing_table(void)
172{
5d64089a
MR
173 u8 * const bios_start = (u8 *)__va(0xf0000);
174 u8 * const bios_end = (u8 *)__va(0x100000);
1da177e4
LT
175 u8 *addr;
176 struct irq_routing_table *rt;
1da177e4 177
120bb424 178 if (pirq_table_addr) {
5d64089a
MR
179 rt = pirq_check_routing_table((u8 *)__va(pirq_table_addr),
180 NULL);
120bb424 181 if (rt)
182 return rt;
183 printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
184 }
5d64089a
MR
185 for (addr = bios_start;
186 addr < bios_end - sizeof(struct irq_routing_table);
187 addr += 16) {
188 rt = pirq_check_routing_table(addr, bios_end);
120bb424 189 if (rt)
1da177e4 190 return rt;
1da177e4 191 }
b584db0c
MR
192 for (addr = bios_start;
193 addr < bios_end - sizeof(struct irt_routing_table);
194 addr++) {
195 rt = pirq_convert_irt_table(addr, bios_end);
196 if (rt)
197 return rt;
198 }
1da177e4
LT
199 return NULL;
200}
201
202/*
203 * If we have a IRQ routing table, use it to search for peer host
204 * bridges. It's a gross hack, but since there are no other known
205 * ways how to get a list of buses, we have to go this way.
206 */
207
208static void __init pirq_peer_trick(void)
209{
210 struct irq_routing_table *rt = pirq_table;
211 u8 busmap[256];
212 int i;
213 struct irq_info *e;
214
215 memset(busmap, 0, sizeof(busmap));
7058b061 216 for (i = 0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
1da177e4
LT
217 e = &rt->slots[i];
218#ifdef DEBUG
219 {
220 int j;
dc0e6408
MR
221 DBG(KERN_DEBUG "%02x:%02x.%x slot=%02x",
222 e->bus, e->devfn / 8, e->devfn % 8, e->slot);
7058b061 223 for (j = 0; j < 4; j++)
1da177e4
LT
224 DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
225 DBG("\n");
226 }
227#endif
228 busmap[e->bus] = 1;
229 }
7058b061 230 for (i = 1; i < 256; i++) {
1da177e4
LT
231 if (!busmap[i] || pci_find_bus(0, i))
232 continue;
49886cf4 233 pcibios_scan_root(i);
1da177e4
LT
234 }
235 pcibios_last_bus = -1;
236}
237
238/*
239 * Code for querying and setting of IRQ routes on various interrupt routers.
ea6cd250 240 * PIC Edge/Level Control Registers (ELCR) 0x4d0 & 0x4d1.
1da177e4
LT
241 */
242
ea6cd250 243void elcr_set_level_irq(unsigned int irq)
1da177e4
LT
244{
245 unsigned char mask = 1 << (irq & 7);
d2531661 246 unsigned int port = PIC_ELCR1 + (irq >> 3);
1da177e4 247 unsigned char val;
ea6cd250 248 static u16 elcr_irq_mask;
1da177e4 249
ea6cd250 250 if (irq >= 16 || (1 << irq) & elcr_irq_mask)
1da177e4
LT
251 return;
252
ea6cd250 253 elcr_irq_mask |= (1 << irq);