aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tc')
-rw-r--r--drivers/tc/tc.c89
-rw-r--r--drivers/tc/zs.c32
2 files changed, 48 insertions, 73 deletions
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index a89ef4df80c3..a0e5af638e0e 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -8,33 +8,31 @@
8 * for more details. 8 * for more details.
9 * 9 *
10 * Copyright (c) Harald Koerfgen, 1998 10 * Copyright (c) Harald Koerfgen, 1998
11 * Copyright (c) 2001, 2003 Maciej W. Rozycki 11 * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki
12 */ 12 */
13#include <linux/string.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/kernel.h> 14#include <linux/kernel.h>
17#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/string.h>
17#include <linux/types.h>
18 18
19#include <asm/addrspace.h> 19#include <asm/addrspace.h>
20#include <asm/bug.h>
20#include <asm/errno.h> 21#include <asm/errno.h>
22#include <asm/io.h>
23#include <asm/paccess.h>
24
21#include <asm/dec/machtype.h> 25#include <asm/dec/machtype.h>
22#include <asm/dec/prom.h> 26#include <asm/dec/prom.h>
23#include <asm/dec/tcinfo.h> 27#include <asm/dec/tcinfo.h>
24#include <asm/dec/tcmodule.h> 28#include <asm/dec/tcmodule.h>
25#include <asm/dec/interrupts.h> 29#include <asm/dec/interrupts.h>
26#include <asm/paccess.h>
27#include <asm/ptrace.h>
28
29#define TC_DEBUG
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32slot_info tc_bus[MAX_SLOT]; 32slot_info tc_bus[MAX_SLOT];
33static int num_tcslots; 33static int num_tcslots;
34static tcinfo *info; 34static tcinfo *info;
35 35
36unsigned long system_base;
37
38/* 36/*
39 * Interface to the world. Read comment in include/asm-mips/tc.h. 37 * Interface to the world. Read comment in include/asm-mips/tc.h.
40 */ 38 */
@@ -97,13 +95,16 @@ unsigned long get_tc_speed(void)
97static void __init tc_probe(unsigned long startaddr, unsigned long size, 95static void __init tc_probe(unsigned long startaddr, unsigned long size,
98 int slots) 96 int slots)
99{ 97{
98 unsigned long slotaddr;
100 int i, slot, err; 99 int i, slot, err;
101 long offset; 100 long offset;
102 unsigned char pattern[4]; 101 u8 pattern[4];
103 unsigned char *module; 102 volatile u8 *module;
104 103
105 for (slot = 0; slot < slots; slot++) { 104 for (slot = 0; slot < slots; slot++) {
106 module = (char *)(startaddr + slot * size); 105 slotaddr = startaddr + slot * size;
106 module = ioremap_nocache(slotaddr, size);
107 BUG_ON(!module);
107 108
108 offset = OLDCARD; 109 offset = OLDCARD;
109 110
@@ -112,8 +113,10 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
112 err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1); 113 err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
113 err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2); 114 err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
114 err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3); 115 err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
115 if (err) 116 if (err) {
117 iounmap(module);
116 continue; 118 continue;
119 }
117 120
118 if (pattern[0] != 0x55 || pattern[1] != 0x00 || 121 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
119 pattern[2] != 0xaa || pattern[3] != 0xff) { 122 pattern[2] != 0xaa || pattern[3] != 0xff) {
@@ -124,16 +127,20 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
124 err |= get_dbe(pattern[1], module + TC_PATTERN1); 127 err |= get_dbe(pattern[1], module + TC_PATTERN1);
125 err |= get_dbe(pattern[2], module + TC_PATTERN2); 128 err |= get_dbe(pattern[2], module + TC_PATTERN2);
126 err |= get_dbe(pattern[3], module + TC_PATTERN3); 129 err |= get_dbe(pattern[3], module + TC_PATTERN3);
127 if (err) 130 if (err) {
131 iounmap(module);
128 continue; 132 continue;
133 }
129 } 134 }
130 135
131 if (pattern[0] != 0x55 || pattern[1] != 0x00 || 136 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
132 pattern[2] != 0xaa || pattern[3] != 0xff) 137 pattern[2] != 0xaa || pattern[3] != 0xff) {
138 iounmap(module);
133 continue; 139 continue;
140 }
134 141
135 tc_bus[slot].base_addr = (unsigned long)module; 142 tc_bus[slot].base_addr = slotaddr;
136 for(i = 0; i < 8; i++) { 143 for (i = 0; i < 8; i++) {
137 tc_bus[slot].firmware[i] = 144 tc_bus[slot].firmware[i] =
138 module[TC_FIRM_VER + offset + 4 * i]; 145 module[TC_FIRM_VER + offset + 4 * i];
139 tc_bus[slot].vendor[i] = 146 tc_bus[slot].vendor[i] =
@@ -171,13 +178,15 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
171 tc_bus[slot].interrupt = -1; 178 tc_bus[slot].interrupt = -1;
172 break; 179 break;
173 } 180 }
181
182 iounmap(module);
174 } 183 }
175} 184}
176 185
177/* 186/*
178 * the main entry 187 * the main entry
179 */ 188 */
180void __init tc_init(void) 189static int __init tc_init(void)
181{ 190{
182 int tc_clock; 191 int tc_clock;
183 int i; 192 int i;
@@ -185,7 +194,7 @@ void __init tc_init(void)
185 unsigned long slot_size; 194 unsigned long slot_size;
186 195
187 if (!TURBOCHANNEL) 196 if (!TURBOCHANNEL)
188 return; 197 return 0;
189 198
190 for (i = 0; i < MAX_SLOT; i++) { 199 for (i = 0; i < MAX_SLOT; i++) {
191 tc_bus[i].base_addr = 0; 200 tc_bus[i].base_addr = 0;
@@ -196,8 +205,8 @@ void __init tc_init(void)
196 tc_bus[i].flags = FREE; 205 tc_bus[i].flags = FREE;
197 } 206 }
198 207
199 info = (tcinfo *) rex_gettcinfo(); 208 info = rex_gettcinfo();
200 slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0)); 209 slot0addr = CPHYSADDR((long)rex_slot_address(0));
201 210
202 switch (mips_machtype) { 211 switch (mips_machtype) {
203 case MACH_DS5000_200: 212 case MACH_DS5000_200:
@@ -216,37 +225,24 @@ void __init tc_init(void)
216 225
217 tc_clock = 10000 / info->clk_period; 226 tc_clock = 10000 / info->clk_period;
218 227
219 if (TURBOCHANNEL && info->slot_size && slot0addr) { 228 if (info->slot_size && slot0addr) {
220 printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision, 229 pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n",
221 tc_clock / 10, tc_clock % 10); 230 info->revision, tc_clock / 10, tc_clock % 10,
222 printk("(with%s parity)\n", info->parity ? "" : "out"); 231 info->parity ? "" : "out");
223 232
224 slot_size = info->slot_size << 20; 233 slot_size = info->slot_size << 20;
225 234
226 tc_probe(slot0addr, slot_size, num_tcslots); 235 tc_probe(slot0addr, slot_size, num_tcslots);
227 236
228 /* 237 for (i = 0; i < num_tcslots; i++) {
229 * All TURBOchannel DECstations have the onboard devices 238 if (!tc_bus[i].base_addr)
230 * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module 239 continue;
231 * would be. 240 pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor,
232 */ 241 tc_bus[i].name, tc_bus[i].firmware);
233 if(mips_machtype == MACH_DS5000_XX) 242 }
234 i = 1;
235 else
236 i = 0;
237
238 system_base = slot0addr + slot_size * (num_tcslots + i);
239
240#ifdef TC_DEBUG
241 for (i = 0; i < num_tcslots; i++)
242 if (tc_bus[i].base_addr) {
243 printk(" slot %d: ", i);
244 printk("%s %s %s\n", tc_bus[i].vendor,
245 tc_bus[i].name, tc_bus[i].firmware);
246 }
247#endif
248 ioport_resource.end = KSEG2 - 1;
249 } 243 }
244
245 return 0;
250} 246}
251 247
252subsys_initcall(tc_init); 248subsys_initcall(tc_init);
@@ -257,4 +253,3 @@ EXPORT_SYMBOL(release_tc_card);
257EXPORT_SYMBOL(get_tc_base_addr); 253EXPORT_SYMBOL(get_tc_base_addr);
258EXPORT_SYMBOL(get_tc_irq_nr); 254EXPORT_SYMBOL(get_tc_irq_nr);
259EXPORT_SYMBOL(get_tc_speed); 255EXPORT_SYMBOL(get_tc_speed);
260EXPORT_SYMBOL(system_base);
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 6bed8713897e..c52af73a251b 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -65,14 +65,14 @@
65#include <asm/system.h> 65#include <asm/system.h>
66#include <asm/uaccess.h> 66#include <asm/uaccess.h>
67#include <asm/bootinfo.h> 67#include <asm/bootinfo.h>
68#include <asm/dec/serial.h>
69 68
70#ifdef CONFIG_MACH_DECSTATION
71#include <asm/dec/interrupts.h> 69#include <asm/dec/interrupts.h>
70#include <asm/dec/ioasic_addrs.h>
72#include <asm/dec/machtype.h> 71#include <asm/dec/machtype.h>
72#include <asm/dec/serial.h>
73#include <asm/dec/system.h>
73#include <asm/dec/tc.h> 74#include <asm/dec/tc.h>
74#include <asm/dec/ioasic_addrs.h> 75
75#endif
76#ifdef CONFIG_KGDB 76#ifdef CONFIG_KGDB
77#include <asm/kgdb.h> 77#include <asm/kgdb.h>
78#endif 78#endif
@@ -192,18 +192,6 @@ static void probe_sccs(void);
192static void change_speed(struct dec_serial *info); 192static void change_speed(struct dec_serial *info);
193static void rs_wait_until_sent(struct tty_struct *tty, int timeout); 193static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
194 194
195/*
196 * tmp_buf is used as a temporary buffer by serial_write. We need to
197 * lock it in case the copy_from_user blocks while swapping in a page,
198 * and some other program tries to do a serial write at the same time.
199 * Since the lock will only come under contention when the system is
200 * swapping and available memory is low, it makes sense to share one
201 * buffer across all the serial ports, since it significantly saves
202 * memory if large numbers of serial ports are open.
203 */
204static unsigned char tmp_buf[4096]; /* This is cheating */
205static DECLARE_MUTEX(tmp_buf_sem);
206
207static inline int serial_paranoia_check(struct dec_serial *info, 195static inline int serial_paranoia_check(struct dec_serial *info,
208 char *name, const char *routine) 196 char *name, const char *routine)
209{ 197{
@@ -1628,30 +1616,22 @@ static void __init probe_sccs(void)
1628 return; 1616 return;
1629 } 1617 }
1630 1618
1631 /*
1632 * When serial console is activated, tc_init has not been called yet
1633 * and system_base is undefined. Unfortunately we have to hardcode
1634 * system_base for this case :-(. HK
1635 */
1636 switch(mips_machtype) { 1619 switch(mips_machtype) {
1637#ifdef CONFIG_MACH_DECSTATION 1620#ifdef CONFIG_MACH_DECSTATION
1638 case MACH_DS5000_2X0: 1621 case MACH_DS5000_2X0:
1639 case MACH_DS5900: 1622 case MACH_DS5900:
1640 system_base = KSEG1ADDR(0x1f800000);
1641 n_chips = 2; 1623 n_chips = 2;
1642 zs_parms = &ds_parms; 1624 zs_parms = &ds_parms;
1643 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0]; 1625 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
1644 zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1]; 1626 zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
1645 break; 1627 break;
1646 case MACH_DS5000_1XX: 1628 case MACH_DS5000_1XX:
1647 system_base = KSEG1ADDR(0x1c000000);
1648 n_chips = 2; 1629 n_chips = 2;
1649 zs_parms = &ds_parms; 1630 zs_parms = &ds_parms;
1650 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0]; 1631 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
1651 zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1]; 1632 zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
1652 break; 1633 break;
1653 case MACH_DS5000_XX: 1634 case MACH_DS5000_XX:
1654 system_base = KSEG1ADDR(0x1c000000);
1655 n_chips = 1; 1635 n_chips = 1;
1656 zs_parms = &ds_parms; 1636 zs_parms = &ds_parms;
1657 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0]; 1637 zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
@@ -1673,10 +1653,10 @@ static void __init probe_sccs(void)
1673 * The sccs reside on the high byte of the 16 bit IOBUS 1653 * The sccs reside on the high byte of the 16 bit IOBUS
1674 */ 1654 */
1675 zs_channels[n_channels].control = 1655 zs_channels[n_channels].control =
1676 (volatile unsigned char *)system_base + 1656 (volatile void *)CKSEG1ADDR(dec_kn_slot_base +
1677 (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 1657 (0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
1678 (0 == channel ? zs_parms->channel_a_offset : 1658 (0 == channel ? zs_parms->channel_a_offset :
1679 zs_parms->channel_b_offset); 1659 zs_parms->channel_b_offset));
1680 zs_channels[n_channels].data = 1660 zs_channels[n_channels].data =
1681 zs_channels[n_channels].control + 4; 1661 zs_channels[n_channels].control + 4;
1682 1662