diff options
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r-- | arch/alpha/kernel/Makefile | 20 | ||||
-rw-r--r-- | arch/alpha/kernel/ns87312.c | 38 | ||||
-rw-r--r-- | arch/alpha/kernel/pc873xx.c | 88 | ||||
-rw-r--r-- | arch/alpha/kernel/pc873xx.h | 35 | ||||
-rw-r--r-- | arch/alpha/kernel/sys_sio.c | 23 |
5 files changed, 155 insertions, 49 deletions
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 7739a62440a7..5a62fb46ef20 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile | |||
@@ -35,7 +35,7 @@ endif | |||
35 | 35 | ||
36 | obj-y += irq_pyxis.o irq_i8259.o irq_srm.o | 36 | obj-y += irq_pyxis.o irq_i8259.o irq_srm.o |
37 | obj-y += err_ev6.o | 37 | obj-y += err_ev6.o |
38 | obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o | 38 | obj-y += es1888.o smc37c669.o smc37c93x.o pc873xx.o gct.o |
39 | obj-y += srmcons.o | 39 | obj-y += srmcons.o |
40 | 40 | ||
41 | else | 41 | else |
@@ -63,11 +63,11 @@ obj-$(CONFIG_ALPHA_WILDFIRE) += core_wildfire.o | |||
63 | # Board support | 63 | # Board support |
64 | obj-$(CONFIG_ALPHA_ALCOR) += sys_alcor.o irq_i8259.o irq_srm.o | 64 | obj-$(CONFIG_ALPHA_ALCOR) += sys_alcor.o irq_i8259.o irq_srm.o |
65 | obj-$(CONFIG_ALPHA_CABRIOLET) += sys_cabriolet.o irq_i8259.o irq_srm.o \ | 65 | obj-$(CONFIG_ALPHA_CABRIOLET) += sys_cabriolet.o irq_i8259.o irq_srm.o \ |
66 | ns87312.o | 66 | pc873xx.o |
67 | obj-$(CONFIG_ALPHA_EB164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ | 67 | obj-$(CONFIG_ALPHA_EB164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ |
68 | ns87312.o | 68 | pc873xx.o |
69 | obj-$(CONFIG_ALPHA_EB66P) += sys_cabriolet.o irq_i8259.o irq_srm.o \ | 69 | obj-$(CONFIG_ALPHA_EB66P) += sys_cabriolet.o irq_i8259.o irq_srm.o \ |
70 | ns87312.o | 70 | pc873xx.o |
71 | obj-$(CONFIG_ALPHA_LX164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ | 71 | obj-$(CONFIG_ALPHA_LX164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ |
72 | smc37c93x.o | 72 | smc37c93x.o |
73 | obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ | 73 | obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ |
@@ -90,14 +90,14 @@ obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o irq_pyxis.o irq_i8259.o | |||
90 | obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o irq_i8259.o | 90 | obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o irq_i8259.o |
91 | obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o | 91 | obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o |
92 | obj-$(CONFIG_ALPHA_LYNX) += sys_sable.o | 92 | obj-$(CONFIG_ALPHA_LYNX) += sys_sable.o |
93 | obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o | 93 | obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o |
94 | obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o | 94 | obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o |
95 | obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o | 95 | obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o |
96 | obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o | 96 | obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o |
97 | obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o | 97 | obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o |
98 | obj-$(CONFIG_ALPHA_SX164) += sys_sx164.o irq_pyxis.o irq_i8259.o \ | 98 | obj-$(CONFIG_ALPHA_SX164) += sys_sx164.o irq_pyxis.o irq_i8259.o \ |
99 | irq_srm.o smc37c669.o | 99 | irq_srm.o smc37c669.o |
100 | obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o ns87312.o | 100 | obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o pc873xx.o |
101 | obj-$(CONFIG_ALPHA_WILDFIRE) += sys_wildfire.o irq_i8259.o | 101 | obj-$(CONFIG_ALPHA_WILDFIRE) += sys_wildfire.o irq_i8259.o |
102 | 102 | ||
103 | # Error support | 103 | # Error support |
diff --git a/arch/alpha/kernel/ns87312.c b/arch/alpha/kernel/ns87312.c deleted file mode 100644 index 342b56d24c20..000000000000 --- a/arch/alpha/kernel/ns87312.c +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/alpha/kernel/ns87312.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <asm/io.h> | ||
7 | #include "proto.h" | ||
8 | |||
9 | |||
10 | /* | ||
11 | * The SRM console *disables* the IDE interface, this code ensures it's | ||
12 | * enabled. | ||
13 | * | ||
14 | * This code bangs on a control register of the 87312 Super I/O chip | ||
15 | * that implements parallel port/serial ports/IDE/FDI. Depending on | ||
16 | * the motherboard, the Super I/O chip can be configured through a | ||
17 | * pair of registers that are located either at I/O ports 0x26e/0x26f | ||
18 | * or 0x398/0x399. Unfortunately, autodetecting which base address is | ||
19 | * in use works only once (right after a reset). The Super I/O chip | ||
20 | * has the additional quirk that configuration register data must be | ||
21 | * written twice (I believe this is a safety feature to prevent | ||
22 | * accidental modification---fun, isn't it?). | ||
23 | */ | ||
24 | |||
25 | void __init | ||
26 | ns87312_enable_ide(long ide_base) | ||
27 | { | ||
28 | int data; | ||
29 | unsigned long flags; | ||
30 | |||
31 | local_irq_save(flags); | ||
32 | outb(0, ide_base); /* set the index register for reg #0 */ | ||
33 | data = inb(ide_base+1); /* read the current contents */ | ||
34 | outb(0, ide_base); /* set the index register for reg #0 */ | ||
35 | outb(data | 0x40, ide_base+1); /* turn on IDE */ | ||
36 | outb(data | 0x40, ide_base+1); /* turn on IDE, really! */ | ||
37 | local_irq_restore(flags); | ||
38 | } | ||
diff --git a/arch/alpha/kernel/pc873xx.c b/arch/alpha/kernel/pc873xx.c new file mode 100644 index 000000000000..27dcbff85613 --- /dev/null +++ b/arch/alpha/kernel/pc873xx.c | |||
@@ -0,0 +1,88 @@ | |||
1 | #include <linux/ioport.h> | ||
2 | #include <asm/io.h> | ||
3 | |||
4 | #include "pc873xx.h" | ||
5 | |||
6 | static unsigned pc873xx_probelist[] = {0x398, 0x26e, 0}; | ||
7 | |||
8 | static char *pc873xx_names[] = { | ||
9 | "PC87303", "PC87306", "PC87312", "PC87332", "PC87334" | ||
10 | }; | ||
11 | |||
12 | static unsigned int base, model; | ||
13 | |||
14 | |||
15 | unsigned int __init pc873xx_get_base() | ||
16 | { | ||
17 | return base; | ||
18 | } | ||
19 | |||
20 | char *__init pc873xx_get_model() | ||
21 | { | ||
22 | return pc873xx_names[model]; | ||
23 | } | ||
24 | |||
25 | static unsigned char __init pc873xx_read(unsigned int base, int reg) | ||
26 | { | ||
27 | outb(reg, base); | ||
28 | return inb(base + 1); | ||
29 | } | ||
30 | |||
31 | static void __init pc873xx_write(unsigned int base, int reg, unsigned char data) | ||
32 | { | ||
33 | unsigned long flags; | ||
34 | |||
35 | local_irq_save(flags); | ||
36 | outb(reg, base); | ||
37 | outb(data, base + 1); | ||
38 | outb(data, base + 1); /* Must be written twice */ | ||
39 | local_irq_restore(flags); | ||
40 | } | ||
41 | |||
42 | int __init pc873xx_probe(void) | ||
43 | { | ||
44 | int val, index = 0; | ||
45 | |||
46 | while ((base = pc873xx_probelist[index++])) { | ||
47 | |||
48 | if (request_region(base, 2, "Super IO PC873xx") == NULL) | ||
49 | continue; | ||
50 | |||
51 | val = pc873xx_read(base, REG_SID); | ||
52 | if ((val & 0xf0) == 0x10) { | ||
53 | model = PC87332; | ||
54 | break; | ||
55 | } else if ((val & 0xf8) == 0x70) { | ||
56 | model = PC87306; | ||
57 | break; | ||
58 | } else if ((val & 0xf8) == 0x50) { | ||
59 | model = PC87334; | ||
60 | break; | ||
61 | } else if ((val & 0xf8) == 0x40) { | ||
62 | model = PC87303; | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | release_region(base, 2); | ||
67 | } | ||
68 | |||
69 | return (base == 0) ? -1 : 1; | ||
70 | } | ||
71 | |||
72 | void __init pc873xx_enable_epp19(void) | ||
73 | { | ||
74 | unsigned char data; | ||
75 | |||
76 | printk(KERN_INFO "PC873xx enabling EPP v1.9\n"); | ||
77 | data = pc873xx_read(base, REG_PCR); | ||
78 | pc873xx_write(base, REG_PCR, (data & 0xFC) | 0x02); | ||
79 | } | ||
80 | |||
81 | void __init pc873xx_enable_ide(void) | ||
82 | { | ||
83 | unsigned char data; | ||
84 | |||
85 | printk(KERN_INFO "PC873xx enabling IDE interrupt\n"); | ||
86 | data = pc873xx_read(base, REG_FER); | ||
87 | pc873xx_write(base, REG_FER, data | 0x40); | ||
88 | } | ||
diff --git a/arch/alpha/kernel/pc873xx.h b/arch/alpha/kernel/pc873xx.h new file mode 100644 index 000000000000..25e16956fe3e --- /dev/null +++ b/arch/alpha/kernel/pc873xx.h | |||
@@ -0,0 +1,35 @@ | |||
1 | |||
2 | #ifndef _PC873xx_H_ | ||
3 | #define _PC873xx_H_ | ||
4 | |||
5 | /* | ||
6 | * Control Register Values | ||
7 | */ | ||
8 | #define REG_FER 0x00 | ||
9 | #define REG_FAR 0x01 | ||
10 | #define REG_PTR 0x02 | ||
11 | #define REG_FCR 0x03 | ||
12 | #define REG_PCR 0x04 | ||
13 | #define REG_KRR 0x05 | ||
14 | #define REG_PMC 0x06 | ||
15 | #define REG_TUP 0x07 | ||
16 | #define REG_SID 0x08 | ||
17 | #define REG_ASC 0x09 | ||
18 | #define REG_IRC 0x0e | ||
19 | |||
20 | /* | ||
21 | * Model numbers | ||
22 | */ | ||
23 | #define PC87303 0 | ||
24 | #define PC87306 1 | ||
25 | #define PC87312 2 | ||
26 | #define PC87332 3 | ||
27 | #define PC87334 4 | ||
28 | |||
29 | int pc873xx_probe(void); | ||
30 | unsigned int pc873xx_get_base(void); | ||
31 | char *pc873xx_get_model(void); | ||
32 | void pc873xx_enable_epp19(void); | ||
33 | void pc873xx_enable_ide(void); | ||
34 | |||
35 | #endif | ||
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index d4327e461c22..85b4aea01ef8 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "irq_impl.h" | 34 | #include "irq_impl.h" |
35 | #include "pci_impl.h" | 35 | #include "pci_impl.h" |
36 | #include "machvec_impl.h" | 36 | #include "machvec_impl.h" |
37 | #include "pc873xx.h" | ||
37 | 38 | ||
38 | #if defined(ALPHA_RESTORE_SRM_SETUP) | 39 | #if defined(ALPHA_RESTORE_SRM_SETUP) |
39 | /* Save LCA configuration data as the console had it set up. */ | 40 | /* Save LCA configuration data as the console had it set up. */ |
@@ -208,7 +209,27 @@ noname_init_pci(void) | |||
208 | common_init_pci(); | 209 | common_init_pci(); |
209 | sio_pci_route(); | 210 | sio_pci_route(); |
210 | sio_fixup_irq_levels(sio_collect_irq_levels()); | 211 | sio_fixup_irq_levels(sio_collect_irq_levels()); |
211 | ns87312_enable_ide(0x26e); | 212 | |
213 | if (pc873xx_probe() == -1) { | ||
214 | printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); | ||
215 | } else { | ||
216 | printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", | ||
217 | pc873xx_get_model(), pc873xx_get_base()); | ||
218 | |||
219 | /* Enabling things in the Super IO chip doesn't actually | ||
220 | * configure and enable things, the legacy drivers still | ||
221 | * need to do the actual configuration and enabling. | ||
222 | * This only unblocks them. | ||
223 | */ | ||
224 | |||
225 | #if !defined(CONFIG_ALPHA_AVANTI) | ||
226 | /* Don't bother on the Avanti family. | ||
227 | * None of them had on-board IDE. | ||
228 | */ | ||
229 | pc873xx_enable_ide(); | ||
230 | #endif | ||
231 | pc873xx_enable_epp19(); | ||
232 | } | ||
212 | } | 233 | } |
213 | 234 | ||
214 | static inline void __init | 235 | static inline void __init |