aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-10 07:31:04 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-10 12:55:32 -0400
commit31ac409a7921da39cc998f2432afa13e77fd8705 (patch)
tree1065fc1b963c95e75683ea6c661e2e6ee3958e51 /arch
parent22d5c67c5b0476e463ce4b632ba9ec3953d33a5f (diff)
x86, VisWS: turn into generic arch, add early init quirks
add early init quirks for VisWS. This gradually turns the VISWS subarch into a generic PC architecture. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/mach-visws/Makefile2
-rw-r--r--arch/x86/mach-visws/reboot.c55
-rw-r--r--arch/x86/mach-visws/setup.c30
-rw-r--r--arch/x86/mach-visws/setup_visws.c233
-rw-r--r--arch/x86/mach-visws/traps.c4
-rw-r--r--arch/x86/mach-visws/visws_apic.c3
-rw-r--r--arch/x86/pci/Makefile2
-rw-r--r--arch/x86/pci/visws.c4
9 files changed, 273 insertions, 62 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3b1b1da78dae..5198a0857944 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -186,7 +186,7 @@ config X86_HT
186 186
187config X86_BIOS_REBOOT 187config X86_BIOS_REBOOT
188 bool 188 bool
189 depends on !X86_VISWS && !X86_VOYAGER 189 depends on !X86_VOYAGER
190 default y 190 default y
191 191
192config X86_TRAMPOLINE 192config X86_TRAMPOLINE
diff --git a/arch/x86/mach-visws/Makefile b/arch/x86/mach-visws/Makefile
index 835fd96ad768..35a4c101b267 100644
--- a/arch/x86/mach-visws/Makefile
+++ b/arch/x86/mach-visws/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := setup.o traps.o reboot.o 5obj-y := setup.o setup_visws.o traps.o
6 6
7obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o 7obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
8obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o 8obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o
diff --git a/arch/x86/mach-visws/reboot.c b/arch/x86/mach-visws/reboot.c
deleted file mode 100644
index 79c26eab8824..000000000000
--- a/arch/x86/mach-visws/reboot.c
+++ /dev/null
@@ -1,55 +0,0 @@
1#include <linux/module.h>
2#include <linux/smp.h>
3#include <linux/delay.h>
4
5#include <asm/io.h>
6#include "piix4.h"
7
8void (*pm_power_off)(void);
9EXPORT_SYMBOL(pm_power_off);
10
11void machine_shutdown(void)
12{
13#ifdef CONFIG_SMP
14 smp_send_stop();
15#endif
16}
17
18void machine_emergency_restart(void)
19{
20 /*
21 * Visual Workstations restart after this
22 * register is poked on the PIIX4
23 */
24 outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
25}
26
27void machine_restart(char * __unused)
28{
29 machine_shutdown();
30 machine_emergency_restart();
31}
32
33void machine_power_off(void)
34{
35 unsigned short pm_status;
36/* extern unsigned int pci_bus0; */
37
38 while ((pm_status = inw(PMSTS_PORT)) & 0x100)
39 outw(pm_status, PMSTS_PORT);
40
41 outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
42
43 mdelay(10);
44
45#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
46 (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
47
48/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */
49 outl(PIIX_SPECIAL_STOP, 0xCFC);
50}
51
52void machine_halt(void)
53{
54}
55
diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c
index 2f5e277686b8..b8054c3ffce3 100644
--- a/arch/x86/mach-visws/setup.c
+++ b/arch/x86/mach-visws/setup.c
@@ -10,6 +10,14 @@
10#include <asm/e820.h> 10#include <asm/e820.h>
11#include <asm/setup.h> 11#include <asm/setup.h>
12 12
13/*
14 * Any quirks to be performed to initialize timers/irqs/etc?
15 */
16int (*arch_time_init_quirk)(void);
17int (*arch_pre_intr_init_quirk)(void);
18int (*arch_intr_init_quirk)(void);
19int (*arch_trap_init_quirk)(void);
20
13#ifdef CONFIG_HOTPLUG_CPU 21#ifdef CONFIG_HOTPLUG_CPU
14#define DEFAULT_SEND_IPI (1) 22#define DEFAULT_SEND_IPI (1)
15#else 23#else
@@ -29,6 +37,10 @@ int no_broadcast=DEFAULT_SEND_IPI;
29 **/ 37 **/
30void __init pre_intr_init_hook(void) 38void __init pre_intr_init_hook(void)
31{ 39{
40 if (arch_pre_intr_init_quirk) {
41 if (arch_pre_intr_init_quirk())
42 return;
43 }
32 init_ISA_irqs(); 44 init_ISA_irqs();
33} 45}
34 46
@@ -52,6 +64,10 @@ static struct irqaction irq2 = {
52 **/ 64 **/
53void __init intr_init_hook(void) 65void __init intr_init_hook(void)
54{ 66{
67 if (arch_intr_init_quirk) {
68 if (arch_intr_init_quirk())
69 return;
70 }
55#ifdef CONFIG_X86_LOCAL_APIC 71#ifdef CONFIG_X86_LOCAL_APIC
56 apic_intr_init(); 72 apic_intr_init();
57#endif 73#endif
@@ -81,6 +97,10 @@ void __init pre_setup_arch_hook(void)
81 **/ 97 **/
82void __init trap_init_hook(void) 98void __init trap_init_hook(void)
83{ 99{
100 if (arch_trap_init_quirk) {
101 if (arch_trap_init_quirk())
102 return;
103 }
84} 104}
85 105
86static struct irqaction irq0 = { 106static struct irqaction irq0 = {
@@ -99,6 +119,16 @@ static struct irqaction irq0 = {
99 **/ 119 **/
100void __init time_init_hook(void) 120void __init time_init_hook(void)
101{ 121{
122 if (arch_time_init_quirk) {
123 /*
124 * A nonzero return code does not mean failure, it means
125 * that the architecture quirk does not want any
126 * generic (timer) setup to be performed after this:
127 */
128 if (arch_time_init_quirk())
129 return;
130 }
131
102 irq0.mask = cpumask_of_cpu(0); 132 irq0.mask = cpumask_of_cpu(0);
103 setup_irq(0, &irq0); 133 setup_irq(0, &irq0);
104} 134}
diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c
new file mode 100644
index 000000000000..659777f78269
--- /dev/null
+++ b/arch/x86/mach-visws/setup_visws.c
@@ -0,0 +1,233 @@
1/*
2 * Unmaintained SGI Visual Workstation support.
3 * Split out from setup.c by davej@suse.de
4 */
5
6#include <linux/interrupt.h>
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/smp.h>
10
11#include <asm/arch_hooks.h>
12#include <asm/fixmap.h>
13#include <asm/reboot.h>
14#include <asm/setup.h>
15#include <asm/e820.h>
16#include <asm/io.h>
17
18#include <mach_ipi.h>
19
20#include "cobalt.h"
21#include "piix4.h"
22
23char visws_board_type = -1;
24char visws_board_rev = -1;
25
26static int __init visws_time_init_quirk(void)
27{
28 printk(KERN_INFO "Starting Cobalt Timer system clock\n");
29
30 /* Set the countdown value */
31 co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
32
33 /* Start the timer */
34 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
35
36 /* Enable (unmask) the timer interrupt */
37 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
38
39 /*
40 * Zero return means the generic timer setup code will set up
41 * the standard vector:
42 */
43 return 0;
44}
45
46static int __init visws_pre_intr_init_quirk(void)
47{
48 init_VISWS_APIC_irqs();
49
50 /*
51 * We dont want ISA irqs to be set up by the generic code:
52 */
53 return 1;
54}
55
56/* Quirk for machine specific memory setup. */
57
58#define MB (1024 * 1024)
59
60unsigned long sgivwfb_mem_phys;
61unsigned long sgivwfb_mem_size;
62EXPORT_SYMBOL(sgivwfb_mem_phys);
63EXPORT_SYMBOL(sgivwfb_mem_size);
64
65long long mem_size __initdata = 0;
66
67static char * __init visws_memory_setup_quirk(void)
68{
69 long long gfx_mem_size = 8 * MB;
70
71 mem_size = boot_params.alt_mem_k;
72
73 if (!mem_size) {
74 printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n");
75 mem_size = 128 * MB;
76 }
77
78 /*
79 * this hardcodes the graphics memory to 8 MB
80 * it really should be sized dynamically (or at least
81 * set as a boot param)
82 */
83 if (!sgivwfb_mem_size) {
84 printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n");
85 sgivwfb_mem_size = 8 * MB;
86 }
87
88 /*
89 * Trim to nearest MB
90 */
91 sgivwfb_mem_size &= ~((1 << 20) - 1);
92 sgivwfb_mem_phys = mem_size - gfx_mem_size;
93
94 e820_add_region(0, LOWMEMSIZE(), E820_RAM);
95 e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM);
96 e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED);
97
98 return "PROM";
99}
100
101static void visws_machine_emergency_restart(void)
102{
103 /*
104 * Visual Workstations restart after this
105 * register is poked on the PIIX4
106 */
107 outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
108}
109
110static void visws_machine_power_off(void)
111{
112 unsigned short pm_status;
113/* extern unsigned int pci_bus0; */
114
115 while ((pm_status = inw(PMSTS_PORT)) & 0x100)
116 outw(pm_status, PMSTS_PORT);
117
118 outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
119
120 mdelay(10);
121
122#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
123 (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
124
125/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */
126 outl(PIIX_SPECIAL_STOP, 0xCFC);
127}
128
129extern int visws_trap_init_quirk(void);
130
131void __init visws_early_detect(void)
132{
133 int raw;
134
135 visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
136 >> PIIX_GPI_BD_SHIFT;
137
138 if (visws_board_type < 0)
139 return;
140
141 /*
142 * Install special quirks for timer, interrupt and memory setup:
143 */
144 arch_time_init_quirk = visws_time_init_quirk;
145 arch_pre_intr_init_quirk = visws_pre_intr_init_quirk;
146 arch_memory_setup_quirk = visws_memory_setup_quirk;
147
148 /*
149 * Fall back to generic behavior for traps:
150 */
151 arch_intr_init_quirk = NULL;
152 arch_trap_init_quirk = visws_trap_init_quirk;
153
154 /*
155 * Install reboot quirks:
156 */
157 pm_power_off = visws_machine_power_off;
158 machine_ops.emergency_restart = visws_machine_emergency_restart;
159
160 /*
161 * Do not use broadcast IPIs:
162 */
163 no_broadcast = 0;
164
165 /*
166 * Get Board rev.
167 * First, we have to initialize the 307 part to allow us access
168 * to the GPIO registers. Let's map them at 0x0fc0 which is right
169 * after the PIIX4 PM section.
170 */
171 outb_p(SIO_DEV_SEL, SIO_INDEX);
172 outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */
173
174 outb_p(SIO_DEV_MSB, SIO_INDEX);
175 outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */
176
177 outb_p(SIO_DEV_LSB, SIO_INDEX);
178 outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */
179
180 outb_p(SIO_DEV_ENB, SIO_INDEX);
181 outb_p(1, SIO_DATA); /* Enable GPIO registers. */
182
183 /*
184 * Now, we have to map the power management section to write
185 * a bit which enables access to the GPIO registers.
186 * What lunatic came up with this shit?
187 */
188 outb_p(SIO_DEV_SEL, SIO_INDEX);
189 outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */
190
191 outb_p(SIO_DEV_MSB, SIO_INDEX);
192 outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */
193
194 outb_p(SIO_DEV_LSB, SIO_INDEX);
195 outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */
196
197 outb_p(SIO_DEV_ENB, SIO_INDEX);
198 outb_p(1, SIO_DATA); /* Enable PM registers. */
199
200 /*
201 * Now, write the PM register which enables the GPIO registers.
202 */
203 outb_p(SIO_PM_FER2, SIO_PM_INDEX);
204 outb_p(SIO_PM_GP_EN, SIO_PM_DATA);
205
206 /*
207 * Now, initialize the GPIO registers.
208 * We want them all to be inputs which is the
209 * power on default, so let's leave them alone.
210 * So, let's just read the board rev!
211 */
212 raw = inb_p(SIO_GP_DATA1);
213 raw &= 0x7f; /* 7 bits of valid board revision ID. */
214
215 if (visws_board_type == VISWS_320) {
216 if (raw < 0x6) {
217 visws_board_rev = 4;
218 } else if (raw < 0xc) {
219 visws_board_rev = 5;
220 } else {
221 visws_board_rev = 6;
222 }
223 } else if (visws_board_type == VISWS_540) {
224 visws_board_rev = 2;
225 } else {
226 visws_board_rev = raw;
227 }
228
229 printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n",
230 (visws_board_type == VISWS_320 ? "320" :
231 (visws_board_type == VISWS_540 ? "540" :
232 "unknown")), visws_board_rev);
233}
diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c
index dd1f5fa94210..8a160ec147f7 100644
--- a/arch/x86/mach-visws/traps.c
+++ b/arch/x86/mach-visws/traps.c
@@ -62,8 +62,10 @@ static __init void cobalt_init(void)
62 co_apic_read(CO_APIC_ID)); 62 co_apic_read(CO_APIC_ID));
63} 63}
64 64
65void __init trap_init_hook_dontuse(void) 65int __init visws_trap_init_quirk(void)
66{ 66{
67 lithium_init(); 67 lithium_init();
68 cobalt_init(); 68 cobalt_init();
69
70 return 1;
69} 71}
diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c
index 8b1cd8e01cb4..d8b2cfd85d92 100644
--- a/arch/x86/mach-visws/visws_apic.c
+++ b/arch/x86/mach-visws/visws_apic.c
@@ -25,9 +25,6 @@
25 25
26#include "cobalt.h" 26#include "cobalt.h"
27 27
28char visws_board_type = -1;
29char visws_board_rev = -1;
30
31static DEFINE_SPINLOCK(cobalt_lock); 28static DEFINE_SPINLOCK(cobalt_lock);
32 29
33/* 30/*
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index fa0164d80bbd..c03c2094864f 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -11,7 +11,7 @@ pci-y += legacy.o irq.o
11 11
12# Careful: VISWS overrule the pci-y above. The colons are 12# Careful: VISWS overrule the pci-y above. The colons are
13# therefor correct. This needs a proper fix by distangling the code. 13# therefor correct. This needs a proper fix by distangling the code.
14#pci-$(CONFIG_X86_VISWS) := visws.o irq.o fixup.o 14pci-$(CONFIG_X86_VISWS) += visws.o
15 15
16pci-$(CONFIG_X86_NUMAQ) += numa.o 16pci-$(CONFIG_X86_NUMAQ) += numa.o
17 17
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
index 343ccf668d14..2e022210a632 100644
--- a/arch/x86/pci/visws.c
+++ b/arch/x86/pci/visws.c
@@ -107,7 +107,11 @@ static int __init pci_visws_init(void)
107 107
108static __init int pci_subsys_init(void) 108static __init int pci_subsys_init(void)
109{ 109{
110 return -1;
111
110 pci_visws_init(); 112 pci_visws_init();
111 pcibios_init(); 113 pcibios_init();
114
115 return 0;
112} 116}
113subsys_initcall(pci_subsys_init); 117subsys_initcall(pci_subsys_init);