aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/mach-visws
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/i386/mach-visws
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/i386/mach-visws')
-rw-r--r--arch/i386/mach-visws/Makefile8
-rw-r--r--arch/i386/mach-visws/mpparse.c105
-rw-r--r--arch/i386/mach-visws/reboot.c51
-rw-r--r--arch/i386/mach-visws/setup.c134
-rw-r--r--arch/i386/mach-visws/traps.c69
-rw-r--r--arch/i386/mach-visws/visws_apic.c303
6 files changed, 670 insertions, 0 deletions
diff --git a/arch/i386/mach-visws/Makefile b/arch/i386/mach-visws/Makefile
new file mode 100644
index 000000000000..835fd96ad768
--- /dev/null
+++ b/arch/i386/mach-visws/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := setup.o traps.o reboot.o
6
7obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
8obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o
diff --git a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c
new file mode 100644
index 000000000000..5a22082147f4
--- /dev/null
+++ b/arch/i386/mach-visws/mpparse.c
@@ -0,0 +1,105 @@
1
2#include <linux/config.h>
3#include <linux/init.h>
4#include <linux/smp.h>
5
6#include <asm/smp.h>
7#include <asm/io.h>
8
9#include "cobalt.h"
10#include "mach_apic.h"
11
12/* Have we found an MP table */
13int smp_found_config;
14
15/*
16 * Various Linux-internal data structures created from the
17 * MP-table.
18 */
19int apic_version [MAX_APICS];
20
21int pic_mode;
22unsigned long mp_lapic_addr;
23
24/* Processor that is doing the boot up */
25unsigned int boot_cpu_physical_apicid = -1U;
26unsigned int boot_cpu_logical_apicid = -1U;
27
28/* Bitmask of physically existing CPUs */
29physid_mask_t phys_cpu_present_map;
30
31unsigned int __initdata maxcpus = NR_CPUS;
32
33/*
34 * The Visual Workstation is Intel MP compliant in the hardware
35 * sense, but it doesn't have a BIOS(-configuration table).
36 * No problem for Linux.
37 */
38
39static void __init MP_processor_info (struct mpc_config_processor *m)
40{
41 int ver, logical_apicid;
42 physid_mask_t apic_cpus;
43
44 if (!(m->mpc_cpuflag & CPU_ENABLED))
45 return;
46
47 logical_apicid = m->mpc_apicid;
48 printk(KERN_INFO "%sCPU #%d %ld:%ld APIC version %d\n",
49 m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
50 m->mpc_apicid,
51 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
52 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
53 m->mpc_apicver);
54
55 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
56 boot_cpu_physical_apicid = m->mpc_apicid;
57 boot_cpu_logical_apicid = logical_apicid;
58 }
59
60 ver = m->mpc_apicver;
61 if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
62 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
63 m->mpc_apicid, MAX_APICS);
64 return;
65 }
66
67 apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
68 physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
69 /*
70 * Validate version
71 */
72 if (ver == 0x0) {
73 printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! "
74 "fixing up to 0x10. (tell your hw vendor)\n",
75 m->mpc_apicid);
76 ver = 0x10;
77 }
78 apic_version[m->mpc_apicid] = ver;
79}
80
81void __init find_smp_config(void)
82{
83 struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
84 unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
85
86 if (ncpus > CO_CPU_MAX) {
87 printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n",
88 ncpus, mp);
89
90 ncpus = CO_CPU_MAX;
91 }
92
93 if (ncpus > maxcpus)
94 ncpus = maxcpus;
95
96 smp_found_config = 1;
97 while (ncpus--)
98 MP_processor_info(mp++);
99
100 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
101}
102
103void __init get_smp_config (void)
104{
105}
diff --git a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c
new file mode 100644
index 000000000000..3a81e904a7b8
--- /dev/null
+++ b/arch/i386/mach-visws/reboot.c
@@ -0,0 +1,51 @@
1#include <linux/module.h>
2#include <linux/smp.h>
3#include <linux/delay.h>
4#include <linux/platform.h>
5
6#include <asm/io.h>
7#include "piix4.h"
8
9void (*pm_power_off)(void);
10
11void machine_restart(char * __unused)
12{
13#ifdef CONFIG_SMP
14 smp_send_stop();
15#endif
16
17 /*
18 * Visual Workstations restart after this
19 * register is poked on the PIIX4
20 */
21 outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
22}
23
24EXPORT_SYMBOL(machine_restart);
25
26void machine_power_off(void)
27{
28 unsigned short pm_status;
29 extern unsigned int pci_bus0;
30
31 while ((pm_status = inw(PMSTS_PORT)) & 0x100)
32 outw(pm_status, PMSTS_PORT);
33
34 outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
35
36 mdelay(10);
37
38#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
39 (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
40
41 outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8);
42 outl(PIIX_SPECIAL_STOP, 0xCFC);
43}
44
45EXPORT_SYMBOL(machine_power_off);
46
47void machine_halt(void)
48{
49}
50
51EXPORT_SYMBOL(machine_halt);
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c
new file mode 100644
index 000000000000..9f6d2d9b1be7
--- /dev/null
+++ b/arch/i386/mach-visws/setup.c
@@ -0,0 +1,134 @@
1/*
2 * Unmaintained SGI Visual Workstation support.
3 * Split out from setup.c by davej@suse.de
4 */
5
6#include <linux/smp.h>
7#include <linux/init.h>
8#include <linux/irq.h>
9#include <linux/interrupt.h>
10
11#include <asm/fixmap.h>
12#include <asm/arch_hooks.h>
13#include <asm/io.h>
14#include "cobalt.h"
15#include "piix4.h"
16
17char visws_board_type = -1;
18char visws_board_rev = -1;
19
20void __init visws_get_board_type_and_rev(void)
21{
22 int raw;
23
24 visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
25 >> PIIX_GPI_BD_SHIFT;
26 /*
27 * Get Board rev.
28 * First, we have to initialize the 307 part to allow us access
29 * to the GPIO registers. Let's map them at 0x0fc0 which is right
30 * after the PIIX4 PM section.
31 */
32 outb_p(SIO_DEV_SEL, SIO_INDEX);
33 outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */
34
35 outb_p(SIO_DEV_MSB, SIO_INDEX);
36 outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */
37
38 outb_p(SIO_DEV_LSB, SIO_INDEX);
39 outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */
40
41 outb_p(SIO_DEV_ENB, SIO_INDEX);
42 outb_p(1, SIO_DATA); /* Enable GPIO registers. */
43
44 /*
45 * Now, we have to map the power management section to write
46 * a bit which enables access to the GPIO registers.
47 * What lunatic came up with this shit?
48 */
49 outb_p(SIO_DEV_SEL, SIO_INDEX);
50 outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */
51
52 outb_p(SIO_DEV_MSB, SIO_INDEX);
53 outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */
54
55 outb_p(SIO_DEV_LSB, SIO_INDEX);
56 outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */
57
58 outb_p(SIO_DEV_ENB, SIO_INDEX);
59 outb_p(1, SIO_DATA); /* Enable PM registers. */
60
61 /*
62 * Now, write the PM register which enables the GPIO registers.
63 */
64 outb_p(SIO_PM_FER2, SIO_PM_INDEX);
65 outb_p(SIO_PM_GP_EN, SIO_PM_DATA);
66
67 /*
68 * Now, initialize the GPIO registers.
69 * We want them all to be inputs which is the
70 * power on default, so let's leave them alone.
71 * So, let's just read the board rev!
72 */
73 raw = inb_p(SIO_GP_DATA1);
74 raw &= 0x7f; /* 7 bits of valid board revision ID. */
75
76 if (visws_board_type == VISWS_320) {
77 if (raw < 0x6) {
78 visws_board_rev = 4;
79 } else if (raw < 0xc) {
80 visws_board_rev = 5;
81 } else {
82 visws_board_rev = 6;
83 }
84 } else if (visws_board_type == VISWS_540) {
85 visws_board_rev = 2;
86 } else {
87 visws_board_rev = raw;
88 }
89
90 printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n",
91 (visws_board_type == VISWS_320 ? "320" :
92 (visws_board_type == VISWS_540 ? "540" :
93 "unknown")), visws_board_rev);
94}
95
96void __init pre_intr_init_hook(void)
97{
98 init_VISWS_APIC_irqs();
99}
100
101void __init intr_init_hook(void)
102{
103#ifdef CONFIG_X86_LOCAL_APIC
104 apic_intr_init();
105#endif
106}
107
108void __init pre_setup_arch_hook()
109{
110 visws_get_board_type_and_rev();
111}
112
113static struct irqaction irq0 = {
114 .handler = timer_interrupt,
115 .flags = SA_INTERRUPT,
116 .name = "timer",
117};
118
119void __init time_init_hook(void)
120{
121 printk(KERN_INFO "Starting Cobalt Timer system clock\n");
122
123 /* Set the countdown value */
124 co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
125
126 /* Start the timer */
127 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
128
129 /* Enable (unmask) the timer interrupt */
130 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
131
132 /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
133 setup_irq(0, &irq0);
134}
diff --git a/arch/i386/mach-visws/traps.c b/arch/i386/mach-visws/traps.c
new file mode 100644
index 000000000000..964353992031
--- /dev/null
+++ b/arch/i386/mach-visws/traps.c
@@ -0,0 +1,69 @@
1/* VISWS traps */
2
3#include <linux/config.h>
4#include <linux/sched.h>
5#include <linux/kernel.h>
6#include <linux/init.h>
7#include <linux/pci.h>
8#include <linux/pci_ids.h>
9
10#include <asm/io.h>
11#include <asm/arch_hooks.h>
12#include <asm/apic.h>
13#include "cobalt.h"
14#include "lithium.h"
15
16
17#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4)
18#define BCD (LI_INTB | LI_INTC | LI_INTD)
19#define ALLDEVS (A01234 | BCD)
20
21static __init void lithium_init(void)
22{
23 set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
24 set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
25
26 if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
27 (li_pcia_read16(PCI_DEVICE_ID) != PCI_VENDOR_ID_SGI_LITHIUM)) {
28 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A');
29 panic("This machine is not SGI Visual Workstation 320/540");
30 }
31
32 if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
33 (li_pcib_read16(PCI_DEVICE_ID) != PCI_VENDOR_ID_SGI_LITHIUM)) {
34 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B');
35 panic("This machine is not SGI Visual Workstation 320/540");
36 }
37
38 li_pcia_write16(LI_PCI_INTEN, ALLDEVS);
39 li_pcib_write16(LI_PCI_INTEN, ALLDEVS);
40}
41
42static __init void cobalt_init(void)
43{
44 /*
45 * On normal SMP PC this is used only with SMP, but we have to
46 * use it and set it up here to start the Cobalt clock
47 */
48 set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
49 setup_local_APIC();
50 printk(KERN_INFO "Local APIC Version %#lx, ID %#lx\n",
51 apic_read(APIC_LVR), apic_read(APIC_ID));
52
53 set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
54 set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
55 printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n",
56 co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID));
57
58 /* Enable Cobalt APIC being careful to NOT change the ID! */
59 co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE);
60
61 printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n",
62 co_apic_read(CO_APIC_ID));
63}
64
65void __init trap_init_hook(void)
66{
67 lithium_init();
68 cobalt_init();
69}
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
new file mode 100644
index 000000000000..04e6585849a2
--- /dev/null
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -0,0 +1,303 @@
1/*
2 * linux/arch/i386/mach_visws/visws_apic.c
3 *
4 * Copyright (C) 1999 Bent Hagemark, Ingo Molnar
5 *
6 * SGI Visual Workstation interrupt controller
7 *
8 * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC
9 * which serves as the main interrupt controller in the system. Non-legacy
10 * hardware in the system uses this controller directly. Legacy devices
11 * are connected to the PIIX4 which in turn has its 8259(s) connected to
12 * a of the Cobalt APIC entry.
13 *
14 * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com
15 *
16 * 25/11/2002 - Updated for 2.5 by Andrey Panin <pazke@orbita1.ru>
17 */
18
19#include <linux/config.h>
20#include <linux/kernel_stat.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/smp_lock.h>
24#include <linux/init.h>
25
26#include <asm/io.h>
27#include <asm/apic.h>
28#include <asm/i8259.h>
29
30#include "cobalt.h"
31#include "irq_vectors.h"
32
33
34static DEFINE_SPINLOCK(cobalt_lock);
35
36/*
37 * Set the given Cobalt APIC Redirection Table entry to point
38 * to the given IDT vector/index.
39 */
40static inline void co_apic_set(int entry, int irq)
41{
42 co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR));
43 co_apic_write(CO_APIC_HI(entry), 0);
44}
45
46/*
47 * Cobalt (IO)-APIC functions to handle PCI devices.
48 */
49static inline int co_apic_ide0_hack(void)
50{
51 extern char visws_board_type;
52 extern char visws_board_rev;
53
54 if (visws_board_type == VISWS_320 && visws_board_rev == 5)
55 return 5;
56 return CO_APIC_IDE0;
57}
58
59static int is_co_apic(unsigned int irq)
60{
61 if (IS_CO_APIC(irq))
62 return CO_APIC(irq);
63
64 switch (irq) {
65 case 0: return CO_APIC_CPU;
66 case CO_IRQ_IDE0: return co_apic_ide0_hack();
67 case CO_IRQ_IDE1: return CO_APIC_IDE1;
68 default: return -1;
69 }
70}
71
72
73/*
74 * This is the SGI Cobalt (IO-)APIC:
75 */
76
77static void enable_cobalt_irq(unsigned int irq)
78{
79 co_apic_set(is_co_apic(irq), irq);
80}
81
82static void disable_cobalt_irq(unsigned int irq)
83{
84 int entry = is_co_apic(irq);
85
86 co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
87 co_apic_read(CO_APIC_LO(entry));
88}
89
90/*
91 * "irq" really just serves to identify the device. Here is where we
92 * map this to the Cobalt APIC entry where it's physically wired.
93 * This is called via request_irq -> setup_irq -> irq_desc->startup()
94 */
95static unsigned int startup_cobalt_irq(unsigned int irq)
96{
97 unsigned long flags;
98
99 spin_lock_irqsave(&cobalt_lock, flags);
100 if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
101 irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
102 enable_cobalt_irq(irq);
103 spin_unlock_irqrestore(&cobalt_lock, flags);
104 return 0;
105}
106
107static void ack_cobalt_irq(unsigned int irq)
108{
109 unsigned long flags;
110
111 spin_lock_irqsave(&cobalt_lock, flags);
112 disable_cobalt_irq(irq);
113 apic_write(APIC_EOI, APIC_EIO_ACK);
114 spin_unlock_irqrestore(&cobalt_lock, flags);
115}
116
117static void end_cobalt_irq(unsigned int irq)
118{
119 unsigned long flags;
120
121 spin_lock_irqsave(&cobalt_lock, flags);
122 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
123 enable_cobalt_irq(irq);
124 spin_unlock_irqrestore(&cobalt_lock, flags);
125}
126
127static struct hw_interrupt_type cobalt_irq_type = {
128 .typename = "Cobalt-APIC",
129 .startup = startup_cobalt_irq,
130 .shutdown = disable_cobalt_irq,
131 .enable = enable_cobalt_irq,
132 .disable = disable_cobalt_irq,
133 .ack = ack_cobalt_irq,
134 .end = end_cobalt_irq,
135};
136
137
138/*
139 * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
140 * -- not the manner expected by the code in i8259.c.
141 *
142 * there is a 'master' physical interrupt source that gets sent to
143 * the CPU. But in the chipset there are various 'virtual' interrupts
144 * waiting to be handled. We represent this to Linux through a 'master'
145 * interrupt controller type, and through a special virtual interrupt-
146 * controller. Device drivers only see the virtual interrupt sources.
147 */
148static unsigned int startup_piix4_master_irq(unsigned int irq)
149{
150 init_8259A(0);
151
152 return startup_cobalt_irq(irq);
153}
154
155static void end_piix4_master_irq(unsigned int irq)
156{
157 unsigned long flags;
158
159 spin_lock_irqsave(&cobalt_lock, flags);
160 enable_cobalt_irq(irq);
161 spin_unlock_irqrestore(&cobalt_lock, flags);
162}
163
164static struct hw_interrupt_type piix4_master_irq_type = {
165 .typename = "PIIX4-master",
166 .startup = startup_piix4_master_irq,
167 .ack = ack_cobalt_irq,
168 .end = end_piix4_master_irq,
169};
170
171
172static struct hw_interrupt_type piix4_virtual_irq_type = {
173 .typename = "PIIX4-virtual",
174 .startup = startup_8259A_irq,
175 .shutdown = disable_8259A_irq,
176 .enable = enable_8259A_irq,
177 .disable = disable_8259A_irq,
178};
179
180
181/*
182 * PIIX4-8259 master/virtual functions to handle interrupt requests
183 * from legacy devices: floppy, parallel, serial, rtc.
184 *
185 * None of these get Cobalt APIC entries, neither do they have IDT
186 * entries. These interrupts are purely virtual and distributed from
187 * the 'master' interrupt source: CO_IRQ_8259.
188 *
189 * When the 8259 interrupts its handler figures out which of these
190 * devices is interrupting and dispatches to its handler.
191 *
192 * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/
193 * enable_irq gets the right irq. This 'master' irq is never directly
194 * manipulated by any driver.
195 */
196static irqreturn_t piix4_master_intr(int irq, void *dev_id, struct pt_regs * regs)
197{
198 int realirq;
199 irq_desc_t *desc;
200 unsigned long flags;
201
202 spin_lock_irqsave(&i8259A_lock, flags);
203
204 /* Find out what's interrupting in the PIIX4 master 8259 */
205 outb(0x0c, 0x20); /* OCW3 Poll command */
206 realirq = inb(0x20);
207
208 /*
209 * Bit 7 == 0 means invalid/spurious
210 */
211 if (unlikely(!(realirq & 0x80)))
212 goto out_unlock;
213
214 realirq &= 7;
215
216 if (unlikely(realirq == 2)) {
217 outb(0x0c, 0xa0);
218 realirq = inb(0xa0);
219
220 if (unlikely(!(realirq & 0x80)))
221 goto out_unlock;
222
223 realirq = (realirq & 7) + 8;
224 }
225
226 /* mask and ack interrupt */
227 cached_irq_mask |= 1 << realirq;
228 if (unlikely(realirq > 7)) {
229 inb(0xa1);
230 outb(cached_slave_mask, 0xa1);
231 outb(0x60 + (realirq & 7), 0xa0);
232 outb(0x60 + 2, 0x20);
233 } else {
234 inb(0x21);
235 outb(cached_master_mask, 0x21);
236 outb(0x60 + realirq, 0x20);
237 }
238
239 spin_unlock_irqrestore(&i8259A_lock, flags);
240
241 desc = irq_desc + realirq;
242
243 /*
244 * handle this 'virtual interrupt' as a Cobalt one now.
245 */
246 kstat_cpu(smp_processor_id()).irqs[realirq]++;
247
248 if (likely(desc->action != NULL))
249 handle_IRQ_event(realirq, regs, desc->action);
250
251 if (!(desc->status & IRQ_DISABLED))
252 enable_8259A_irq(realirq);
253
254 return IRQ_HANDLED;
255
256out_unlock:
257 spin_unlock_irqrestore(&i8259A_lock, flags);
258 return IRQ_NONE;
259}
260
261static struct irqaction master_action = {
262 .handler = piix4_master_intr,
263 .name = "PIIX4-8259",
264};
265
266static struct irqaction cascade_action = {
267 .handler = no_action,
268 .name = "cascade",
269};
270
271
272void init_VISWS_APIC_irqs(void)
273{
274 int i;
275
276 for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
277 irq_desc[i].status = IRQ_DISABLED;
278 irq_desc[i].action = 0;
279 irq_desc[i].depth = 1;
280
281 if (i == 0) {
282 irq_desc[i].handler = &cobalt_irq_type;
283 }
284 else if (i == CO_IRQ_IDE0) {
285 irq_desc[i].handler = &cobalt_irq_type;
286 }
287 else if (i == CO_IRQ_IDE1) {
288 irq_desc[i].handler = &cobalt_irq_type;
289 }
290 else if (i == CO_IRQ_8259) {
291 irq_desc[i].handler = &piix4_master_irq_type;
292 }
293 else if (i < CO_IRQ_APIC0) {
294 irq_desc[i].handler = &piix4_virtual_irq_type;
295 }
296 else if (IS_CO_APIC(i)) {
297 irq_desc[i].handler = &cobalt_irq_type;
298 }
299 }
300
301 setup_irq(CO_IRQ_8259, &master_action);
302 setup_irq(2, &cascade_action);
303}