aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/galileo-boards/ev96100
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/galileo-boards/ev96100')
-rw-r--r--arch/mips/galileo-boards/ev96100/Makefile9
-rw-r--r--arch/mips/galileo-boards/ev96100/init.c173
-rw-r--r--arch/mips/galileo-boards/ev96100/irq.c77
-rw-r--r--arch/mips/galileo-boards/ev96100/puts.c138
-rw-r--r--arch/mips/galileo-boards/ev96100/reset.c70
-rw-r--r--arch/mips/galileo-boards/ev96100/setup.c159
-rw-r--r--arch/mips/galileo-boards/ev96100/time.c88
7 files changed, 0 insertions, 714 deletions
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile
deleted file mode 100644
index cd868ec78cbc..000000000000
--- a/arch/mips/galileo-boards/ev96100/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Copyright 2000 MontaVista Software Inc.
3# Author: MontaVista Software, Inc.
4# ppopov@mvista.com or source@mvista.com
5#
6# Makefile for the Galileo EV96100 board.
7#
8
9obj-y += init.o irq.o puts.o reset.o time.o setup.o
diff --git a/arch/mips/galileo-boards/ev96100/init.c b/arch/mips/galileo-boards/ev96100/init.c
deleted file mode 100644
index a01fe9b36f2c..000000000000
--- a/arch/mips/galileo-boards/ev96100/init.c
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * This file was derived from Carsten Langgaard's
7 * arch/mips/mips-boards/generic/generic.c
8 *
9 * Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/init.h>
33#include <linux/mm.h>
34#include <linux/sched.h>
35#include <linux/bootmem.h>
36#include <linux/string.h>
37#include <linux/kernel.h>
38
39#include <asm/addrspace.h>
40#include <asm/bootinfo.h>
41#include <asm/gt64120.h>
42
43
44/* Environment variable */
45
46typedef struct {
47 char *name;
48 char *val;
49} t_env_var;
50
51int prom_argc;
52char **prom_argv, **prom_envp;
53
54int init_debug = 0;
55
56char * __init prom_getcmdline(void)
57{
58 return &(arcs_cmdline[0]);
59}
60
61unsigned long __init prom_free_prom_memory(void)
62{
63 return 0;
64}
65
66void __init prom_init_cmdline(void)
67{
68 char *cp;
69 int actr;
70
71 actr = 1; /* Always ignore argv[0] */
72
73 cp = &(arcs_cmdline[0]);
74 while(actr < prom_argc) {
75 strcpy(cp, prom_argv[actr]);
76 cp += strlen(prom_argv[actr]);
77 *cp++ = ' ';
78 actr++;
79 }
80 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
81 --cp;
82 *cp = '\0';
83}
84
85char *prom_getenv(char *envname)
86{
87 /*
88 * Return a pointer to the given environment variable.
89 */
90
91 t_env_var *env = (t_env_var *) prom_envp;
92 int i;
93
94 i = strlen(envname);
95
96 while (env->name) {
97 if (strncmp(envname, env->name, i) == 0) {
98 return (env->val);
99 }
100 env++;
101 }
102 return (NULL);
103}
104
105static inline unsigned char str2hexnum(unsigned char c)
106{
107 if (c >= '0' && c <= '9')
108 return c - '0';
109 if (c >= 'a' && c <= 'f')
110 return c - 'a' + 10;
111 return 0; /* foo */
112}
113
114static inline void str2eaddr(unsigned char *ea, unsigned char *str)
115{
116 int i;
117
118 for (i = 0; i < 6; i++) {
119 unsigned char num;
120
121 if ((*str == '.') || (*str == ':'))
122 str++;
123 num = str2hexnum(*str++) << 4;
124 num |= (str2hexnum(*str++));
125 ea[i] = num;
126 }
127}
128
129int get_ethernet_addr(char *ethernet_addr)
130{
131 char *ethaddr_str;
132
133 ethaddr_str = prom_getenv("ethaddr");
134 if (!ethaddr_str) {
135 printk("ethaddr not set in boot prom\n");
136 return -1;
137 }
138 str2eaddr(ethernet_addr, ethaddr_str);
139
140 if (init_debug > 1) {
141 int i;
142 printk("get_ethernet_addr: ");
143 for (i = 0; i < 5; i++)
144 printk("%02x:",
145 (unsigned char) *(ethernet_addr + i));
146 printk("%02x\n", *(ethernet_addr + i));
147 }
148
149 return 0;
150}
151
152const char *get_system_type(void)
153{
154 return "Galileo EV96100";
155}
156
157void __init prom_init(void)
158{
159 volatile unsigned char *uart;
160 char ppbuf[8];
161
162 prom_argc = fw_arg0;
163 prom_argv = (char **) fw_arg1;
164 prom_envp = (char **) fw_arg2;
165
166 mips_machgroup = MACH_GROUP_GALILEO;
167 mips_machtype = MACH_EV96100;
168
169 prom_init_cmdline();
170
171 /* 32 MB upgradable */
172 add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
173}
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c
deleted file mode 100644
index ee5d6720f23b..000000000000
--- a/arch/mips/galileo-boards/ev96100/irq.c
+++ /dev/null
@@ -1,77 +0,0 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * This file was derived from Carsten Langgaard's
7 * arch/mips/mips-boards/atlas/atlas_int.c.
8 *
9 * Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/errno.h>
33#include <linux/init.h>
34#include <linux/kernel_stat.h>
35#include <linux/irq.h>
36#include <linux/module.h>
37#include <linux/signal.h>
38#include <linux/sched.h>
39#include <linux/types.h>
40#include <linux/interrupt.h>
41#include <asm/irq_cpu.h>
42
43static inline unsigned int ffz8(unsigned int word)
44{
45 unsigned long k;
46
47 k = 7;
48 if (word & 0x0fUL) { k -= 4; word <<= 4; }
49 if (word & 0x30UL) { k -= 2; word <<= 2; }
50 if (word & 0x40UL) { k -= 1; }
51
52 return k;
53}
54
55extern void mips_timer_interrupt(struct pt_regs *regs);
56
57asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
58{
59 do_IRQ(ffz8(pending >> 8), regs);
60}
61
62asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
63{
64 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
65
66 if (pending & CAUSEF_IP7)
67 mips_timer_interrupt(regs);
68 else if (pending)
69 ev96100_cpu_irq(pending, regs);
70 else
71 spurious_interrupt(regs);
72}
73
74void __init arch_init_irq(void)
75{
76 mips_cpu_irq_init(0);
77}
diff --git a/arch/mips/galileo-boards/ev96100/puts.c b/arch/mips/galileo-boards/ev96100/puts.c
deleted file mode 100644
index 49dc6d137b9c..000000000000
--- a/arch/mips/galileo-boards/ev96100/puts.c
+++ /dev/null
@@ -1,138 +0,0 @@
1
2/*
3 * Debug routines which directly access the uart.
4 */
5
6#include <linux/types.h>
7#include <asm/gt64120.h>
8
9
10//#define SERIAL_BASE EV96100_UART0_REGS_BASE
11#define SERIAL_BASE 0xBD000020
12#define NS16550_BASE SERIAL_BASE
13
14#define SERA_CMD 0x0D
15#define SERA_DATA 0x08
16//#define SERB_CMD 0x05
17#define SERB_CMD 20
18#define SERB_DATA 0x00
19#define TX_BUSY 0x20
20
21#define TIMEOUT 0xffff
22#undef SLOW_DOWN
23
24static const char digits[16] = "0123456789abcdef";
25static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
26
27
28#ifdef SLOW_DOWN
29static inline void slow_down()
30{
31 int k;
32 for (k = 0; k < 10000; k++);
33}
34#else
35#define slow_down()
36#endif
37
38void putch(const unsigned char c)
39{
40 unsigned char ch;
41 int i = 0;
42
43 do {
44 ch = com1[SERB_CMD];
45 slow_down();
46 i++;
47 if (i > TIMEOUT) {
48 break;
49 }
50 } while (0 == (ch & TX_BUSY));
51 com1[SERB_DATA] = c;
52}
53
54void putchar(const unsigned char c)
55{
56 unsigned char ch;
57 int i = 0;
58
59 do {
60 ch = com1[SERB_CMD];
61 slow_down();
62 i++;
63 if (i > TIMEOUT) {
64 break;
65 }
66 } while (0 == (ch & TX_BUSY));
67 com1[SERB_DATA] = c;
68}
69
70void puts(unsigned char *cp)
71{
72 unsigned char ch;
73 int i = 0;
74
75 while (*cp) {
76 do {
77 ch = com1[SERB_CMD];
78 slow_down();
79 i++;
80 if (i > TIMEOUT) {
81 break;
82 }
83 } while (0 == (ch & TX_BUSY));
84 com1[SERB_DATA] = *cp++;
85 }
86 putch('\r');
87 putch('\n');
88}
89
90void fputs(unsigned char *cp)
91{
92 unsigned char ch;
93 int i = 0;
94
95 while (*cp) {
96
97 do {
98 ch = com1[SERB_CMD];
99 slow_down();
100 i++;
101 if (i > TIMEOUT) {
102 break;
103 }
104 } while (0 == (ch & TX_BUSY));
105 com1[SERB_DATA] = *cp++;
106 }
107}
108
109
110void put64(uint64_t ul)
111{
112 int cnt;
113 unsigned ch;
114
115 cnt = 16; /* 16 nibbles in a 64 bit long */
116 putch('0');
117 putch('x');
118 do {
119 cnt--;
120 ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
121 putch(digits[ch]);
122 } while (cnt > 0);
123}
124
125void put32(unsigned u)
126{
127 int cnt;
128 unsigned ch;
129
130 cnt = 8; /* 8 nibbles in a 32 bit long */
131 putch('0');
132 putch('x');
133 do {
134 cnt--;
135 ch = (unsigned char) (u >> cnt * 4) & 0x0F;
136 putch(digits[ch]);
137 } while (cnt > 0);
138}
diff --git a/arch/mips/galileo-boards/ev96100/reset.c b/arch/mips/galileo-boards/ev96100/reset.c
deleted file mode 100644
index 5ef9b7f896e6..000000000000
--- a/arch/mips/galileo-boards/ev96100/reset.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 reset routines.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/generic/reset.c
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/sched.h>
36#include <linux/mm.h>
37#include <asm/io.h>
38#include <asm/pgtable.h>
39#include <asm/processor.h>
40#include <asm/reboot.h>
41#include <asm/system.h>
42#include <asm/gt64120.h>
43
44static void mips_machine_restart(char *command);
45static void mips_machine_halt(void);
46
47static void mips_machine_restart(char *command)
48{
49 set_c0_status(ST0_BEV | ST0_ERL);
50 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
51 flush_cache_all();
52 write_c0_wired(0);
53 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
54 while (1);
55}
56
57static void mips_machine_halt(void)
58{
59 printk(KERN_NOTICE "You can safely turn off the power\n");
60 while (1)
61 __asm__(".set\tmips3\n\t"
62 "wait\n\t"
63 ".set\tmips0");
64}
65
66void mips_reboot_setup(void)
67{
68 _machine_restart = mips_machine_restart;
69 _machine_halt = mips_machine_halt;
70}
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
deleted file mode 100644
index 639ad5562c63..000000000000
--- a/arch/mips/galileo-boards/ev96100/setup.c
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 setup.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/atlas/atlas_setup.c.
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/init.h>
36#include <linux/sched.h>
37#include <linux/ioport.h>
38#include <linux/string.h>
39#include <linux/ctype.h>
40#include <linux/pci.h>
41
42#include <asm/cpu.h>
43#include <asm/bootinfo.h>
44#include <asm/mipsregs.h>
45#include <asm/irq.h>
46#include <asm/delay.h>
47#include <asm/gt64120.h>
48#include <asm/galileo-boards/ev96100int.h>
49
50
51extern char *__init prom_getcmdline(void);
52
53extern void mips_reboot_setup(void);
54
55unsigned char mac_0_1[12];
56
57void __init plat_mem_setup(void)
58{
59 unsigned int config = read_c0_config();
60 unsigned int status = read_c0_status();
61 unsigned int info = read_c0_info();
62 u32 tmp;
63
64 char *argptr;
65
66 clear_c0_status(ST0_FR);
67
68 if (config & 0x8)
69 printk("Secondary cache is enabled\n");
70 else
71 printk("Secondary cache is disabled\n");
72
73 if (status & (1 << 27))
74 printk("User-mode cache ops enabled\n");
75 else
76 printk("User-mode cache ops disabled\n");
77
78 printk("CP0 info reg: %x\n", (unsigned) info);
79 if (info & (1 << 28))
80 printk("burst mode Scache RAMS\n");
81 else
82 printk("pipelined Scache RAMS\n");
83
84 if (info & 0x1)
85 printk("Atomic Enable is set\n");
86
87 argptr = prom_getcmdline();
88#ifdef CONFIG_SERIAL_CONSOLE
89 if (strstr(argptr, "console=") == NULL) {
90 argptr = prom_getcmdline();
91 strcat(argptr, " console=ttyS0,115200");
92 }
93#endif
94
95 mips_reboot_setup();
96
97 set_io_port_base(KSEG1);
98 ioport_resource.start = GT_PCI_IO_BASE;
99 ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff;
100
101#ifdef CONFIG_BLK_DEV_INITRD
102 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
103#endif
104
105
106 /*
107 * Setup GT controller master bit so we can do config cycles
108 */
109
110 /* Clear cause register bits */
111 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
112 GT_INTRCAUSE_TARABORT0_BIT));
113 /* Setup address */
114 GT_WRITE(GT_PCI0_CFGADDR_OFS,
115 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
116 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
117 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
118 GT_PCI0_CFGADDR_CONFIGEN_BIT);
119
120 udelay(2);
121 tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
122
123 tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
124 PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
125 GT_WRITE(GT_PCI0_CFGADDR_OFS,
126 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
127 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
128 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
129 GT_PCI0_CFGADDR_CONFIGEN_BIT);
130 udelay(2);
131 GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp);
132
133 /* Setup address */
134 GT_WRITE(GT_PCI0_CFGADDR_OFS,
135 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
136 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
137 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
138 GT_PCI0_CFGADDR_CONFIGEN_BIT);
139
140 udelay(2);
141 tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
142}
143
144unsigned short get_gt_devid(void)
145{
146 u32 gt_devid;
147
148 /* Figure out if this is a gt96100 or gt96100A */
149 GT_WRITE(GT_PCI0_CFGADDR_OFS,
150 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
151 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
152 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
153 GT_PCI0_CFGADDR_CONFIGEN_BIT);
154
155 udelay(4);
156 gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS);
157
158 return gt_devid >> 16;
159}
diff --git a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c
deleted file mode 100644
index 8cbe8426491a..000000000000
--- a/arch/mips/galileo-boards/ev96100/time.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 rtc routines.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/atlas/atlas_rtc.c.
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/init.h>
36#include <linux/kernel_stat.h>
37#include <linux/module.h>
38#include <linux/sched.h>
39#include <linux/spinlock.h>
40#include <linux/timex.h>
41
42#include <asm/mipsregs.h>
43#include <asm/ptrace.h>
44#include <asm/time.h>
45
46
47#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
48
49extern volatile unsigned long wall_jiffies;
50unsigned long missed_heart_beats = 0;
51
52static unsigned long r4k_offset; /* Amount to increment compare reg each time */
53static unsigned long r4k_cur; /* What counter should be at next timer irq */
54
55static inline void ack_r4ktimer(unsigned long newval)
56{
57 write_c0_compare(newval);
58}
59
60/*
61 * There are a lot of conceptually broken versions of the MIPS timer interrupt
62 * handler floating around. This one is rather different, but the algorithm
63 * is probably more robust.
64 */
65void mips_timer_interrupt(struct pt_regs *regs)
66{
67 int irq = 7; /* FIX ME */
68
69 if (r4k_offset == 0) {
70 goto null;
71 }
72
73 do {
74 kstat_this_cpu.irqs[irq]++;
75 do_timer(regs);
76#ifndef CONFIG_SMP
77 update_process_times(user_mode(regs));
78#endif
79 r4k_cur += r4k_offset;
80 ack_r4ktimer(r4k_cur);
81
82 } while (((unsigned long)read_c0_count()
83 - r4k_cur) < 0x7fffffff);
84 return;
85
86null:
87 ack_r4ktimer(0);
88}
n> printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", mxser_brdname[hwconf.board_type - 1], ioaddr[b]); if (retval <= 0) { if (retval == MXSER_ERR_IRQ) printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_IRQ_CONFLIT) printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_VECTOR) printk(KERN_ERR "Invalid interrupt vector,board not configured\n"); else if (retval == MXSER_ERR_IOADDR) printk(KERN_ERR "Invalid I/O address,board not configured\n"); continue; } hwconf.pciInfo.busNum = 0; hwconf.pciInfo.devNum = 0; hwconf.pciInfo.pdev = NULL; mxser_getcfg(m, &hwconf); //init mxsercfg first, or mxsercfg data is not correct on ISR. //mxser_initbrd will hook ISR. if (mxser_initbrd(m, &hwconf) < 0) continue; m++; } /* start finding PCI board here */ #ifdef CONFIG_PCI n = (sizeof(mxser_pcibrds) / sizeof(mxser_pcibrds[0])) - 1; index = 0; b = 0; while (b < n) { pdev = pci_find_device(mxser_pcibrds[b].vendor, mxser_pcibrds[b].device, pdev); if (pdev == NULL) { b++; continue; } hwconf.pciInfo.busNum = busnum = pdev->bus->number; hwconf.pciInfo.devNum = devnum = PCI_SLOT(pdev->devfn) << 3; hwconf.pciInfo.pdev = pdev; printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n", mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1], busnum, devnum >> 3); index++; if (m >= MXSER_BOARDS) { printk(KERN_ERR "Too many Smartio/Industio family boards find (maximum %d),board not configured\n", MXSER_BOARDS); } else { if (pci_enable_device(pdev)) { printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n"); continue; } retval = mxser_get_PCI_conf(busnum, devnum, (int) mxser_pcibrds[b].driver_data, &hwconf); if (retval < 0) { if (retval == MXSER_ERR_IRQ) printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_IRQ_CONFLIT) printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_VECTOR) printk(KERN_ERR "Invalid interrupt vector,board not configured\n"); else if (retval == MXSER_ERR_IOADDR) printk(KERN_ERR "Invalid I/O address,board not configured\n"); continue; } mxser_getcfg(m, &hwconf); //init mxsercfg first, or mxsercfg data is not correct on ISR. //mxser_initbrd will hook ISR. if (mxser_initbrd(m, &hwconf) < 0) continue; m++; } } #endif ret1 = 0; if (!(ret1 = tty_register_driver(mxvar_sdriver))) { return 0; } else printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n"); if (ret1) { for (i = 0; i < MXSER_BOARDS; i++) { if (mxsercfg[i].board_type == -1) continue; else { free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]); //todo: release io, vector } } return -1; } return (0); } static void mxser_do_softint(void *private_) { struct mxser_struct *info = (struct mxser_struct *) private_; struct tty_struct *tty; tty = info->tty; if (tty) { if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) tty_wakeup(tty); if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) tty_hangup(tty); } } static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info) { unsigned char status = 0; status = inb(baseaddr + UART_MSR); mxser_msr[port] &= 0x0F; mxser_msr[port] |= status; status = mxser_msr[port]; if (mode) mxser_msr[port] = 0; return status; } /* * This routine is called whenever a serial port is opened. It * enables interrupts for a serial port, linking in its async structure into * the IRQ chain. It also performs the serial-specific * initialization for the tty structure. */ static int mxser_open(struct tty_struct *tty, struct file *filp) { struct mxser_struct *info; int retval, line; line = tty->index; if (line == MXSER_PORTS) return 0; if (line < 0 || line > MXSER_PORTS) return -ENODEV; info = mxvar_table + line; if (!info->base) return (-ENODEV); tty->driver_data = info; info->tty = tty; /* * Start up serial port */ retval = mxser_startup(info); if (retval) return (retval); retval = mxser_block_til_ready(tty, filp, info); if (retval) return (retval); info->count++; if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { if (tty->driver->subtype == SERIAL_TYPE_NORMAL) *tty->termios = info->normal_termios; else *tty->termios = info->callout_termios; mxser_change_speed(info, NULL); } info->session = current->signal->session; info->pgrp = process_group(current); clear_bit(TTY_DONT_FLIP, &tty->flags); //status = mxser_get_msr(info->base, 0, info->port); //mxser_check_modem_status(info, status); /* unmark here for very high baud rate (ex. 921600 bps) used */ tty->low_latency = 1; return 0; } /* * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * async structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. */ static void mxser_close(struct tty_struct *tty, struct file *filp) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long timeout; unsigned long flags; struct tty_ldisc *ld; if (tty->index == MXSER_PORTS) return; if (!info) BUG(); spin_lock_irqsave(&info->slock, flags); if (tty_hung_up_p(filp)) { spin_unlock_irqrestore(&info->slock, flags); return; } if ((tty->count == 1) && (info->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk(KERN_ERR "mxser_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { printk(KERN_ERR "mxser_close: bad serial port count for ttys%d: %d\n", info->port, info->count); info->count = 0; } if (info->count) { spin_unlock_irqrestore(&info->slock, flags); return; } info->flags |= ASYNC_CLOSING; spin_unlock_irqrestore(&info->slock, flags); /* * Save the termios structure, since this port may have * separate termios for callout and dialin. */ if (info->flags & ASYNC_NORMAL_ACTIVE) info->normal_termios = *tty->termios; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, info->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ info->IER &= ~UART_IER_RLSI; if (info->IsMoxaMustChipFlag) info->IER &= ~MOXA_MUST_RECV_ISR; /* by William info->read_status_mask &= ~UART_LSR_DR; */ if (info->flags & ASYNC_INITIALIZED) { outb(info->IER, info->base + UART_IER); /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially * important if there is a transmit FIFO! */ timeout = jiffies + HZ; while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) { schedule_timeout_interruptible(5); if (time_after(jiffies, timeout)) break; } } mxser_shutdown(info); if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); ld = tty_ldisc_ref(tty); if (ld) { if(ld->flush_buffer) ld->flush_buffer(tty); tty_ldisc_deref(ld); } tty->closing = 0; info->event = 0; info->tty = NULL; if (info->blocked_open) { if (info->close_delay) schedule_timeout_interruptible(info->close_delay); wake_up_interruptible(&info->open_wait); } info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); } static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) { int c, total = 0; struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; if (!tty || !info->xmit_buf) return (0); while (1) { c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); spin_lock_irqsave(&info->slock, flags); info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); info->xmit_cnt += c; spin_unlock_irqrestore(&info->slock, flags); buf += c; count -= c; total += c; } if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) { if (!tty->hw_stopped || (info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { spin_lock_irqsave(&info->slock, flags); info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); spin_unlock_irqrestore(&info->slock, flags); } } return total; } static void mxser_put_char(struct tty_struct *tty, unsigned char ch) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; if (!tty || !info->xmit_buf) return; if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) return; spin_lock_irqsave(&info->slock, flags); info->xmit_buf[info->xmit_head++] = ch; info->xmit_head &= SERIAL_XMIT_SIZE - 1; info->xmit_cnt++; spin_unlock_irqrestore(&info->slock, flags); if (!tty->stopped && !(info->IER & UART_IER_THRI)) { if (!tty->hw_stopped || (info->type == PORT_16550A) || info->IsMoxaMustChipFlag) { spin_lock_irqsave(&info->slock, flags); info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); spin_unlock_irqrestore(&info->slock, flags); } } } static void mxser_flush_chars(struct tty_struct *tty) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf || (tty->hw_stopped && (info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag))) return; spin_lock_irqsave(&info->slock, flags); info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); spin_unlock_irqrestore(&info->slock, flags); } static int mxser_write_room(struct tty_struct *tty) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; int ret; ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; if (ret < 0) ret = 0; return (ret); } static int mxser_chars_in_buffer(struct tty_struct *tty) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; return info->xmit_cnt; } static void mxser_flush_buffer(struct tty_struct *tty) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; char fcr; unsigned long flags; spin_lock_irqsave(&info->slock, flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; /* below added by shinhay */ fcr = inb(info->base + UART_FCR); outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), info->base + UART_FCR); outb(fcr, info->base + UART_FCR); spin_unlock_irqrestore(&info->slock, flags); /* above added by shinhay */ wake_up_interruptible(&tty->write_wait); if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup) (tty); } static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; int retval; struct async_icount cprev, cnow; /* kernel counter temps */ struct serial_icounter_struct __user *p_cuser; unsigned long templ; unsigned long flags; void __user *argp = (void __user *)arg; if (tty->index == MXSER_PORTS) return (mxser_ioctl_special(cmd, argp)); // following add by Victor Yu. 01-05-2004 if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { int opmode, p; static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; int shiftbit; unsigned char val, mask; p = info->port % 4; if (cmd == MOXA_SET_OP_MODE) { if (get_user(opmode, (int __user *) argp)) return -EFAULT; if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && opmode != RS422_MODE && opmode != RS485_4WIRE_MODE) return -EFAULT; mask = ModeMask[p]; shiftbit = p * 2; val = inb(info->opmode_ioaddr); val &= mask; val |= (opmode << shiftbit); outb(val, info->opmode_ioaddr); } else { shiftbit = p * 2; opmode = inb(info->opmode_ioaddr) >> shiftbit; opmode &= OP_MODE_MASK; if (copy_to_user(argp, &opmode, sizeof(int))) return -EFAULT; } return 0; } // above add by Victor Yu. 01-05-2004 if ((cmd != TIOCGSERIAL) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { if (tty->flags & (1 << TTY_IO_ERROR)) return (-EIO); } switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) return (retval); tty_wait_until_sent(tty, 0); if (!arg) mxser_send_break(info, HZ / 4); /* 1/4 second */ return (0); case TCSBRKP: /* support for POSIX tcsendbreak() */ retval = tty_check_change(tty); if (retval) return (retval); tty_wait_until_sent(tty, 0); mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); return (0); case TIOCGSOFTCAR: return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); case TIOCSSOFTCAR: if (get_user(templ, (unsigned long __user *) argp)) return -EFAULT; arg = templ; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); return (0); case TIOCGSERIAL: return mxser_get_serial_info(info, argp); case TIOCSSERIAL: return mxser_set_serial_info(info, argp); case TIOCSERGETLSR: /* Get line status register */ return mxser_get_lsr_info(info, argp); /* * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change * - mask passed in arg for lines of interest * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) * Caller should use TIOCGICOUNT to see which one it was */ case TIOCMIWAIT:{ DECLARE_WAITQUEUE(wait, current); int ret; spin_lock_irqsave(&info->slock, flags); cprev = info->icount; /* note the counters on entry */ spin_unlock_irqrestore(&info->slock, flags); add_wait_queue(&info->delta_msr_wait, &wait); while (1) { spin_lock_irqsave(&info->slock, flags); cnow = info->icount; /* atomic copy */ spin_unlock_irqrestore(&info->slock, flags); set_current_state(TASK_INTERRUPTIBLE); if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { ret = 0; break; } /* see if a signal did it */ if (signal_pending(current)) { ret = -ERESTARTSYS; break; } cprev = cnow; } current->state = TASK_RUNNING; remove_wait_queue(&info->delta_msr_wait, &wait); break; } /* NOTREACHED */ /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct * NB: both 1->0 and 0->1 transitions are counted except for * RI where only 0->1 is counted. */ case TIOCGICOUNT: spin_lock_irqsave(&info->slock, flags); cnow = info->icount; spin_unlock_irqrestore(&info->slock, flags); p_cuser = argp; /* modified by casper 1/11/2000 */ if (put_user(cnow.frame, &p_cuser->frame)) return -EFAULT; if (put_user(cnow.brk, &p_cuser->brk)) return -EFAULT; if (put_user(cnow.overrun, &p_cuser->overrun)) return -EFAULT; if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) return -EFAULT; if (put_user(cnow.parity, &p_cuser->parity)) return -EFAULT; if (put_user(cnow.rx, &p_cuser->rx)) return -EFAULT; if (put_user(cnow.tx, &p_cuser->tx)) return -EFAULT; put_user(cnow.cts, &p_cuser->cts); put_user(cnow.dsr, &p_cuser->dsr); put_user(cnow.rng, &p_cuser->rng); put_user(cnow.dcd, &p_cuser->dcd); /* */ return 0; case MOXA_HighSpeedOn: return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *) argp); case MOXA_SDS_RSTICOUNTER:{ info->mon_data.rxcnt = 0; info->mon_data.txcnt = 0; return 0; } // (above) added by James. case MOXA_ASPP_SETBAUD:{ long baud; if (get_user(baud, (long __user *) argp)) return -EFAULT; mxser_set_baud(info, baud); return 0; } case MOXA_ASPP_GETBAUD: if (copy_to_user(argp, &info->realbaud, sizeof(long))) return -EFAULT; return 0; case MOXA_ASPP_OQUEUE:{ int len, lsr; len = mxser_chars_in_buffer(tty); lsr = inb(info->base + UART_LSR) & UART_LSR_TEMT; len += (lsr ? 0 : 1); if (copy_to_user(argp, &len, sizeof(int))) return -EFAULT; return 0; } case MOXA_ASPP_MON:{ int mcr, status; // info->mon_data.ser_param = tty->termios->c_cflag; status = mxser_get_msr(info->base, 1, info->port, info); mxser_check_modem_status(info, status); mcr = inb(info->base + UART_MCR); if (mcr & MOXA_MUST_MCR_XON_FLAG) info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; else info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD; if (mcr & MOXA_MUST_MCR_TX_XON) info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT; else info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; if (info->tty->hw_stopped) info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; else info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; if (copy_to_user(argp, &info->mon_data, sizeof(struct mxser_mon))) return -EFAULT; return 0; } case MOXA_ASPP_LSTATUS:{ if (copy_to_user(argp, &info->err_shadow, sizeof(unsigned char))) return -EFAULT; info->err_shadow = 0; return 0; } case MOXA_SET_BAUD_METHOD:{ int method; if (get_user(method, (int __user *) argp)) return -EFAULT; mxser_set_baud_method[info->port] = method; if (copy_to_user(argp, &method, sizeof(int))) return -EFAULT; return 0; } default: return -ENOIOCTLCMD; } return 0; } #ifndef CMSPAR #define CMSPAR 010000000000 #endif static int mxser_ioctl_special(unsigned int cmd, void __user *argp) { int i, result, status; switch (cmd) { case MOXA_GET_CONF: if (copy_to_user(argp, mxsercfg, sizeof(struct mxser_hwconf) * 4)) return -EFAULT; return 0; case MOXA_GET_MAJOR: if (copy_to_user(argp, &ttymajor, sizeof(int))) return -EFAULT; return 0; case MOXA_GET_CUMAJOR: if (copy_to_user(argp, &calloutmajor, sizeof(int))) return -EFAULT; return 0; case MOXA_CHKPORTENABLE: result = 0; for (i = 0; i < MXSER_PORTS; i++) { if (mxvar_table[i].base) result |= (1 << i); } return put_user(result, (unsigned long __user *) argp); case MOXA_GETDATACOUNT: if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) return -EFAULT; return (0); case MOXA_GETMSTATUS: for (i = 0; i < MXSER_PORTS; i++) { GMStatus[i].ri = 0; if (!mxvar_table[i].base) { GMStatus[i].dcd = 0; GMStatus[i].dsr = 0; GMStatus[i].cts = 0; continue; } if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios) GMStatus[i].cflag = mxvar_table[i].normal_termios.c_cflag; else GMStatus[i].cflag = mxvar_table[i].tty->termios->c_cflag; status = inb(mxvar_table[i].base + UART_MSR); if (status & 0x80 /*UART_MSR_DCD */ ) GMStatus[i].dcd = 1; else GMStatus[i].dcd = 0; if (status & 0x20 /*UART_MSR_DSR */ ) GMStatus[i].dsr = 1; else GMStatus[i].dsr = 0; if (status & 0x10 /*UART_MSR_CTS */ ) GMStatus[i].cts = 1; else GMStatus[i].cts = 0; } if (copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MXSER_PORTS)) return -EFAULT; return 0; case MOXA_ASPP_MON_EXT:{ int status; int opmode, p; int shiftbit; unsigned cflag, iflag; for (i = 0; i < MXSER_PORTS; i++) { if (!mxvar_table[i].base) continue; status = mxser_get_msr(mxvar_table[i].base, 0, i, &(mxvar_table[i])); // mxser_check_modem_status(&mxvar_table[i], status); if (status & UART_MSR_TERI) mxvar_table[i].icount.rng++; if (status & UART_MSR_DDSR) mxvar_table[i].icount.dsr++; if (status & UART_MSR_DDCD) mxvar_table[i].icount.dcd++; if (status & UART_MSR_DCTS) mxvar_table[i].icount.cts++; mxvar_table[i].mon_data.modem_status = status; mon_data_ext.rx_cnt[i] = mxvar_table[i].mon_data.rxcnt; mon_data_ext.tx_cnt[i] = mxvar_table[i].mon_data.txcnt; mon_data_ext.up_rxcnt[i] = mxvar_table[i].mon_data.up_rxcnt; mon_data_ext.up_txcnt[i] = mxvar_table[i].mon_data.up_txcnt; mon_data_ext.modem_status[i] = mxvar_table[i].mon_data.modem_status; mon_data_ext.baudrate[i] = mxvar_table[i].realbaud; if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios) { cflag = mxvar_table[i].normal_termios.c_cflag; iflag = mxvar_table[i].normal_termios.c_iflag; } else { cflag = mxvar_table[i].tty->termios->c_cflag; iflag = mxvar_table[i].tty->termios->c_iflag; } mon_data_ext.databits[i] = cflag & CSIZE; mon_data_ext.stopbits[i] = cflag & CSTOPB; mon_data_ext.parity[i] = cflag & (PARENB | PARODD | CMSPAR); mon_data_ext.flowctrl[i] = 0x00; if (cflag & CRTSCTS) mon_data_ext.flowctrl[i] |= 0x03; if (iflag & (IXON | IXOFF)) mon_data_ext.flowctrl[i] |= 0x0C; if (mxvar_table[i].type == PORT_16550A) mon_data_ext.fifo[i] = 1; else mon_data_ext.fifo[i] = 0; p = i % 4; shiftbit = p * 2; opmode = inb(mxvar_table[i].opmode_ioaddr) >> shiftbit; opmode &= OP_MODE_MASK; mon_data_ext.iftype[i] = opmode; } if (copy_to_user(argp, &mon_data_ext, sizeof(struct mxser_mon_ext))) return -EFAULT; return 0; } default: return -ENOIOCTLCMD; } return 0; } static void mxser_stoprx(struct tty_struct *tty) {