commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / kernel / acpi.c
1 /*
2  *  acpi.c - Architecture-Specific Low-Level ACPI Support
3  *
4  *  Copyright (C) 1999 VA Linux Systems
5  *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
6  *  Copyright (C) 2000, 2002-2003 Hewlett-Packard Co.
7  *      David Mosberger-Tang <davidm@hpl.hp.com>
8  *  Copyright (C) 2000 Intel Corp.
9  *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
10  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
11  *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
12  *  Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
13  *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
14  *
15  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16  *
17  *  This program is free software; you can redistribute it and/or modify
18  *  it under the terms of the GNU General Public License as published by
19  *  the Free Software Foundation; either version 2 of the License, or
20  *  (at your option) any later version.
21  *
22  *  This program is distributed in the hope that it will be useful,
23  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  *  GNU General Public License for more details.
26  *
27  *  You should have received a copy of the GNU General Public License
28  *  along with this program; if not, write to the Free Software
29  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  *
31  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32  */
33
34 #include <linux/config.h>
35 #include <linux/init.h>
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/smp.h>
39 #include <linux/string.h>
40 #include <linux/types.h>
41 #include <linux/irq.h>
42 #include <linux/acpi.h>
43 #include <linux/efi.h>
44 #include <asm/io.h>
45 #include <asm/iosapic.h>
46 #include <asm/machvec.h>
47 #include <asm/page.h>
48 #include <asm/system.h>
49 #include <asm/numa.h>
50
51
52 #define PREFIX                  "ACPI: "
53
54 void (*pm_idle) (void);
55 void (*pm_power_off) (void);
56
57 unsigned char acpi_kbd_controller_present = 1;
58
59 int acpi_disabled __initdata;   /* XXX this shouldn't be needed---we can't boot without ACPI! */
60
61 const char *
62 acpi_get_sysname (void)
63 {
64 #ifdef CONFIG_IA64_GENERIC
65         unsigned long rsdp_phys;
66         struct acpi20_table_rsdp *rsdp;
67         struct acpi_table_xsdt *xsdt;
68         struct acpi_table_header *hdr;
69
70         rsdp_phys = acpi_find_rsdp();
71         if (!rsdp_phys) {
72                 printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
73                 return "dig";
74         }
75
76         rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
77         if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
78                 printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
79                 return "dig";
80         }
81
82         xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
83         hdr = &xsdt->header;
84         if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
85                 printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
86                 return "dig";
87         }
88
89         if (!strcmp(hdr->oem_id, "HP")) {
90                 return "hpzx1";
91         }
92         else if (!strcmp(hdr->oem_id, "SGI")) {
93                 return "sn2";
94         }
95
96         return "dig";
97 #else
98 # if defined (CONFIG_IA64_HP_SIM)
99         return "hpsim";
100 # elif defined (CONFIG_IA64_HP_ZX1)
101         return "hpzx1";
102 # elif defined (CONFIG_IA64_SGI_SN2)
103         return "sn2";
104 # elif defined (CONFIG_IA64_DIG)
105         return "dig";
106 # else
107 #       error Unknown platform.  Fix acpi.c.
108 # endif
109 #endif
110 }
111
112 #ifdef CONFIG_ACPI_BOOT
113
114 #define ACPI_MAX_PLATFORM_INTERRUPTS    256
115
116 /* Array to record platform interrupt vectors for generic interrupt routing. */
117 int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
118         [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
119 };
120
121 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
122
123 /*
124  * Interrupt routing API for device drivers.  Provides interrupt vector for
125  * a generic platform event.  Currently only CPEI is implemented.
126  */
127 int
128 acpi_request_vector (u32 int_type)
129 {
130         int vector = -1;
131
132         if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
133                 /* correctable platform error interrupt */
134                 vector = platform_intr_list[int_type];
135         } else
136                 printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
137         return vector;
138 }
139
140 char *
141 __acpi_map_table (unsigned long phys_addr, unsigned long size)
142 {
143         return __va(phys_addr);
144 }
145
146 /* --------------------------------------------------------------------------
147                             Boot-time Table Parsing
148    -------------------------------------------------------------------------- */
149
150 static int                      total_cpus __initdata;
151 static int                      available_cpus __initdata;
152 struct acpi_table_madt *        acpi_madt __initdata;
153 static u8                       has_8259;
154
155
156 static int __init
157 acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
158 {
159         struct acpi_table_lapic_addr_ovr *lapic;
160
161         lapic = (struct acpi_table_lapic_addr_ovr *) header;
162         if (!lapic)
163                 return -EINVAL;
164
165         acpi_table_print_madt_entry(header);
166
167         if (lapic->address) {
168                 iounmap((void *) ipi_base_addr);
169                 ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
170         }
171         return 0;
172 }
173
174
175 static int __init
176 acpi_parse_lsapic (acpi_table_entry_header *header)
177 {
178         struct acpi_table_lsapic *lsapic;
179
180         lsapic = (struct acpi_table_lsapic *) header;
181         if (!lsapic)
182                 return -EINVAL;
183
184         acpi_table_print_madt_entry(header);
185
186         printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
187
188         if (!lsapic->flags.enabled)
189                 printk(" disabled");
190         else if (available_cpus >= NR_CPUS)
191                 printk(" ignored (increase NR_CPUS)");
192         else {
193                 printk(" enabled");
194 #ifdef CONFIG_SMP
195                 smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
196                 if (hard_smp_processor_id()
197                     == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
198                         printk(" (BSP)");
199 #endif
200                 ++available_cpus;
201         }
202
203         printk("\n");
204
205         total_cpus++;
206         return 0;
207 }
208
209
210 static int __init
211 acpi_parse_lapic_nmi (acpi_table_entry_header *header)
212 {
213         struct acpi_table_lapic_nmi *lacpi_nmi;
214
215         lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
216         if (!lacpi_nmi)
217                 return -EINVAL;
218
219         acpi_table_print_madt_entry(header);
220
221         /* TBD: Support lapic_nmi entries */
222         return 0;
223 }
224
225
226 static int __init
227 acpi_parse_iosapic (acpi_table_entry_header *header)
228 {
229         struct acpi_table_iosapic *iosapic;
230
231         iosapic = (struct acpi_table_iosapic *) header;
232         if (!iosapic)
233                 return -EINVAL;
234
235         acpi_table_print_madt_entry(header);
236
237         iosapic_init(iosapic->address, iosapic->global_irq_base);
238
239         return 0;
240 }
241
242
243 static int __init
244 acpi_parse_plat_int_src (acpi_table_entry_header *header)
245 {
246         struct acpi_table_plat_int_src *plintsrc;
247         int vector;
248
249         plintsrc = (struct acpi_table_plat_int_src *) header;
250         if (!plintsrc)
251                 return -EINVAL;
252
253         acpi_table_print_madt_entry(header);
254
255         /*
256          * Get vector assignment for this interrupt, set attributes,
257          * and program the IOSAPIC routing table.
258          */
259         vector = iosapic_register_platform_intr(plintsrc->type,
260                                                 plintsrc->global_irq,
261                                                 plintsrc->iosapic_vector,
262                                                 plintsrc->eid,
263                                                 plintsrc->id,
264                                                 (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
265                                                 (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
266
267         platform_intr_list[plintsrc->type] = vector;
268         return 0;
269 }
270
271
272 static int __init
273 acpi_parse_int_src_ovr (acpi_table_entry_header *header)
274 {
275         struct acpi_table_int_src_ovr *p;
276
277         p = (struct acpi_table_int_src_ovr *) header;
278         if (!p)
279                 return -EINVAL;
280
281         acpi_table_print_madt_entry(header);
282
283         iosapic_override_isa_irq(p->bus_irq, p->global_irq,
284                                  (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
285                                  (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
286         return 0;
287 }
288
289
290 static int __init
291 acpi_parse_nmi_src (acpi_table_entry_header *header)
292 {
293         struct acpi_table_nmi_src *nmi_src;
294
295         nmi_src = (struct acpi_table_nmi_src*) header;
296         if (!nmi_src)
297                 return -EINVAL;
298
299         acpi_table_print_madt_entry(header);
300
301         /* TBD: Support nimsrc entries */
302         return 0;
303 }
304
305
306 static int __init
307 acpi_parse_madt (unsigned long phys_addr, unsigned long size)
308 {
309         if (!phys_addr || !size)
310                 return -EINVAL;
311
312         acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
313
314         /* remember the value for reference after free_initmem() */
315 #ifdef CONFIG_ITANIUM
316         has_8259 = 1; /* Firmware on old Itanium systems is broken */
317 #else
318         has_8259 = acpi_madt->flags.pcat_compat;
319 #endif
320         iosapic_system_init(has_8259);
321
322         /* Get base address of IPI Message Block */
323
324         if (acpi_madt->lapic_address)
325                 ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
326
327         printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
328         return 0;
329 }
330
331
332 #ifdef CONFIG_ACPI_NUMA
333
334 #define SLIT_DEBUG
335
336 #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
337
338 static int __initdata srat_num_cpus;                    /* number of cpus */
339 static u32 __initdata pxm_flag[PXM_FLAG_LEN];
340 #define pxm_bit_set(bit)        (set_bit(bit,(void *)pxm_flag))
341 #define pxm_bit_test(bit)       (test_bit(bit,(void *)pxm_flag))
342 /* maps to convert between proximity domain and logical node ID */
343 int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
344 int __initdata nid_to_pxm_map[NR_NODES];
345 static struct acpi_table_slit __initdata *slit_table;
346
347 /*
348  * ACPI 2.0 SLIT (System Locality Information Table)
349  * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
350  */
351 void __init
352 acpi_numa_slit_init (struct acpi_table_slit *slit)
353 {
354         u32 len;
355
356         len = sizeof(struct acpi_table_header) + 8
357                 + slit->localities * slit->localities;
358         if (slit->header.length != len) {
359                 printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
360                        len, slit->header.length);
361                 memset(numa_slit, 10, sizeof(numa_slit));
362                 return;
363         }
364         slit_table = slit;
365 }
366
367 void __init
368 acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
369 {
370         /* record this node in proximity bitmap */
371         pxm_bit_set(pa->proximity_domain);
372
373         node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
374         /* nid should be overridden as logical node id later */
375         node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
376         srat_num_cpus++;
377 }
378
379 void __init
380 acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
381 {
382         unsigned long paddr, size, hole_size, min_hole_size;
383         u8 pxm;
384         struct node_memblk_s *p, *q, *pend;
385
386         pxm = ma->proximity_domain;
387
388         /* fill node memory chunk structure */
389         paddr = ma->base_addr_hi;
390         paddr = (paddr << 32) | ma->base_addr_lo;
391         size = ma->length_hi;
392         size = (size << 32) | ma->length_lo;
393
394         if (num_memblks >= NR_MEMBLKS) {
395                 printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
396                        size/(1024*1024), paddr);
397                 return;
398         }
399
400         /* Ignore disabled entries */
401         if (!ma->flags.enabled)
402                 return;
403
404         /*
405          * When the chunk is not the first one in the node, check distance
406          * from the other chunks. When the hole is too huge ignore the chunk.
407          * This restriction should be removed when multiple chunks per node
408          * is supported.
409          */
410         pend = &node_memblk[num_memblks];
411         min_hole_size = 0;
412         for (p = &node_memblk[0]; p < pend; p++) {
413                 if (p->nid != pxm)
414                         continue;
415                 if (p->start_paddr < paddr)
416                         hole_size = paddr - (p->start_paddr + p->size);
417                 else
418                         hole_size = p->start_paddr - (paddr + size);
419
420                 if (!min_hole_size || hole_size < min_hole_size)
421                         min_hole_size = hole_size;
422         }
423
424         if (min_hole_size) {
425                 if (min_hole_size > size) {
426                         printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
427                                size/(1024*1024), paddr);
428                         return;
429                 }
430         }
431
432         /* record this node in proximity bitmap */
433         pxm_bit_set(pxm);
434
435         /* Insertion sort based on base address */
436         pend = &node_memblk[num_memblks];
437         for (p = &node_memblk[0]; p < pend; p++) {
438                 if (paddr < p->start_paddr)
439                         break;
440         }
441         if (p < pend) {
442                 for (q = pend; q >= p; q--)
443                         *(q + 1) = *q;
444         }
445         p->start_paddr = paddr;
446         p->size = size;
447         p->nid = pxm;
448         num_memblks++;
449 }
450
451 void __init
452 acpi_numa_arch_fixup (void)
453 {
454         int i, j, node_from, node_to;
455
456         /* calculate total number of nodes in system from PXM bitmap */
457         numnodes = 0;           /* init total nodes in system */
458
459         memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
460         memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
461         for (i = 0; i < MAX_PXM_DOMAINS; i++) {
462                 if (pxm_bit_test(i)) {
463                         pxm_to_nid_map[i] = numnodes;
464                         nid_to_pxm_map[numnodes++] = i;
465                 }
466         }
467
468         /* set logical node id in memory chunk structure */
469         for (i = 0; i < num_memblks; i++)
470                 node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
471
472         /* assign memory bank numbers for each chunk on each node */
473         for (i = 0; i < numnodes; i++) {
474                 int bank;
475
476                 bank = 0;
477                 for (j = 0; j < num_memblks; j++)
478                         if (node_memblk[j].nid == i)
479                                 node_memblk[j].bank = bank++;
480         }
481
482         /* set logical node id in cpu structure */
483         for (i = 0; i < srat_num_cpus; i++)
484                 node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
485
486         printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
487         printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks);
488
489         if (!slit_table) return;
490         memset(numa_slit, -1, sizeof(numa_slit));
491         for (i=0; i<slit_table->localities; i++) {
492                 if (!pxm_bit_test(i))
493                         continue;
494                 node_from = pxm_to_nid_map[i];
495                 for (j=0; j<slit_table->localities; j++) {
496                         if (!pxm_bit_test(j))
497                                 continue;
498                         node_to = pxm_to_nid_map[j];
499                         node_distance(node_from, node_to) =
500                                 slit_table->entry[i*slit_table->localities + j];
501                 }
502         }
503
504 #ifdef SLIT_DEBUG
505         printk("ACPI 2.0 SLIT locality table:\n");
506         for (i = 0; i < numnodes; i++) {
507                 for (j = 0; j < numnodes; j++)
508                         printk("%03d ", node_distance(i,j));
509                 printk("\n");
510         }
511 #endif
512 }
513 #endif /* CONFIG_ACPI_NUMA */
514
515 static int __init
516 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
517 {
518         struct acpi_table_header *fadt_header;
519         struct fadt_descriptor_rev2 *fadt;
520
521         if (!phys_addr || !size)
522                 return -EINVAL;
523
524         fadt_header = (struct acpi_table_header *) __va(phys_addr);
525         if (fadt_header->revision != 3)
526                 return -ENODEV;         /* Only deal with ACPI 2.0 FADT */
527
528         fadt = (struct fadt_descriptor_rev2 *) fadt_header;
529
530         if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
531                 acpi_kbd_controller_present = 0;
532
533         acpi_register_irq(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
534         return 0;
535 }
536
537
538 unsigned long __init
539 acpi_find_rsdp (void)
540 {
541         unsigned long rsdp_phys = 0;
542
543         if (efi.acpi20)
544                 rsdp_phys = __pa(efi.acpi20);
545         else if (efi.acpi)
546                 printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
547         return rsdp_phys;
548 }
549
550
551 int __init
552 acpi_boot_init (void)
553 {
554
555         /*
556          * MADT
557          * ----
558          * Parse the Multiple APIC Description Table (MADT), if exists.
559          * Note that this table provides platform SMP configuration
560          * information -- the successor to MPS tables.
561          */
562
563         if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
564                 printk(KERN_ERR PREFIX "Can't find MADT\n");
565                 goto skip_madt;
566         }
567
568         /* Local APIC */
569
570         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0)
571                 printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
572
573         if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1)
574                 printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
575
576         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0)
577                 printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
578
579         /* I/O APIC */
580
581         if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1)
582                 printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
583
584         /* System-Level Interrupt Routing */
585
586         if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0)
587                 printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
588
589         if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0)
590                 printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
591
592         if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0)
593                 printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
594   skip_madt:
595
596         /*
597          * FADT says whether a legacy keyboard controller is present.
598          * The FADT also contains an SCI_INT line, by which the system
599          * gets interrupts such as power and sleep buttons.  If it's not
600          * on a Legacy interrupt, it needs to be setup.
601          */
602         if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
603                 printk(KERN_ERR PREFIX "Can't find FADT\n");
604
605 #ifdef CONFIG_SMP
606         smp_boot_data.cpu_count = available_cpus;
607         if (available_cpus == 0) {
608                 printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
609                 available_cpus = 1; /* We've got at least one of these, no? */
610         }
611
612         smp_build_cpu_map();
613 # ifdef CONFIG_NUMA
614         build_cpu_to_node_map();
615 # endif
616 #endif
617         /* Make boot-up look pretty */
618         printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
619         return 0;
620 }
621
622 /*
623  * PCI Interrupt Routing
624  */
625
626 #ifdef CONFIG_PCI
627 int __init
628 acpi_get_prt (struct pci_vector_struct **vectors, int *count)
629 {
630         struct pci_vector_struct *vector;
631         struct list_head *node;
632         struct acpi_prt_entry *entry;
633         int i = 0;
634
635         if (!vectors || !count)
636                 return -EINVAL;
637
638         *vectors = NULL;
639         *count = 0;
640
641         if (acpi_prt.count < 0) {
642                 printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n");
643                 return -ENODEV;
644         }
645
646         /* Allocate vectors */
647
648         *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);
649         if (!(*vectors))
650                 return -ENOMEM;
651
652         /* Convert PRT entries to IOSAPIC PCI vectors */
653
654         vector = *vectors;
655
656         list_for_each(node, &acpi_prt.entries) {
657                 entry = (struct acpi_prt_entry *)node;
658                 vector[i].segment = entry->id.segment;
659                 vector[i].bus    = entry->id.bus;
660                 vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
661                 vector[i].pin    = entry->pin;
662                 vector[i].irq    = entry->link.index;
663                 i++;
664         }
665         *count = acpi_prt.count;
666         return 0;
667 }
668 #endif /* CONFIG_PCI */
669
670 /* Assume IA64 always use I/O SAPIC */
671
672 int __init
673 acpi_get_interrupt_model (int *type)
674 {
675         if (!type)
676                 return -EINVAL;
677
678         *type = ACPI_IRQ_MODEL_IOSAPIC;
679         return 0;
680 }
681
682 int
683 acpi_irq_to_vector (u32 gsi)
684 {
685         if (has_8259 && gsi < 16)
686                 return isa_irq_to_vector(gsi);
687
688         return gsi_to_vector(gsi);
689 }
690
691 int
692 acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
693 {
694         if (has_8259 && gsi < 16)
695                 return isa_irq_to_vector(gsi);
696
697         return iosapic_register_intr(gsi,
698                         (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
699                         (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
700 }
701
702 #endif /* CONFIG_ACPI_BOOT */