]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/visws_quirks.c
arch/x86/kernel/visws_quirks.c: Removed duplicated #include
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / visws_quirks.c
1 /*
2  *  SGI Visual Workstation support and quirks, unmaintained.
3  *
4  *  Split out from setup.c by davej@suse.de
5  *
6  *      Copyright (C) 1999 Bent Hagemark, Ingo Molnar
7  *
8  *  SGI Visual Workstation interrupt controller
9  *
10  *  The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC
11  *  which serves as the main interrupt controller in the system.  Non-legacy
12  *  hardware in the system uses this controller directly.  Legacy devices
13  *  are connected to the PIIX4 which in turn has its 8259(s) connected to
14  *  a of the Cobalt APIC entry.
15  *
16  *  09/02/2000 - Updated for 2.4 by jbarnes@sgi.com
17  *
18  *  25/11/2002 - Updated for 2.5 by Andrey Panin <pazke@orbita1.ru>
19  */
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/smp.h>
24
25 #include <asm/visws/cobalt.h>
26 #include <asm/visws/piix4.h>
27 #include <asm/arch_hooks.h>
28 #include <asm/fixmap.h>
29 #include <asm/reboot.h>
30 #include <asm/setup.h>
31 #include <asm/e820.h>
32 #include <asm/io.h>
33
34 #include <mach_ipi.h>
35
36 #include "mach_apic.h"
37
38 #include <linux/kernel_stat.h>
39
40 #include <asm/i8259.h>
41 #include <asm/irq_vectors.h>
42 #include <asm/visws/lithium.h>
43
44 #include <linux/sched.h>
45 #include <linux/kernel.h>
46 #include <linux/pci.h>
47 #include <linux/pci_ids.h>
48
49 extern int no_broadcast;
50
51 #include <asm/apic.h>
52
53 char visws_board_type   = -1;
54 char visws_board_rev    = -1;
55
56 int is_visws_box(void)
57 {
58         return visws_board_type >= 0;
59 }
60
61 static int __init visws_time_init(void)
62 {
63         printk(KERN_INFO "Starting Cobalt Timer system clock\n");
64
65         /* Set the countdown value */
66         co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
67
68         /* Start the timer */
69         co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
70
71         /* Enable (unmask) the timer interrupt */
72         co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
73
74         /*
75          * Zero return means the generic timer setup code will set up
76          * the standard vector:
77          */
78         return 0;
79 }
80
81 static int __init visws_pre_intr_init(void)
82 {
83         init_VISWS_APIC_irqs();
84
85         /*
86          * We dont want ISA irqs to be set up by the generic code:
87          */
88         return 1;
89 }
90
91 /* Quirk for machine specific memory setup. */
92
93 #define MB (1024 * 1024)
94
95 unsigned long sgivwfb_mem_phys;
96 unsigned long sgivwfb_mem_size;
97 EXPORT_SYMBOL(sgivwfb_mem_phys);
98 EXPORT_SYMBOL(sgivwfb_mem_size);
99
100 long long mem_size __initdata = 0;
101
102 static char * __init visws_memory_setup(void)
103 {
104         long long gfx_mem_size = 8 * MB;
105
106         mem_size = boot_params.alt_mem_k;
107
108         if (!mem_size) {
109                 printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n");
110                 mem_size = 128 * MB;
111         }
112
113         /*
114          * this hardcodes the graphics memory to 8 MB
115          * it really should be sized dynamically (or at least
116          * set as a boot param)
117          */
118         if (!sgivwfb_mem_size) {
119                 printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n");
120                 sgivwfb_mem_size = 8 * MB;
121         }
122
123         /*
124          * Trim to nearest MB
125          */
126         sgivwfb_mem_size &= ~((1 << 20) - 1);
127         sgivwfb_mem_phys = mem_size - gfx_mem_size;
128
129         e820_add_region(0, LOWMEMSIZE(), E820_RAM);
130         e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM);
131         e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED);
132
133         return "PROM";
134 }
135
136 static void visws_machine_emergency_restart(void)
137 {
138         /*
139          * Visual Workstations restart after this
140          * register is poked on the PIIX4
141          */
142         outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
143 }
144
145 static void visws_machine_power_off(void)
146 {
147         unsigned short pm_status;
148 /*      extern unsigned int pci_bus0; */
149
150         while ((pm_status = inw(PMSTS_PORT)) & 0x100)
151                 outw(pm_status, PMSTS_PORT);
152
153         outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
154
155         mdelay(10);
156
157 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
158         (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
159
160 /*      outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */
161         outl(PIIX_SPECIAL_STOP, 0xCFC);
162 }
163
164 static int __init visws_get_smp_config(unsigned int early)
165 {
166         /*
167          * Prevent MP-table parsing by the generic code:
168          */
169         return 1;
170 }
171
172 extern unsigned int __cpuinitdata maxcpus;
173
174 /*
175  * The Visual Workstation is Intel MP compliant in the hardware
176  * sense, but it doesn't have a BIOS(-configuration table).
177  * No problem for Linux.
178  */
179
180 static void __init MP_processor_info(struct mpc_config_processor *m)
181 {
182         int ver, logical_apicid;
183         physid_mask_t apic_cpus;
184
185         if (!(m->mpc_cpuflag & CPU_ENABLED))
186                 return;
187
188         logical_apicid = m->mpc_apicid;
189         printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n",
190                m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
191                m->mpc_apicid,
192                (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
193                (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
194                m->mpc_apicver);
195
196         if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
197                 boot_cpu_physical_apicid = m->mpc_apicid;
198
199         ver = m->mpc_apicver;
200         if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
201                 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
202                         m->mpc_apicid, MAX_APICS);
203                 return;
204         }
205
206         apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
207         physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
208         /*
209          * Validate version
210          */
211         if (ver == 0x0) {
212                 printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! "
213                         "fixing up to 0x10. (tell your hw vendor)\n",
214                         m->mpc_apicid);
215                 ver = 0x10;
216         }
217         apic_version[m->mpc_apicid] = ver;
218 }
219
220 static int __init visws_find_smp_config(unsigned int reserve)
221 {
222         struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
223         unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
224
225         if (ncpus > CO_CPU_MAX) {
226                 printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n",
227                         ncpus, mp);
228
229                 ncpus = CO_CPU_MAX;
230         }
231
232         if (ncpus > maxcpus)
233                 ncpus = maxcpus;
234
235 #ifdef CONFIG_X86_LOCAL_APIC
236         smp_found_config = 1;
237 #endif
238         while (ncpus--)
239                 MP_processor_info(mp++);
240
241         mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
242
243         return 1;
244 }
245
246 static int visws_trap_init(void);
247
248 static struct x86_quirks visws_x86_quirks __initdata = {
249         .arch_time_init         = visws_time_init,
250         .arch_pre_intr_init     = visws_pre_intr_init,
251         .arch_memory_setup      = visws_memory_setup,
252         .arch_intr_init         = NULL,
253         .arch_trap_init         = visws_trap_init,
254         .mach_get_smp_config    = visws_get_smp_config,
255         .mach_find_smp_config   = visws_find_smp_config,
256 };
257
258 void __init visws_early_detect(void)
259 {
260         int raw;
261
262         visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
263                                                          >> PIIX_GPI_BD_SHIFT;
264
265         if (visws_board_type < 0)
266                 return;
267
268         /*
269          * Install special quirks for timer, interrupt and memory setup:
270          * Fall back to generic behavior for traps:
271          * Override generic MP-table parsing:
272          */
273         x86_quirks = &visws_x86_quirks;
274
275         /*
276          * Install reboot quirks:
277          */
278         pm_power_off                    = visws_machine_power_off;
279         machine_ops.emergency_restart   = visws_machine_emergency_restart;
280
281         /*
282          * Do not use broadcast IPIs:
283          */
284         no_broadcast = 0;
285
286 #ifdef CONFIG_X86_IO_APIC
287         /*
288          * Turn off IO-APIC detection and initialization:
289          */
290         skip_ioapic_setup               = 1;
291 #endif
292
293         /*
294          * Get Board rev.
295          * First, we have to initialize the 307 part to allow us access
296          * to the GPIO registers.  Let's map them at 0x0fc0 which is right
297          * after the PIIX4 PM section.
298          */
299         outb_p(SIO_DEV_SEL, SIO_INDEX);
300         outb_p(SIO_GP_DEV, SIO_DATA);   /* Talk to GPIO regs. */
301
302         outb_p(SIO_DEV_MSB, SIO_INDEX);
303         outb_p(SIO_GP_MSB, SIO_DATA);   /* MSB of GPIO base address */
304
305         outb_p(SIO_DEV_LSB, SIO_INDEX);
306         outb_p(SIO_GP_LSB, SIO_DATA);   /* LSB of GPIO base address */
307
308         outb_p(SIO_DEV_ENB, SIO_INDEX);
309         outb_p(1, SIO_DATA);            /* Enable GPIO registers. */
310
311         /*
312          * Now, we have to map the power management section to write
313          * a bit which enables access to the GPIO registers.
314          * What lunatic came up with this shit?
315          */
316         outb_p(SIO_DEV_SEL, SIO_INDEX);
317         outb_p(SIO_PM_DEV, SIO_DATA);   /* Talk to GPIO regs. */
318
319         outb_p(SIO_DEV_MSB, SIO_INDEX);
320         outb_p(SIO_PM_MSB, SIO_DATA);   /* MSB of PM base address */
321
322         outb_p(SIO_DEV_LSB, SIO_INDEX);
323         outb_p(SIO_PM_LSB, SIO_DATA);   /* LSB of PM base address */
324
325         outb_p(SIO_DEV_ENB, SIO_INDEX);
326         outb_p(1, SIO_DATA);            /* Enable PM registers. */
327
328         /*
329          * Now, write the PM register which enables the GPIO registers.
330          */
331         outb_p(SIO_PM_FER2, SIO_PM_INDEX);
332         outb_p(SIO_PM_GP_EN, SIO_PM_DATA);
333
334         /*
335          * Now, initialize the GPIO registers.
336          * We want them all to be inputs which is the
337          * power on default, so let's leave them alone.
338          * So, let's just read the board rev!
339          */
340         raw = inb_p(SIO_GP_DATA1);
341         raw &= 0x7f;    /* 7 bits of valid board revision ID. */
342
343         if (visws_board_type == VISWS_320) {
344                 if (raw < 0x6) {
345                         visws_board_rev = 4;
346                 } else if (raw < 0xc) {
347                         visws_board_rev = 5;
348                 } else {
349                         visws_board_rev = 6;
350                 }
351         } else if (visws_board_type == VISWS_540) {
352                         visws_board_rev = 2;
353                 } else {
354                         visws_board_rev = raw;
355                 }
356
357         printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n",
358                (visws_board_type == VISWS_320 ? "320" :
359                (visws_board_type == VISWS_540 ? "540" :
360                 "unknown")), visws_board_rev);
361 }
362
363 #define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4)
364 #define BCD (LI_INTB | LI_INTC | LI_INTD)
365 #define ALLDEVS (A01234 | BCD)
366
367 static __init void lithium_init(void)
368 {
369         set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
370         set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
371
372         if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
373             (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
374                 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A');
375 /*              panic("This machine is not SGI Visual Workstation 320/540"); */
376         }
377
378         if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
379             (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
380                 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B');
381 /*              panic("This machine is not SGI Visual Workstation 320/540"); */
382         }
383
384         li_pcia_write16(LI_PCI_INTEN, ALLDEVS);
385         li_pcib_write16(LI_PCI_INTEN, ALLDEVS);
386 }
387
388 static __init void cobalt_init(void)
389 {
390         /*
391          * On normal SMP PC this is used only with SMP, but we have to
392          * use it and set it up here to start the Cobalt clock
393          */
394         set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
395         setup_local_APIC();
396         printk(KERN_INFO "Local APIC Version %#x, ID %#x\n",
397                 (unsigned int)apic_read(APIC_LVR),
398                 (unsigned int)apic_read(APIC_ID));
399
400         set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
401         set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
402         printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n",
403                 co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID));
404
405         /* Enable Cobalt APIC being careful to NOT change the ID! */
406         co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE);
407
408         printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n",
409                 co_apic_read(CO_APIC_ID));
410 }
411
412 static int __init visws_trap_init(void)
413 {
414         lithium_init();
415         cobalt_init();
416
417         return 1;
418 }
419
420 /*
421  * IRQ controller / APIC support:
422  */
423
424 static DEFINE_SPINLOCK(cobalt_lock);
425
426 /*
427  * Set the given Cobalt APIC Redirection Table entry to point
428  * to the given IDT vector/index.
429  */
430 static inline void co_apic_set(int entry, int irq)
431 {
432         co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR));
433         co_apic_write(CO_APIC_HI(entry), 0);
434 }
435
436 /*
437  * Cobalt (IO)-APIC functions to handle PCI devices.
438  */
439 static inline int co_apic_ide0_hack(void)
440 {
441         extern char visws_board_type;
442         extern char visws_board_rev;
443
444         if (visws_board_type == VISWS_320 && visws_board_rev == 5)
445                 return 5;
446         return CO_APIC_IDE0;
447 }
448
449 static int is_co_apic(unsigned int irq)
450 {
451         if (IS_CO_APIC(irq))
452                 return CO_APIC(irq);
453
454         switch (irq) {
455                 case 0: return CO_APIC_CPU;
456                 case CO_IRQ_IDE0: return co_apic_ide0_hack();
457                 case CO_IRQ_IDE1: return CO_APIC_IDE1;
458                 default: return -1;
459         }
460 }
461
462
463 /*
464  * This is the SGI Cobalt (IO-)APIC:
465  */
466
467 static void enable_cobalt_irq(unsigned int irq)
468 {
469         co_apic_set(is_co_apic(irq), irq);
470 }
471
472 static void disable_cobalt_irq(unsigned int irq)
473 {
474         int entry = is_co_apic(irq);
475
476         co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
477         co_apic_read(CO_APIC_LO(entry));
478 }
479
480 /*
481  * "irq" really just serves to identify the device.  Here is where we
482  * map this to the Cobalt APIC entry where it's physically wired.
483  * This is called via request_irq -> setup_irq -> irq_desc->startup()
484  */
485 static unsigned int startup_cobalt_irq(unsigned int irq)
486 {
487         unsigned long flags;
488
489         spin_lock_irqsave(&cobalt_lock, flags);
490         if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
491                 irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
492         enable_cobalt_irq(irq);
493         spin_unlock_irqrestore(&cobalt_lock, flags);
494         return 0;
495 }
496
497 static void ack_cobalt_irq(unsigned int irq)
498 {
499         unsigned long flags;
500
501         spin_lock_irqsave(&cobalt_lock, flags);
502         disable_cobalt_irq(irq);
503         apic_write(APIC_EOI, APIC_EIO_ACK);
504         spin_unlock_irqrestore(&cobalt_lock, flags);
505 }
506
507 static void end_cobalt_irq(unsigned int irq)
508 {
509         unsigned long flags;
510
511         spin_lock_irqsave(&cobalt_lock, flags);
512         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
513                 enable_cobalt_irq(irq);
514         spin_unlock_irqrestore(&cobalt_lock, flags);
515 }
516
517 static struct irq_chip cobalt_irq_type = {
518         .typename =     "Cobalt-APIC",
519         .startup =      startup_cobalt_irq,
520         .shutdown =     disable_cobalt_irq,
521         .enable =       enable_cobalt_irq,
522         .disable =      disable_cobalt_irq,
523         .ack =          ack_cobalt_irq,
524         .end =          end_cobalt_irq,
525 };
526
527
528 /*
529  * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
530  * -- not the manner expected by the code in i8259.c.
531  *
532  * there is a 'master' physical interrupt source that gets sent to
533  * the CPU. But in the chipset there are various 'virtual' interrupts
534  * waiting to be handled. We represent this to Linux through a 'master'
535  * interrupt controller type, and through a special virtual interrupt-
536  * controller. Device drivers only see the virtual interrupt sources.
537  */
538 static unsigned int startup_piix4_master_irq(unsigned int irq)
539 {
540         init_8259A(0);
541
542         return startup_cobalt_irq(irq);
543 }
544
545 static void end_piix4_master_irq(unsigned int irq)
546 {
547         unsigned long flags;
548
549         spin_lock_irqsave(&cobalt_lock, flags);
550         enable_cobalt_irq(irq);
551         spin_unlock_irqrestore(&cobalt_lock, flags);
552 }
553
554 static struct irq_chip piix4_master_irq_type = {
555         .typename =     "PIIX4-master",
556         .startup =      startup_piix4_master_irq,
557         .ack =          ack_cobalt_irq,
558         .end =          end_piix4_master_irq,
559 };
560
561
562 static struct irq_chip piix4_virtual_irq_type = {
563         .typename =     "PIIX4-virtual",
564         .shutdown =     disable_8259A_irq,
565         .enable =       enable_8259A_irq,
566         .disable =      disable_8259A_irq,
567 };
568
569
570 /*
571  * PIIX4-8259 master/virtual functions to handle interrupt requests
572  * from legacy devices: floppy, parallel, serial, rtc.
573  *
574  * None of these get Cobalt APIC entries, neither do they have IDT
575  * entries. These interrupts are purely virtual and distributed from
576  * the 'master' interrupt source: CO_IRQ_8259.
577  *
578  * When the 8259 interrupts its handler figures out which of these
579  * devices is interrupting and dispatches to its handler.
580  *
581  * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/
582  * enable_irq gets the right irq. This 'master' irq is never directly
583  * manipulated by any driver.
584  */
585 static irqreturn_t piix4_master_intr(int irq, void *dev_id)
586 {
587         int realirq;
588         irq_desc_t *desc;
589         unsigned long flags;
590
591         spin_lock_irqsave(&i8259A_lock, flags);
592
593         /* Find out what's interrupting in the PIIX4 master 8259 */
594         outb(0x0c, 0x20);               /* OCW3 Poll command */
595         realirq = inb(0x20);
596
597         /*
598          * Bit 7 == 0 means invalid/spurious
599          */
600         if (unlikely(!(realirq & 0x80)))
601                 goto out_unlock;
602
603         realirq &= 7;
604
605         if (unlikely(realirq == 2)) {
606                 outb(0x0c, 0xa0);
607                 realirq = inb(0xa0);
608
609                 if (unlikely(!(realirq & 0x80)))
610                         goto out_unlock;
611
612                 realirq = (realirq & 7) + 8;
613         }
614
615         /* mask and ack interrupt */
616         cached_irq_mask |= 1 << realirq;
617         if (unlikely(realirq > 7)) {
618                 inb(0xa1);
619                 outb(cached_slave_mask, 0xa1);
620                 outb(0x60 + (realirq & 7), 0xa0);
621                 outb(0x60 + 2, 0x20);
622         } else {
623                 inb(0x21);
624                 outb(cached_master_mask, 0x21);
625                 outb(0x60 + realirq, 0x20);
626         }
627
628         spin_unlock_irqrestore(&i8259A_lock, flags);
629
630         desc = irq_desc + realirq;
631
632         /*
633          * handle this 'virtual interrupt' as a Cobalt one now.
634          */
635         kstat_cpu(smp_processor_id()).irqs[realirq]++;
636
637         if (likely(desc->action != NULL))
638                 handle_IRQ_event(realirq, desc->action);
639
640         if (!(desc->status & IRQ_DISABLED))
641                 enable_8259A_irq(realirq);
642
643         return IRQ_HANDLED;
644
645 out_unlock:
646         spin_unlock_irqrestore(&i8259A_lock, flags);
647         return IRQ_NONE;
648 }
649
650 static struct irqaction master_action = {
651         .handler =      piix4_master_intr,
652         .name =         "PIIX4-8259",
653 };
654
655 static struct irqaction cascade_action = {
656         .handler =      no_action,
657         .name =         "cascade",
658 };
659
660
661 void init_VISWS_APIC_irqs(void)
662 {
663         int i;
664
665         for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
666                 irq_desc[i].status = IRQ_DISABLED;
667                 irq_desc[i].action = 0;
668                 irq_desc[i].depth = 1;
669
670                 if (i == 0) {
671                         irq_desc[i].chip = &cobalt_irq_type;
672                 }
673                 else if (i == CO_IRQ_IDE0) {
674                         irq_desc[i].chip = &cobalt_irq_type;
675                 }
676                 else if (i == CO_IRQ_IDE1) {
677                         irq_desc[i].chip = &cobalt_irq_type;
678                 }
679                 else if (i == CO_IRQ_8259) {
680                         irq_desc[i].chip = &piix4_master_irq_type;
681                 }
682                 else if (i < CO_IRQ_APIC0) {
683                         irq_desc[i].chip = &piix4_virtual_irq_type;
684                 }
685                 else if (IS_CO_APIC(i)) {
686                         irq_desc[i].chip = &cobalt_irq_type;
687                 }
688         }
689
690         setup_irq(CO_IRQ_8259, &master_action);
691         setup_irq(2, &cascade_action);
692 }