VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / parisc / iosapic.c
1 /*
2 ** I/O Sapic Driver - PCI interrupt line support
3 **
4 **      (c) Copyright 1999 Grant Grundler
5 **      (c) Copyright 1999 Hewlett-Packard Company
6 **
7 **      This program is free software; you can redistribute it and/or modify
8 **      it under the terms of the GNU General Public License as published by
9 **      the Free Software Foundation; either version 2 of the License, or
10 **      (at your option) any later version.
11 **
12 ** The I/O sapic driver manages the Interrupt Redirection Table which is
13 ** the control logic to convert PCI line based interrupts into a Message
14 ** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
15 **
16 ** Acronyms
17 ** --------
18 ** HPA  Hard Physical Address (aka MMIO address)
19 ** IRQ  Interrupt ReQuest. Implies Line based interrupt.
20 ** IRT  Interrupt Routing Table (provided by PAT firmware)
21 ** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
22 **      table which is implemented in I/O SAPIC.
23 ** ISR  Interrupt Service Routine. aka Interrupt handler.
24 ** MSI  Message Signaled Interrupt. PCI 2.2 functionality.
25 **      aka Transaction Based Interrupt (or TBI).
26 ** PA   Precision Architecture. HP's RISC architecture.
27 ** RISC Reduced Instruction Set Computer.
28 **
29 **
30 ** What's a Message Signalled Interrupt?
31 ** -------------------------------------
32 ** MSI is a write transaction which targets a processor and is similar
33 ** to a processor write to memory or MMIO. MSIs can be generated by I/O
34 ** devices as well as processors and require *architecture* to work.
35 **
36 ** PA only supports MSI. So I/O subsystems must either natively generate
37 ** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
38 ** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
39 ** acts on behalf of a processor.
40 **
41 ** MSI allows any I/O device to interrupt any processor. This makes
42 ** load balancing of the interrupt processing possible on an SMP platform.
43 ** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
44 ** coherent systems to completely eliminate PIO reads from the interrupt
45 ** path. The device and driver must be designed and implemented to
46 ** guarantee all DMA has been issued (issues about atomicity here)
47 ** before the MSI is issued. I/O status can then safely be read from
48 ** DMA'd data by the ISR.
49 **
50 **
51 ** PA Firmware
52 ** -----------
53 ** PA-RISC platforms have two fundementally different types of firmware.
54 ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
55 ** and BARs similar to a traditional PC BIOS.
56 ** The newer "PAT" firmware supports PDC calls which return tables.
57 ** PAT firmware only initializes PCI Console and Boot interface.
58 ** With these tables, the OS can progam all other PCI devices.
59 **
60 ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
61 ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
62 ** input line.  If the IRT is not available, this driver assumes
63 ** INTERRUPT_LINE register has been programmed by firmware. The latter
64 ** case also means online addition of PCI cards can NOT be supported
65 ** even if HW support is present.
66 **
67 ** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
68 ** Routing Table for the entire platform.
69 **
70 ** Where's the iosapic?
71 ** --------------------
72 ** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
73 ** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
74 ** will discover I/O Sapic. I/O Sapic driver learns about each device
75 ** when lba driver advertises the presence of the I/O sapic by calling
76 ** iosapic_register().
77 **
78 **
79 ** IRQ region notes
80 ** ----------------
81 ** The data passed to iosapic_interrupt() is per IRQ line.
82 ** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
83 ** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
84 ** implementations).  The IRQ region "sysdata" will NOT be directly passed
85 ** to the interrupt handler like GSCtoPCI (dino.c).
86 **
87 ** iosapic interrupt handler will NOT call do_irq_mask().
88 ** It doesn't need to read a bit mask to determine which IRQ line was pulled
89 ** since it already knows based on vector_info passed to iosapic_interrupt().
90 **
91 ** One IRQ number represents both an IRQ line and a driver ISR.
92 ** The I/O sapic driver can't manage shared IRQ lines because
93 ** additional data besides the IRQ number must be passed via
94 ** irq_region_ops. do_irq() and request_irq() must manage
95 ** a sharing a bit in the mask.
96 **
97 ** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
98 ** Which IRQ line was asserted is already known since each
99 ** line has unique data associated with it. We could omit
100 ** iosapic_interrupt() from the calling path if it did NOT need
101 ** to write EOI. For unshared lines, it really doesn't.
102 **
103 ** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
104 ** N-class console "device" and some sort of heartbeat actually share
105 ** one line though only one driver is registered...<sigh>...this was
106 ** true for HP-UX at least. May not be true for parisc-linux.
107 **
108 **
109 ** Overview of exported iosapic functions
110 ** --------------------------------------
111 ** (caveat: code isn't finished yet - this is just the plan)
112 **
113 ** iosapic_init:
114 **   o initialize globals (lock, etc)
115 **   o try to read IRT. Presence of IRT determines if this is
116 **     a PAT platform or not.
117 **
118 ** iosapic_register():
119 **   o create iosapic_info instance data structure
120 **   o allocate vector_info array for this iosapic
121 **   o initialize vector_info - read corresponding IRdT?
122 **
123 ** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
124 **   o intr_pin = read cfg (INTERRUPT_PIN);
125 **   o if (device under PCI-PCI bridge)
126 **               translate slot/pin
127 **
128 ** iosapic_fixup_irq:
129 **   o if PAT platform (IRT present)
130 **         intr_pin = iosapic_xlate_pin(isi,pcidev):
131 **         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
132 **         save IRT entry into vector_info later
133 **         write cfg INTERRUPT_LINE (with intr_line)?
134 **     else
135 **         intr_line = pcidev->irq
136 **         IRT pointer = NULL
137 **     endif
138 **   o locate vector_info (needs: isi, intr_line)
139 **   o allocate processor "irq" and get txn_addr/data
140 **   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
141 **   o pcidev->irq = isi->isi_region...base + intr_line;
142 **
143 ** iosapic_interrupt:
144 **   o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
145 **   o assume level triggered and write EOI
146 **
147 ** iosapic_enable_irq:
148 **   o clear any pending IRQ on that line
149 **   o enable IRdT - call enable_irq(vector[line]->processor_irq)
150 **   o write EOI in case line is already asserted.
151 **
152 ** iosapic_disable_irq:
153 **   o disable IRdT - call disable_irq(vector[line]->processor_irq)
154 **
155 ** FIXME: mask/unmask
156 */
157
158
159 /* FIXME: determine which include files are really needed */
160 #include <linux/types.h>
161 #include <linux/kernel.h>
162 #include <linux/spinlock.h>
163 #include <linux/pci.h>          /* pci cfg accessor functions  */
164 #include <linux/init.h>
165 #include <linux/slab.h>
166 #include <linux/smp_lock.h>
167 #include <linux/interrupt.h>    /* irqaction */
168 #include <linux/irq.h>          /* irq_region support */
169
170 #include <asm/byteorder.h>      /* get in-line asm for swab */
171 #include <asm/pdc.h>
172 #include <asm/pdcpat.h>
173 #include <asm/page.h>
174 #include <asm/segment.h>
175 #include <asm/system.h>
176 #include <asm/io.h>             /* read/write functions */
177 #ifdef CONFIG_SUPERIO
178 #include <asm/superio.h>
179 #endif
180
181 #include <asm/iosapic.h>
182 #include "./iosapic_private.h"
183
184 #define MODULE_NAME "iosapic"
185
186 /* "local" compile flags */
187 #undef PCI_BRIDGE_FUNCS
188 #undef DEBUG_IOSAPIC
189 #undef DEBUG_IOSAPIC_IRT
190
191
192 #ifdef DEBUG_IOSAPIC
193 static char assert_buf[128];
194
195 static int
196 assert_failed (char *a, char *f, int l)
197 {
198         sprintf(assert_buf,
199                         "ASSERT(%s) failed!\nline %d in %s\n",
200                         a,      /* assertion text */
201                         l,      /* line number */
202                         f);     /* file name */
203         panic(assert_buf);
204         return 0;
205 }
206
207 #undef ASSERT
208 #define ASSERT(EX) { if (!(EX)) assert_failed(# EX, __FILE__, __LINE__); }
209
210 #define DBG(x...) printk(x)
211
212 #else /* DEBUG_IOSAPIC */
213
214 #define DBG(x...)
215 #undef  ASSERT
216 #define ASSERT(EX)
217
218 #endif /* DEBUG_IOSAPIC */
219
220 #ifdef DEBUG_IOSAPIC_IRT
221 #define DBG_IRT(x...) printk(x)
222 #else
223 #define DBG_IRT(x...)
224 #endif
225
226
227 #define IOSAPIC_REG_SELECT              0x00
228 #define IOSAPIC_REG_WINDOW              0x10
229 #define IOSAPIC_REG_EOI                 0x40
230
231 #define IOSAPIC_REG_VERSION             0x1
232
233 #define IOSAPIC_IRDT_ENTRY(idx)         (0x10+(idx)*2)
234 #define IOSAPIC_IRDT_ENTRY_HI(idx)      (0x11+(idx)*2)
235
236 static inline unsigned int iosapic_read(unsigned long iosapic, unsigned int reg)
237 {
238         writel(reg, iosapic + IOSAPIC_REG_SELECT);
239         return readl(iosapic + IOSAPIC_REG_WINDOW);
240 }
241
242 static inline void iosapic_write(unsigned long iosapic, unsigned int reg, u32 val)
243 {
244         writel(reg, iosapic + IOSAPIC_REG_SELECT);
245         writel(val, iosapic + IOSAPIC_REG_WINDOW);
246 }
247
248 /*
249 **     GFP_KERNEL includes __GFP_WAIT flag and that may not
250 **     be acceptable. Since this is boot time, we shouldn't have
251 **     to wait ever and this code should (will?) never get called
252 **     from the interrrupt context.
253 */
254 #define IOSAPIC_KALLOC(a_type, cnt) \
255                         (a_type *) kmalloc(sizeof(a_type)*(cnt), GFP_KERNEL)
256 #define IOSAPIC_FREE(addr, f_type, cnt) kfree((void *)addr)
257
258
259 #define IOSAPIC_LOCK(lck)       spin_lock_irqsave(lck, irqflags)
260 #define IOSAPIC_UNLOCK(lck)     spin_unlock_irqrestore(lck, irqflags)
261
262
263 #define IOSAPIC_VERSION_MASK    0x000000ff
264 #define IOSAPIC_VERSION(ver)    ((int) (ver & IOSAPIC_VERSION_MASK))
265
266 #define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
267 #define IOSAPIC_MAX_ENTRY_SHIFT         0x10
268 #define IOSAPIC_IRDT_MAX_ENTRY(ver)     \
269         (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
270
271 /* bits in the "low" I/O Sapic IRdT entry */
272 #define IOSAPIC_IRDT_ENABLE       0x10000
273 #define IOSAPIC_IRDT_PO_LOW       0x02000
274 #define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
275 #define IOSAPIC_IRDT_MODE_LPRI    0x00100
276
277 /* bits in the "high" I/O Sapic IRdT entry */
278 #define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
279
280
281 static struct iosapic_info *iosapic_list;
282 static spinlock_t iosapic_lock;
283 static int iosapic_count;
284
285
286 /*
287 ** REVISIT: future platforms may have more than one IRT.
288 ** If so, the following three fields form a structure which
289 ** then be linked into a list. Names are chosen to make searching
290 ** for them easy - not necessarily accurate (eg "cell").
291 **
292 ** Alternative: iosapic_info could point to the IRT it's in.
293 ** iosapic_register() could search a list of IRT's.
294 */
295 static struct irt_entry *irt_cell;
296 static size_t irt_num_entry;
297
298
299
300 /*
301 ** iosapic_load_irt
302 **
303 ** The "Get PCI INT Routing Table Size" option returns the number of 
304 ** entries in the PCI interrupt routing table for the cell specified 
305 ** in the cell_number argument.  The cell number must be for a cell 
306 ** within the caller's protection domain.
307 **
308 ** The "Get PCI INT Routing Table" option returns, for the cell 
309 ** specified in the cell_number argument, the PCI interrupt routing 
310 ** table in the caller allocated memory pointed to by mem_addr.
311 ** We assume the IRT only contains entries for I/O SAPIC and
312 ** calculate the size based on the size of I/O sapic entries.
313 **
314 ** The PCI interrupt routing table entry format is derived from the
315 ** IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
316 ** the routing of PCI interrupt signals between the PCI device output
317 ** "pins" and the IO SAPICs' input "lines" (including core I/O PCI
318 ** devices).  This table does NOT include information for devices/slots
319 ** behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
320 ** for the architected method of routing of IRQ's behind PPB's.
321 */
322
323
324 static int __init /* return number of entries as success/fail flag */
325 iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
326 {
327         long status;              /* PDC return value status */
328         struct irt_entry *table;  /* start of interrupt routing tbl */
329         unsigned long num_entries = 0UL;
330
331         ASSERT(NULL != irt);
332
333         if (is_pdc_pat()) {
334
335                 /* Use pat pdc routine to get interrupt routing table size */
336                 DBG("calling get_irt_size (cell %ld)\n", cell_num);
337                 status = pdc_pat_get_irt_size(&num_entries, cell_num);
338                 DBG("get_irt_size: %ld\n", status);
339
340                 ASSERT(status == PDC_OK);
341
342                 /* save the number of entries in the table */
343                 ASSERT(0UL != num_entries);
344
345                 /*
346                 ** allocate memory for interrupt routing table
347                 ** This interface isn't really right. We are assuming
348                 ** the contents of the table are exclusively
349                 ** for I/O sapic devices.
350                 */
351                 table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
352                 if (table == NULL) {
353                         printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
354                         return 0;
355                 }
356
357                 /* get PCI INT routing table */
358                 status = pdc_pat_get_irt(table, cell_num);
359                 DBG("pdc_pat_get_irt: %ld\n", status);
360                 ASSERT(status == PDC_OK);
361         } else {
362                 /*
363                 ** C3000/J5000 (and similar) platforms with Sprockets PDC
364                 ** will return exactly one IRT for all iosapics.
365                 ** So if we have one, don't need to get it again.
366                 */
367                 if (NULL != irt_cell)
368                         return 0;
369
370                 /* Should be using the Elroy's HPA, but it's ignored anyway */
371                 status = pdc_pci_irt_size(&num_entries, 0);
372                 DBG("pdc_pci_irt_size: %ld\n", status);
373
374                 if (PDC_OK != status) {
375                         /* Not a "legacy" system with I/O SAPIC either */
376                         return 0;
377                 }
378
379                 ASSERT(0UL != num_entries);
380
381                 table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
382                 if (table == NULL) {
383                         printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
384                         return 0;
385                 }
386
387                 /* HPA ignored by this call too. */
388                 status = pdc_pci_irt(num_entries, 0, table);
389                 ASSERT(PDC_OK == status);
390         }
391
392         /* return interrupt table address */
393         *irt = table;
394
395 #ifdef DEBUG_IOSAPIC_IRT
396 {
397         struct irt_entry *p = table;
398         int i;
399
400         printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
401         printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
402                 table,
403                 num_entries,
404                 (int) sizeof(struct irt_entry));
405
406         for (i = 0 ; i < num_entries ; i++, p++) {
407                 printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
408                 p->entry_type, p->entry_length, p->interrupt_type,
409                 p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
410                 p->src_seg_id, p->dest_iosapic_intin,
411                 ((u32 *) p)[2],
412                 ((u32 *) p)[3]
413                 );
414         }
415 }
416 #endif /* DEBUG_IOSAPIC_IRT */
417
418         return num_entries;
419 }
420
421
422
423 void __init
424 iosapic_init(void)
425 {
426         unsigned long cell = 0;
427
428         /* init global data */
429         iosapic_lock = SPIN_LOCK_UNLOCKED;
430         iosapic_list = (struct iosapic_info *) NULL;
431         iosapic_count = 0;
432
433         DBG("iosapic_init()\n");
434
435 #ifdef __LP64__
436         if (is_pdc_pat()) {
437                 int status;
438                 struct pdc_pat_cell_num cell_info;
439
440                 status = pdc_pat_cell_get_number(&cell_info);
441                 if (status == PDC_OK) {
442                         cell = cell_info.cell_num;
443                 }
444         }
445 #endif
446
447         /*
448         **  get IRT for this cell.
449         */
450         irt_num_entry =  iosapic_load_irt(cell, &irt_cell);
451         if (0 == irt_num_entry)
452                 irt_cell = NULL;        /* old PDC w/o iosapic */
453 }
454
455
456 /*
457 ** Return the IRT entry in case we need to look something else up.
458 */
459 static struct irt_entry *
460 irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
461 {
462         struct irt_entry *i = irt_cell;
463         int cnt;        /* track how many entries we've looked at */
464         u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
465
466         DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
467
468         for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
469
470                 /*
471                 ** Validate: entry_type, entry_length, interrupt_type
472                 **
473                 ** Difference between validate vs compare is the former
474                 ** should print debug info and is not expected to "fail"
475                 ** on current platforms.
476                 */
477                 if (i->entry_type != IRT_IOSAPIC_TYPE) {
478                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
479                         continue;
480                 }
481                 
482                 if (i->entry_length != IRT_IOSAPIC_LENGTH) {
483                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
484                         continue;
485                 }
486
487                 if (i->interrupt_type != IRT_VECTORED_INTR) {
488                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
489                         continue;
490                 }
491
492                 /*
493                 ** Compare: dest_iosapic_addr, src_bus_irq_devno
494                 */
495                 if (i->dest_iosapic_addr != (u64) ((long) isi->isi_hpa))
496                         continue;
497
498                 if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
499                         continue;
500
501                 /*
502                 ** Ignore: src_bus_id and rc_seg_id correlate with
503                 **         iosapic_info->isi_hpa on HP platforms.
504                 **         If needed, pass in "PFA" (aka config space addr)
505                 **         instead of slot.
506                 */
507
508                 /* Found it! */
509                 return i;
510         }
511
512         printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
513                         isi->isi_hpa, slot, intr_pin);
514         return NULL;
515 }
516
517
518 /*
519 ** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
520 ** Legacy PDC already does this translation for us and stores it in INTR_LINE.
521 **
522 ** PAT PDC needs to basically do what legacy PDC does:
523 ** o read PIN
524 ** o adjust PIN in case device is "behind" a PPB
525 **     (eg 4-port 100BT and SCSI/LAN "Combo Card")
526 ** o convert slot/pin to I/O SAPIC input line.
527 **
528 ** HP platforms only support:
529 ** o one level of skewing for any number of PPBs
530 ** o only support PCI-PCI Bridges.
531 */
532 static struct irt_entry *
533 iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
534 {
535         u8 intr_pin, intr_slot;
536
537         pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
538
539         DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n",
540                 PCI_SLOT(pcidev->devfn), intr_pin);
541
542         if (0 == intr_pin) {
543                 /* The device does NOT support/use IRQ lines.  */
544                 return NULL;
545         }
546
547         /* Check if pcidev behind a PPB */
548         if (NULL != pcidev->bus->self) {
549                 /* Convert pcidev INTR_PIN into something we
550                 ** can lookup in the IRT.
551                 */
552 #ifdef PCI_BRIDGE_FUNCS
553                 /*
554                 ** Proposal #1:
555                 **
556                 ** call implementation specific translation function
557                 ** This is architecturally "cleaner". HP-UX doesn't
558                 ** support other secondary bus types (eg. E/ISA) directly.
559                 ** May be needed for other processor (eg IA64) architectures
560                 ** or by some ambitous soul who wants to watch TV.
561                 */
562                 if (pci_bridge_funcs->xlate_intr_line) {
563                         intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
564                 }
565 #else   /* PCI_BRIDGE_FUNCS */
566                 struct pci_bus *p = pcidev->bus;
567                 /*
568                 ** Proposal #2:
569                 ** The "pin" is skewed ((pin + dev - 1) % 4).
570                 **
571                 ** This isn't very clean since I/O SAPIC must assume:
572                 **   - all platforms only have PCI busses.
573                 **   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
574                 **   - IRQ routing is only skewed once regardless of
575                 **     the number of PPB's between iosapic and device.
576                 **     (Bit3 expansion chassis follows this rule)
577                 **
578                 ** Advantage is it's really easy to implement.
579                 */
580                 intr_pin = ((intr_pin-1)+PCI_SLOT(pcidev->devfn)) % 4;
581                 intr_pin++;     /* convert back to INTA-D (1-4) */
582 #endif /* PCI_BRIDGE_FUNCS */
583
584                 /*
585                 ** Locate the host slot the PPB nearest the Host bus
586                 ** adapter.
587                 */
588                 while (NULL != p->parent->self)
589                         p = p->parent;
590
591                 intr_slot = PCI_SLOT(p->self->devfn);
592         } else {
593                 intr_slot = PCI_SLOT(pcidev->devfn);
594         }
595         DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
596                                 pcidev->bus->secondary, intr_slot, intr_pin);
597
598         return irt_find_irqline(isi, intr_slot, intr_pin);
599 }
600
601
602 static irqreturn_t
603 iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
604 {
605         struct vector_info *vi = (struct vector_info *) dev_id;
606         extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
607         int irq_num = vi->iosapic->isi_region->data.irqbase + vi->irqline;
608
609         DBG("iosapic_interrupt(): irq %d line %d eoi 0x%p 0x%x\n",
610                 irq, vi->irqline, vi->eoi_addr, vi->eoi_data);
611
612         /* Do NOT need to mask/unmask IRQ. processor is already masked. */
613
614         do_irq(&vi->iosapic->isi_region->action[vi->irqline], irq_num, regs);
615
616         /*
617         ** PARISC only supports PCI devices below I/O SAPIC.
618         ** PCI only supports level triggered in order to share IRQ lines.
619         ** ergo I/O SAPIC must always issue EOI on parisc.
620         **
621         ** i386/ia64 support ISA devices and have to deal with
622         ** edge-triggered interrupts too.
623         */
624         __raw_writel(vi->eoi_data, vi->eoi_addr);
625         return IRQ_HANDLED;
626 }
627
628
629 int
630 iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
631 {
632         struct iosapic_info *isi = (struct iosapic_info *)isi_obj;
633         struct irt_entry *irte = NULL;  /* only used if PAT PDC */
634         struct vector_info *vi;
635         int isi_line;   /* line used by device */
636         int tmp;
637
638         if (NULL == isi) {
639                 printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
640                         pci_name(pcidev));
641                 return(-1);
642         }
643
644 #ifdef CONFIG_SUPERIO
645         /*
646          * HACK ALERT! (non-compliant PCI device support)
647          *
648          * All SuckyIO interrupts are routed through the PIC's on function 1.
649          * But SuckyIO OHCI USB controller gets an IRT entry anyway because
650          * it advertises INT D for INT_PIN.  Use that IRT entry to get the
651          * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
652          */
653         if (is_superio_device(pcidev)) {
654                 /* We must call superio_fixup_irq() to register the pdev */
655                 pcidev->irq = superio_fixup_irq(pcidev);
656
657                 /* Don't return if need to program the IOSAPIC's IRT... */
658                 if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
659                         return pcidev->irq;
660         }
661 #endif /* CONFIG_SUPERIO */
662
663         /* lookup IRT entry for isi/slot/pin set */
664         irte = iosapic_xlate_pin(isi, pcidev);
665         if (NULL == irte) {
666                 printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
667                                 pci_name(pcidev));
668                 return(-1);
669         }
670         DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
671                 irte,
672                 irte->entry_type,
673                 irte->entry_length,
674                 irte->polarity_trigger,
675                 irte->src_bus_irq_devno,
676                 irte->src_bus_id,
677                 irte->src_seg_id,
678                 irte->dest_iosapic_intin,
679                 (u32) irte->dest_iosapic_addr);
680         isi_line = irte->dest_iosapic_intin;
681         pcidev->irq = isi->isi_region->data.irqbase + isi_line;
682
683         /* get vector info for this input line */
684         ASSERT(NULL != isi->isi_vector);
685         vi = &(isi->isi_vector[isi_line]);
686         DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
687
688         /* If this IRQ line has already been setup, skip it */
689         if (vi->irte)
690                 return pcidev->irq;
691
692         vi->irte = irte;
693
694         /* Allocate processor IRQ */
695         vi->txn_irq = txn_alloc_irq();
696
697 /* XXX/FIXME The txn_alloc_irq() code and related code should be moved
698 ** to enable_irq(). That way we only allocate processor IRQ bits
699 ** for devices that actually have drivers claiming them.
700 ** Right now we assign an IRQ to every PCI device present regardless
701 ** of whether it's used or not.
702 */
703         if (vi->txn_irq < 0)
704                 panic("I/O sapic: couldn't get TXN IRQ\n");
705
706         /* enable_irq() will use txn_* to program IRdT */
707         vi->txn_addr = txn_alloc_addr(vi->txn_irq);
708         vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
709         ASSERT(vi->txn_data < 256);  /* matches 8 above */
710
711         tmp = request_irq(vi->txn_irq, iosapic_interrupt, 0,
712                                                 vi->name, vi);
713         ASSERT(tmp == 0);
714
715         vi->eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
716         vi->eoi_data = cpu_to_le32(vi->txn_data);
717         ASSERT(NULL != isi->isi_region);
718
719         DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
720                 PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->irq),
721                 pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
722
723         return pcidev->irq;
724 }
725
726
727 static void
728 iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
729 {
730         struct iosapic_info *isp = vi->iosapic;
731         u8 idx = vi->irqline;
732
733         *dp0 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(idx));
734         *dp1 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(idx));
735 }
736
737
738 static void
739 iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
740 {
741         struct iosapic_info *isp = vi->iosapic;
742
743         ASSERT(NULL != isp);
744         ASSERT(0 != isp->isi_hpa);
745         DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p 0x%x 0x%x\n",
746                 vi->irqline,
747                 isp->isi_hpa,
748                 dp0, dp1);
749
750         iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
751
752         /* Read the window register to flush the writes down to HW  */
753         dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
754
755         iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
756
757         /* Read the window register to flush the writes down to HW  */
758         dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
759 }
760
761
762 /*
763 ** set_irt prepares the data (dp0, dp1) according to the vector_info
764 ** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
765 ** IRdT for the given "vector" (aka IRQ line).
766 */
767 static void
768 iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
769 {
770         u32 mode = 0;
771         struct irt_entry *p = vi->irte;
772         ASSERT(NULL != vi->irte);
773
774         if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
775                 mode |= IOSAPIC_IRDT_PO_LOW;
776
777         if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
778                 mode |= IOSAPIC_IRDT_LEVEL_TRIG;
779
780         /*
781         ** IA64 REVISIT
782         ** PA doesn't support EXTINT or LPRIO bits.
783         */
784
785         ASSERT(vi->txn_data);
786         *dp0 = mode | (u32) vi->txn_data;
787
788         /*
789         ** Extracting id_eid isn't a real clean way of getting it.
790         ** But the encoding is the same for both PA and IA64 platforms.
791         */
792         if (is_pdc_pat()) {
793                 /*
794                 ** PAT PDC just hands it to us "right".
795                 ** txn_addr comes from cpu_data[x].txn_addr.
796                 */
797                 *dp1 = (u32) (vi->txn_addr);
798         } else {
799                 /* 
800                 ** eg if base_addr == 0xfffa0000),
801                 **    we want to get 0xa0ff0000.
802                 **
803                 ** eid  0x0ff00000 -> 0x00ff0000
804                 ** id   0x000ff000 -> 0xff000000
805                 */
806                 *dp1 = (((u32)vi->txn_addr & 0x0ff00000) >> 4) |
807                         (((u32)vi->txn_addr & 0x000ff000) << 12);
808         }
809         DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
810 }
811
812
813 static void
814 iosapic_disable_irq(void *irq_dev, int irq)
815 {
816         ulong irqflags;
817         struct vector_info *vi = &(((struct vector_info *) irq_dev)[irq]);
818         u32 d0, d1;
819
820         ASSERT(NULL != vi);
821
822         IOSAPIC_LOCK(&iosapic_lock);
823
824 #ifdef REVISIT_DESIGN_ISSUE
825 /* 
826 ** XXX/FIXME
827
828 disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
829
830 Current disable_irq interface only allows the irq_region support routines
831 to manage sharing of "irq" objects.  The problem is the disable_irq()
832 interface specifies which IRQ line needs to be disabled but does not
833 identify the particular ISR which needs to be disabled.  IO sapic
834 (and similar code in Dino) can only support one handler per IRQ
835 since they don't further encode the meaning of the IRQ number.
836 irq_region support has to hide it's implementation of "shared IRQ"
837 behind a function call.
838
839 Encoding the IRQ would be possible by I/O SAPIC but makes life really
840 complicated for the IRQ handler and not help performance.
841
842 Need more info on how Linux supports shared IRQ lines on a PC.
843 */
844 #endif /* REVISIT_DESIGN_ISSUE */
845
846         iosapic_rd_irt_entry(vi, &d0, &d1);
847         d0 |= IOSAPIC_IRDT_ENABLE;
848         iosapic_wr_irt_entry(vi, d0, d1);
849
850         IOSAPIC_UNLOCK(&iosapic_lock);
851
852         /* disable ISR for parent */
853         disable_irq(vi->txn_irq);
854 }
855
856
857 static void
858 iosapic_enable_irq(void *dev, int irq)
859 {
860         struct vector_info *vi = &(((struct vector_info *) dev)[irq]);
861         u32 d0, d1;
862
863         ASSERT(NULL != vi);
864         ASSERT(NULL != vi->irte);
865
866         /* data is initialized by fixup_irq */
867         ASSERT(0 < vi->txn_irq);
868         ASSERT(0UL != vi->txn_data);
869
870         iosapic_set_irt_data(vi, &d0, &d1);
871         iosapic_wr_irt_entry(vi, d0, d1);
872
873 #ifdef DEBUG_IOSAPIC_IRT
874 {
875         u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
876         printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
877         for ( ; t < vi->eoi_addr; t++)
878                 printk(" %x", readl(t));
879         printk("\n");
880 }
881
882 printk("iosapic_enable_irq(): sel ");
883 {
884         struct iosapic_info *isp = vi->iosapic;
885
886         for (d0=0x10; d0<0x1e; d0++) {
887                 d1 = iosapic_read(isp->isi_hpa, d0);
888                 printk(" %x", d1);
889         }
890 }
891 printk("\n");
892 #endif
893
894         /*
895         ** Issueing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
896         ** asserted.  IRQ generally should not be asserted when a driver
897         ** enables their IRQ. It can lead to "interesting" race conditions
898         ** in the driver initialization sequence.
899         */
900         __raw_writel(vi->eoi_data, vi->eoi_addr);
901 }
902
903
904 static void
905 iosapic_mask_irq(void *dev, int irq)
906 {
907         BUG();
908 }
909
910
911 static void
912 iosapic_unmask_irq(void *dev, int irq)
913 {
914         BUG();
915 }
916
917
918 static struct irq_region_ops iosapic_irq_ops = {
919         .disable_irq =  iosapic_disable_irq,
920         .enable_irq =   iosapic_enable_irq,
921         .mask_irq =     iosapic_mask_irq,
922         .unmask_irq =   iosapic_unmask_irq
923 };
924
925
926 /*
927 ** squirrel away the I/O Sapic Version
928 */
929 static unsigned int
930 iosapic_rd_version(struct iosapic_info *isi)
931 {
932         ASSERT(isi);
933         ASSERT(isi->isi_hpa);
934
935         return iosapic_read(isi->isi_hpa, IOSAPIC_REG_VERSION);
936 }
937
938
939 /*
940 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
941 ** Caller must be certain they have an I/O SAPIC and know its MMIO address.
942 **
943 **      o allocate iosapic_info and add it to the list
944 **      o read iosapic version and squirrel that away
945 **      o read size of IRdT.
946 **      o allocate and initialize isi_vector[]
947 **      o allocate isi_region (registers region handlers)
948 */
949 void *
950 iosapic_register(unsigned long hpa)
951 {
952         struct iosapic_info *isi = NULL;
953         struct irt_entry *irte = irt_cell;
954         struct vector_info *vip;
955         int cnt;        /* track how many entries we've looked at */
956
957         /*
958         ** Astro based platforms can't support PCI OLARD if they
959         ** implement the legacy PDC (not PAT). Though Legacy PDC
960         ** supports an IRT, LBA's with no device under them
961         ** are *not* listed in the IRT.
962         ** Search the IRT and ignore iosapic's which aren't
963         ** in the IRT.
964         */
965         ASSERT(NULL != irte);   /* always have built-in devices */
966         for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
967                 ASSERT(IRT_IOSAPIC_TYPE == irte->entry_type);
968                 /*
969                 ** We need sign extension of the hpa on 32-bit kernels.
970                 ** The address in the IRT is *always* 64 bit and really
971                 ** is an unsigned quantity (like all physical addresses).
972                 */ 
973                 if (irte->dest_iosapic_addr == (s64) ((long) hpa))
974                         break;
975         }
976
977         if (cnt  >= irt_num_entry)
978                 return (NULL);
979
980         if ((isi = IOSAPIC_KALLOC(struct iosapic_info, 1)) == NULL) {
981                 BUG();
982                 return (NULL);
983         }
984
985         memset(isi, 0, sizeof(struct iosapic_info));
986
987         isi->isi_hpa         = hpa;
988         isi->isi_version     = iosapic_rd_version(isi);
989         isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
990
991         vip = isi->isi_vector =
992                  IOSAPIC_KALLOC(struct vector_info, isi->isi_num_vectors);
993
994         if (vip == NULL) {
995                 IOSAPIC_FREE(isi, struct iosapic_info, 1);
996                 return (NULL);
997         }
998
999         memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
1000         sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
1001
1002         /*
1003         ** Initialize vector array
1004         */
1005         for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
1006                 vip->irqline = (unsigned char) cnt;
1007                 vip->iosapic = isi;
1008                 sprintf(vip->name, "%s-L%d", isi->isi_name, cnt);
1009         }
1010
1011         isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
1012                                 &iosapic_irq_ops, isi->isi_name,
1013                                 (void *) isi->isi_vector);
1014
1015         ASSERT(NULL != isi->isi_region);
1016         return ((void *) isi);
1017 }
1018
1019
1020 #ifdef DEBUG_IOSAPIC
1021
1022 static void
1023 iosapic_prt_irt(void *irt, long num_entry)
1024 {
1025         unsigned int i, *irp = (unsigned int *) irt;
1026
1027         ASSERT(NULL != irt);
1028
1029         printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
1030
1031         for (i=0; i<num_entry; i++, irp += 4) {
1032                 printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
1033                                         irp, i, irp[0], irp[1], irp[2], irp[3]);
1034         }
1035 }
1036
1037
1038 static void
1039 iosapic_prt_vi(struct vector_info *vi)
1040 {
1041         ASSERT(NULL != vi);
1042
1043         printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
1044         printk(KERN_DEBUG "\t\tstatus:   %.4x\n", vi->status);
1045         printk(KERN_DEBUG "\t\ttxn_irq:  %d\n",  vi->txn_irq);
1046         printk(KERN_DEBUG "\t\ttxn_addr: %lx\n", vi->txn_addr);
1047         printk(KERN_DEBUG "\t\ttxn_data: %lx\n", vi->txn_data);
1048         printk(KERN_DEBUG "\t\teoi_addr: %p\n",  vi->eoi_addr);
1049         printk(KERN_DEBUG "\t\teoi_data: %x\n",  vi->eoi_data);
1050 }
1051
1052
1053 static void
1054 iosapic_prt_isi(struct iosapic_info *isi)
1055 {
1056         ASSERT(NULL != isi);
1057         printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
1058         printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
1059         printk(KERN_DEBUG "\t\tisi_status:     %x\n", isi->isi_status);
1060         printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
1061         printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
1062 }
1063 #endif /* DEBUG_IOSAPIC */