diff options
author | Brian Murphy <brm@murphy.dk> | 2007-08-21 16:34:16 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-10-11 18:46:00 -0400 |
commit | 1f21d2bde0046e959b53756f74d96dfd040a803b (patch) | |
tree | 5ca1a0319982f1e665e57f22bd1dae1d90b07e35 /arch/mips/lasat | |
parent | 0caf583398309398ec05fc76bff15c711e9f936d (diff) |
[MIPS] Add back support for LASAT platforms
Signed-off-by: Brian Murphy <brian@murphy.dk>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/lasat')
-rw-r--r-- | arch/mips/lasat/Kconfig | 15 | ||||
-rw-r--r-- | arch/mips/lasat/Makefile | 16 | ||||
-rw-r--r-- | arch/mips/lasat/at93c.c | 149 | ||||
-rw-r--r-- | arch/mips/lasat/at93c.h | 18 | ||||
-rw-r--r-- | arch/mips/lasat/ds1603.c | 183 | ||||
-rw-r--r-- | arch/mips/lasat/ds1603.h | 33 | ||||
-rw-r--r-- | arch/mips/lasat/image/Makefile | 54 | ||||
-rw-r--r-- | arch/mips/lasat/image/head.S | 31 | ||||
-rw-r--r-- | arch/mips/lasat/image/romscript.normal | 23 | ||||
-rw-r--r-- | arch/mips/lasat/interrupt.c | 130 | ||||
-rw-r--r-- | arch/mips/lasat/lasat_board.c | 280 | ||||
-rw-r--r-- | arch/mips/lasat/lasat_models.h | 67 | ||||
-rw-r--r-- | arch/mips/lasat/picvue.c | 244 | ||||
-rw-r--r-- | arch/mips/lasat/picvue.h | 48 | ||||
-rw-r--r-- | arch/mips/lasat/picvue_proc.c | 191 | ||||
-rw-r--r-- | arch/mips/lasat/prom.c | 128 | ||||
-rw-r--r-- | arch/mips/lasat/prom.h | 7 | ||||
-rw-r--r-- | arch/mips/lasat/reset.c | 61 | ||||
-rw-r--r-- | arch/mips/lasat/serial.c | 94 | ||||
-rw-r--r-- | arch/mips/lasat/setup.c | 158 | ||||
-rw-r--r-- | arch/mips/lasat/sysctl.c | 454 | ||||
-rw-r--r-- | arch/mips/lasat/sysctl.h | 24 |
22 files changed, 2408 insertions, 0 deletions
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig new file mode 100644 index 000000000000..1d2ee8a9be13 --- /dev/null +++ b/arch/mips/lasat/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | config PICVUE | ||
2 | tristate "PICVUE LCD display driver" | ||
3 | depends on LASAT | ||
4 | |||
5 | config PICVUE_PROC | ||
6 | tristate "PICVUE LCD display driver /proc interface" | ||
7 | depends on PICVUE | ||
8 | |||
9 | config DS1603 | ||
10 | bool "DS1603 RTC driver" | ||
11 | depends on LASAT | ||
12 | |||
13 | config LASAT_SYSCTL | ||
14 | bool "LASAT sysctl interface" | ||
15 | depends on LASAT | ||
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile new file mode 100644 index 000000000000..33791609fe99 --- /dev/null +++ b/arch/mips/lasat/Makefile | |||
@@ -0,0 +1,16 @@ | |||
1 | # | ||
2 | # Makefile for the LASAT specific kernel interface routines under Linux. | ||
3 | # | ||
4 | |||
5 | obj-y += reset.o setup.o prom.o lasat_board.o \ | ||
6 | at93c.o interrupt.o serial.o | ||
7 | |||
8 | obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o | ||
9 | obj-$(CONFIG_DS1603) += ds1603.o | ||
10 | obj-$(CONFIG_PICVUE) += picvue.o | ||
11 | obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o | ||
12 | |||
13 | clean: | ||
14 | make -C image clean | ||
15 | |||
16 | EXTRA_CFLAGS += -Werror | ||
diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c new file mode 100644 index 000000000000..793e234719a6 --- /dev/null +++ b/arch/mips/lasat/at93c.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Atmel AT93C46 serial eeprom driver | ||
3 | * | ||
4 | * Brian Murphy <brian.murphy@eicon.com> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <asm/lasat/lasat.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | |||
13 | #include "at93c.h" | ||
14 | |||
15 | #define AT93C_ADDR_SHIFT 7 | ||
16 | #define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) | ||
17 | #define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) | ||
18 | #define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) | ||
19 | #define AT93C_WENCMD 0x260 | ||
20 | #define AT93C_WDSCMD 0x200 | ||
21 | |||
22 | struct at93c_defs *at93c; | ||
23 | |||
24 | static void at93c_reg_write(u32 val) | ||
25 | { | ||
26 | *at93c->reg = val; | ||
27 | } | ||
28 | |||
29 | static u32 at93c_reg_read(void) | ||
30 | { | ||
31 | u32 tmp = *at93c->reg; | ||
32 | return tmp; | ||
33 | } | ||
34 | |||
35 | static u32 at93c_datareg_read(void) | ||
36 | { | ||
37 | u32 tmp = *at93c->rdata_reg; | ||
38 | return tmp; | ||
39 | } | ||
40 | |||
41 | static void at93c_cycle_clk(u32 data) | ||
42 | { | ||
43 | at93c_reg_write(data | at93c->clk); | ||
44 | lasat_ndelay(250); | ||
45 | at93c_reg_write(data & ~at93c->clk); | ||
46 | lasat_ndelay(250); | ||
47 | } | ||
48 | |||
49 | static void at93c_write_databit(u8 bit) | ||
50 | { | ||
51 | u32 data = at93c_reg_read(); | ||
52 | if (bit) | ||
53 | data |= 1 << at93c->wdata_shift; | ||
54 | else | ||
55 | data &= ~(1 << at93c->wdata_shift); | ||
56 | |||
57 | at93c_reg_write(data); | ||
58 | lasat_ndelay(100); | ||
59 | at93c_cycle_clk(data); | ||
60 | } | ||
61 | |||
62 | static unsigned int at93c_read_databit(void) | ||
63 | { | ||
64 | u32 data; | ||
65 | |||
66 | at93c_cycle_clk(at93c_reg_read()); | ||
67 | data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; | ||
68 | return data; | ||
69 | } | ||
70 | |||
71 | static u8 at93c_read_byte(void) | ||
72 | { | ||
73 | int i; | ||
74 | u8 data = 0; | ||
75 | |||
76 | for (i = 0; i <= 7; i++) { | ||
77 | data <<= 1; | ||
78 | data |= at93c_read_databit(); | ||
79 | } | ||
80 | return data; | ||
81 | } | ||
82 | |||
83 | static void at93c_write_bits(u32 data, int size) | ||
84 | { | ||
85 | int i; | ||
86 | int shift = size - 1; | ||
87 | u32 mask = (1 << shift); | ||
88 | |||
89 | for (i = 0; i < size; i++) { | ||
90 | at93c_write_databit((data & mask) >> shift); | ||
91 | data <<= 1; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void at93c_init_op(void) | ||
96 | { | ||
97 | at93c_reg_write((at93c_reg_read() | at93c->cs) & | ||
98 | ~at93c->clk & ~(1 << at93c->rdata_shift)); | ||
99 | lasat_ndelay(50); | ||
100 | } | ||
101 | |||
102 | static void at93c_end_op(void) | ||
103 | { | ||
104 | at93c_reg_write(at93c_reg_read() & ~at93c->cs); | ||
105 | lasat_ndelay(250); | ||
106 | } | ||
107 | |||
108 | static void at93c_wait(void) | ||
109 | { | ||
110 | at93c_init_op(); | ||
111 | while (!at93c_read_databit()) | ||
112 | ; | ||
113 | at93c_end_op(); | ||
114 | }; | ||
115 | |||
116 | static void at93c_disable_wp(void) | ||
117 | { | ||
118 | at93c_init_op(); | ||
119 | at93c_write_bits(AT93C_WENCMD, 10); | ||
120 | at93c_end_op(); | ||
121 | } | ||
122 | |||
123 | static void at93c_enable_wp(void) | ||
124 | { | ||
125 | at93c_init_op(); | ||
126 | at93c_write_bits(AT93C_WDSCMD, 10); | ||
127 | at93c_end_op(); | ||
128 | } | ||
129 | |||
130 | u8 at93c_read(u8 addr) | ||
131 | { | ||
132 | u8 byte; | ||
133 | at93c_init_op(); | ||
134 | at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); | ||
135 | byte = at93c_read_byte(); | ||
136 | at93c_end_op(); | ||
137 | return byte; | ||
138 | } | ||
139 | |||
140 | void at93c_write(u8 addr, u8 data) | ||
141 | { | ||
142 | at93c_disable_wp(); | ||
143 | at93c_init_op(); | ||
144 | at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); | ||
145 | at93c_write_bits(data, 8); | ||
146 | at93c_end_op(); | ||
147 | at93c_wait(); | ||
148 | at93c_enable_wp(); | ||
149 | } | ||
diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h new file mode 100644 index 000000000000..cfe2f99b1d44 --- /dev/null +++ b/arch/mips/lasat/at93c.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Atmel AT93C46 serial eeprom driver | ||
3 | * | ||
4 | * Brian Murphy <brian.murphy@eicon.com> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | extern struct at93c_defs { | ||
9 | volatile u32 *reg; | ||
10 | volatile u32 *rdata_reg; | ||
11 | int rdata_shift; | ||
12 | int wdata_shift; | ||
13 | u32 cs; | ||
14 | u32 clk; | ||
15 | } *at93c; | ||
16 | |||
17 | u8 at93c_read(u8 addr); | ||
18 | void at93c_write(u8 addr, u8 data); | ||
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c new file mode 100644 index 000000000000..0b315f51d62c --- /dev/null +++ b/arch/mips/lasat/ds1603.c | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * Dallas Semiconductors 1603 RTC driver | ||
3 | * | ||
4 | * Brian Murphy <brian@murphy.dk> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/kernel.h> | ||
8 | #include <asm/lasat/lasat.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <asm/lasat/ds1603.h> | ||
11 | #include <asm/time.h> | ||
12 | |||
13 | #include "ds1603.h" | ||
14 | |||
15 | #define READ_TIME_CMD 0x81 | ||
16 | #define SET_TIME_CMD 0x80 | ||
17 | #define TRIMMER_SET_CMD 0xC0 | ||
18 | #define TRIMMER_VALUE_MASK 0x38 | ||
19 | #define TRIMMER_SHIFT 3 | ||
20 | |||
21 | struct ds_defs *ds1603; | ||
22 | |||
23 | /* HW specific register functions */ | ||
24 | static void rtc_reg_write(unsigned long val) | ||
25 | { | ||
26 | *ds1603->reg = val; | ||
27 | } | ||
28 | |||
29 | static unsigned long rtc_reg_read(void) | ||
30 | { | ||
31 | unsigned long tmp = *ds1603->reg; | ||
32 | return tmp; | ||
33 | } | ||
34 | |||
35 | static unsigned long rtc_datareg_read(void) | ||
36 | { | ||
37 | unsigned long tmp = *ds1603->data_reg; | ||
38 | return tmp; | ||
39 | } | ||
40 | |||
41 | static void rtc_nrst_high(void) | ||
42 | { | ||
43 | rtc_reg_write(rtc_reg_read() | ds1603->rst); | ||
44 | } | ||
45 | |||
46 | static void rtc_nrst_low(void) | ||
47 | { | ||
48 | rtc_reg_write(rtc_reg_read() & ~ds1603->rst); | ||
49 | } | ||
50 | |||
51 | static void rtc_cycle_clock(unsigned long data) | ||
52 | { | ||
53 | data |= ds1603->clk; | ||
54 | rtc_reg_write(data); | ||
55 | lasat_ndelay(250); | ||
56 | if (ds1603->data_reversed) | ||
57 | data &= ~ds1603->data; | ||
58 | else | ||
59 | data |= ds1603->data; | ||
60 | data &= ~ds1603->clk; | ||
61 | rtc_reg_write(data); | ||
62 | lasat_ndelay(250 + ds1603->huge_delay); | ||
63 | } | ||
64 | |||
65 | static void rtc_write_databit(unsigned int bit) | ||
66 | { | ||
67 | unsigned long data = rtc_reg_read(); | ||
68 | if (ds1603->data_reversed) | ||
69 | bit = !bit; | ||
70 | if (bit) | ||
71 | data |= ds1603->data; | ||
72 | else | ||
73 | data &= ~ds1603->data; | ||
74 | |||
75 | rtc_reg_write(data); | ||
76 | lasat_ndelay(50 + ds1603->huge_delay); | ||
77 | rtc_cycle_clock(data); | ||
78 | } | ||
79 | |||
80 | static unsigned int rtc_read_databit(void) | ||
81 | { | ||
82 | unsigned int data; | ||
83 | |||
84 | data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) | ||
85 | >> ds1603->data_read_shift; | ||
86 | rtc_cycle_clock(rtc_reg_read()); | ||
87 | return data; | ||
88 | } | ||
89 | |||
90 | static void rtc_write_byte(unsigned int byte) | ||
91 | { | ||
92 | int i; | ||
93 | |||
94 | for (i = 0; i <= 7; i++) { | ||
95 | rtc_write_databit(byte & 1L); | ||
96 | byte >>= 1; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | static void rtc_write_word(unsigned long word) | ||
101 | { | ||
102 | int i; | ||
103 | |||
104 | for (i = 0; i <= 31; i++) { | ||
105 | rtc_write_databit(word & 1L); | ||
106 | word >>= 1; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static unsigned long rtc_read_word(void) | ||
111 | { | ||
112 | int i; | ||
113 | unsigned long word = 0; | ||
114 | unsigned long shift = 0; | ||
115 | |||
116 | for (i = 0; i <= 31; i++) { | ||
117 | word |= rtc_read_databit() << shift; | ||
118 | shift++; | ||
119 | } | ||
120 | return word; | ||
121 | } | ||
122 | |||
123 | static void rtc_init_op(void) | ||
124 | { | ||
125 | rtc_nrst_high(); | ||
126 | |||
127 | rtc_reg_write(rtc_reg_read() & ~ds1603->clk); | ||
128 | |||
129 | lasat_ndelay(50); | ||
130 | } | ||
131 | |||
132 | static void rtc_end_op(void) | ||
133 | { | ||
134 | rtc_nrst_low(); | ||
135 | lasat_ndelay(1000); | ||
136 | } | ||
137 | |||
138 | /* interface */ | ||
139 | unsigned long ds1603_read(void) | ||
140 | { | ||
141 | unsigned long word; | ||
142 | unsigned long flags; | ||
143 | |||
144 | spin_lock_irqsave(&rtc_lock, flags); | ||
145 | rtc_init_op(); | ||
146 | rtc_write_byte(READ_TIME_CMD); | ||
147 | word = rtc_read_word(); | ||
148 | rtc_end_op(); | ||
149 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
150 | return word; | ||
151 | } | ||
152 | |||
153 | int ds1603_set(unsigned long time) | ||
154 | { | ||
155 | unsigned long flags; | ||
156 | |||
157 | spin_lock_irqsave(&rtc_lock, flags); | ||
158 | rtc_init_op(); | ||
159 | rtc_write_byte(SET_TIME_CMD); | ||
160 | rtc_write_word(time); | ||
161 | rtc_end_op(); | ||
162 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | void ds1603_set_trimmer(unsigned int trimval) | ||
168 | { | ||
169 | rtc_init_op(); | ||
170 | rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) | ||
171 | | (TRIMMER_SET_CMD)); | ||
172 | rtc_end_op(); | ||
173 | } | ||
174 | |||
175 | void ds1603_disable(void) | ||
176 | { | ||
177 | ds1603_set_trimmer(TRIMMER_DISABLE_RTC); | ||
178 | } | ||
179 | |||
180 | void ds1603_enable(void) | ||
181 | { | ||
182 | ds1603_set_trimmer(TRIMMER_DEFAULT); | ||
183 | } | ||
diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h new file mode 100644 index 000000000000..c2e5c76a379d --- /dev/null +++ b/arch/mips/lasat/ds1603.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Dallas Semiconductors 1603 RTC driver | ||
3 | * | ||
4 | * Brian Murphy <brian@murphy.dk> | ||
5 | * | ||
6 | */ | ||
7 | #ifndef __DS1603_H | ||
8 | #define __DS1603_H | ||
9 | |||
10 | struct ds_defs { | ||
11 | volatile u32 *reg; | ||
12 | volatile u32 *data_reg; | ||
13 | u32 rst; | ||
14 | u32 clk; | ||
15 | u32 data; | ||
16 | u32 data_read_shift; | ||
17 | char data_reversed; | ||
18 | u32 huge_delay; | ||
19 | }; | ||
20 | |||
21 | extern struct ds_defs *ds1603; | ||
22 | |||
23 | unsigned long ds1603_read(void); | ||
24 | int ds1603_set(unsigned long); | ||
25 | void ds1603_set_trimmer(unsigned int); | ||
26 | void ds1603_enable(void); | ||
27 | void ds1603_disable(void); | ||
28 | void ds1603_init(struct ds_defs *); | ||
29 | |||
30 | #define TRIMMER_DEFAULT 3 | ||
31 | #define TRIMMER_DISABLE_RTC 0 | ||
32 | |||
33 | #endif | ||
diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile new file mode 100644 index 000000000000..5332449ec040 --- /dev/null +++ b/arch/mips/lasat/image/Makefile | |||
@@ -0,0 +1,54 @@ | |||
1 | # | ||
2 | # MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER | ||
3 | # | ||
4 | # i-data Networks | ||
5 | # | ||
6 | # Author: Thomas Horsten <thh@i-data.com> | ||
7 | # | ||
8 | |||
9 | ifndef Version | ||
10 | Version = "$(USER)-test" | ||
11 | endif | ||
12 | |||
13 | MKLASATIMG = mklasatimg | ||
14 | MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 | ||
15 | KERNEL_IMAGE = $(TOPDIR)/vmlinux | ||
16 | KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ ) | ||
17 | KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) | ||
18 | |||
19 | LDSCRIPT= -L$(obj) -Tromscript.normal | ||
20 | |||
21 | HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ | ||
22 | -D_kernel_entry=0x$(KERNEL_ENTRY) \ | ||
23 | -D VERSION="\"$(Version)\"" \ | ||
24 | -D TIMESTAMP=$(shell date +%s) | ||
25 | |||
26 | $(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE) | ||
27 | $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $< | ||
28 | |||
29 | OBJECTS = head.o kImage.o | ||
30 | |||
31 | rom.sw: $(obj)/rom.sw | ||
32 | rom.bin: $(obj)/rom.bin | ||
33 | |||
34 | $(obj)/rom.sw: $(obj)/rom.bin | ||
35 | $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH) | ||
36 | |||
37 | $(obj)/rom.bin: $(obj)/rom | ||
38 | $(OBJCOPY) -O binary -S $^ $@ | ||
39 | |||
40 | # Rule to make the bootloader | ||
41 | $(obj)/rom: $(addprefix $(obj)/,$(OBJECTS)) | ||
42 | $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^ | ||
43 | |||
44 | $(obj)/%.o: $(obj)/%.gz | ||
45 | $(LD) -r -o $@ -b binary $< | ||
46 | |||
47 | $(obj)/%.gz: $(obj)/%.bin | ||
48 | gzip -cf -9 $< > $@ | ||
49 | |||
50 | $(obj)/kImage.bin: $(KERNEL_IMAGE) | ||
51 | $(OBJCOPY) -O binary -S $^ $@ | ||
52 | |||
53 | clean: | ||
54 | rm -f rom rom.bin rom.sw kImage.bin kImage.o | ||
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S new file mode 100644 index 000000000000..efb95f2609c2 --- /dev/null +++ b/arch/mips/lasat/image/head.S | |||
@@ -0,0 +1,31 @@ | |||
1 | #include <asm/lasat/head.h> | ||
2 | |||
3 | .text | ||
4 | .section .text.start, "ax" | ||
5 | .set noreorder | ||
6 | .set mips3 | ||
7 | |||
8 | /* Magic words identifying a software image */ | ||
9 | .word LASAT_K_MAGIC0_VAL | ||
10 | .word LASAT_K_MAGIC1_VAL | ||
11 | |||
12 | /* Image header version */ | ||
13 | .word 0x00000002 | ||
14 | |||
15 | /* image start and size */ | ||
16 | .word _image_start | ||
17 | .word _image_size | ||
18 | |||
19 | /* start of kernel and entrypoint in uncompressed image */ | ||
20 | .word _kernel_start | ||
21 | .word _kernel_entry | ||
22 | |||
23 | /* Here we have room for future flags */ | ||
24 | |||
25 | .org 0x40 | ||
26 | reldate: | ||
27 | .word TIMESTAMP | ||
28 | |||
29 | .org 0x50 | ||
30 | release: | ||
31 | .string VERSION | ||
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal new file mode 100644 index 000000000000..988f8ad189cb --- /dev/null +++ b/arch/mips/lasat/image/romscript.normal | |||
@@ -0,0 +1,23 @@ | |||
1 | OUTPUT_ARCH(mips) | ||
2 | |||
3 | SECTIONS | ||
4 | { | ||
5 | .text : | ||
6 | { | ||
7 | *(.text.start) | ||
8 | } | ||
9 | |||
10 | /* Data in ROM */ | ||
11 | |||
12 | .data ALIGN(0x10) : | ||
13 | { | ||
14 | *(.data) | ||
15 | } | ||
16 | _image_start = ADDR(.data); | ||
17 | _image_size = SIZEOF(.data); | ||
18 | |||
19 | .other : | ||
20 | { | ||
21 | *(.*) | ||
22 | } | ||
23 | } | ||
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c new file mode 100644 index 000000000000..5f35289bfff5 --- /dev/null +++ b/arch/mips/lasat/interrupt.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Routines for generic manipulation of the interrupts found on the | ||
19 | * Lasat boards. | ||
20 | */ | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/irq.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/kernel_stat.h> | ||
27 | |||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/lasat/lasatint.h> | ||
30 | #include <asm/time.h> | ||
31 | #include <asm/gdb-stub.h> | ||
32 | |||
33 | static volatile int *lasat_int_status; | ||
34 | static volatile int *lasat_int_mask; | ||
35 | static volatile int lasat_int_mask_shift; | ||
36 | |||
37 | void disable_lasat_irq(unsigned int irq_nr) | ||
38 | { | ||
39 | *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; | ||
40 | } | ||
41 | |||
42 | void enable_lasat_irq(unsigned int irq_nr) | ||
43 | { | ||
44 | *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; | ||
45 | } | ||
46 | |||
47 | static struct irq_chip lasat_irq_type = { | ||
48 | .name = "Lasat", | ||
49 | .ack = disable_lasat_irq, | ||
50 | .mask = disable_lasat_irq, | ||
51 | .mask_ack = disable_lasat_irq, | ||
52 | .unmask = enable_lasat_irq, | ||
53 | }; | ||
54 | |||
55 | static inline int ls1bit32(unsigned int x) | ||
56 | { | ||
57 | int b = 31, s; | ||
58 | |||
59 | s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; | ||
60 | s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; | ||
61 | s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; | ||
62 | s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; | ||
63 | s = 1; if (x << 1 == 0) s = 0; b -= s; | ||
64 | |||
65 | return b; | ||
66 | } | ||
67 | |||
68 | static unsigned long (*get_int_status)(void); | ||
69 | |||
70 | static unsigned long get_int_status_100(void) | ||
71 | { | ||
72 | return *lasat_int_status & *lasat_int_mask; | ||
73 | } | ||
74 | |||
75 | static unsigned long get_int_status_200(void) | ||
76 | { | ||
77 | unsigned long int_status; | ||
78 | |||
79 | int_status = *lasat_int_status; | ||
80 | int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; | ||
81 | return int_status; | ||
82 | } | ||
83 | |||
84 | asmlinkage void plat_irq_dispatch(void) | ||
85 | { | ||
86 | unsigned long int_status; | ||
87 | unsigned int cause = read_c0_cause(); | ||
88 | int irq; | ||
89 | |||
90 | if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ | ||
91 | ll_timer_interrupt(7); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | int_status = get_int_status(); | ||
96 | |||
97 | /* if int_status == 0, then the interrupt has already been cleared */ | ||
98 | if (int_status) { | ||
99 | irq = ls1bit32(int_status); | ||
100 | |||
101 | do_IRQ(irq); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void __init arch_init_irq(void) | ||
106 | { | ||
107 | int i; | ||
108 | |||
109 | switch (mips_machtype) { | ||
110 | case MACH_LASAT_100: | ||
111 | lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; | ||
112 | lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; | ||
113 | lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; | ||
114 | get_int_status = get_int_status_100; | ||
115 | *lasat_int_mask = 0; | ||
116 | break; | ||
117 | case MACH_LASAT_200: | ||
118 | lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; | ||
119 | lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; | ||
120 | lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; | ||
121 | get_int_status = get_int_status_200; | ||
122 | *lasat_int_mask &= 0xffff; | ||
123 | break; | ||
124 | default: | ||
125 | panic("arch_init_irq: mips_machtype incorrect"); | ||
126 | } | ||
127 | |||
128 | for (i = 0; i <= LASATINT_END; i++) | ||
129 | set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); | ||
130 | } | ||
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c new file mode 100644 index 000000000000..ec2f658c3709 --- /dev/null +++ b/arch/mips/lasat/lasat_board.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * Thomas Horsten <thh@lasat.com> | ||
3 | * Copyright (C) 2000 LASAT Networks A/S. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Routines specific to the LASAT boards | ||
19 | */ | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <asm/lasat/lasat.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/ctype.h> | ||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/addrspace.h> | ||
28 | #include "at93c.h" | ||
29 | /* New model description table */ | ||
30 | #include "lasat_models.h" | ||
31 | |||
32 | #define EEPROM_CRC(data, len) (~crc32(~0, data, len)) | ||
33 | |||
34 | struct lasat_info lasat_board_info; | ||
35 | |||
36 | void update_bcastaddr(void); | ||
37 | |||
38 | int EEPROMRead(unsigned int pos, unsigned char *data, int len) | ||
39 | { | ||
40 | int i; | ||
41 | |||
42 | for (i = 0; i < len; i++) | ||
43 | *data++ = at93c_read(pos++); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | int EEPROMWrite(unsigned int pos, unsigned char *data, int len) | ||
49 | { | ||
50 | int i; | ||
51 | |||
52 | for (i = 0; i < len; i++) | ||
53 | at93c_write(pos++, *data++); | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void init_flash_sizes(void) | ||
59 | { | ||
60 | unsigned long *lb = lasat_board_info.li_flashpart_base; | ||
61 | unsigned long *ls = lasat_board_info.li_flashpart_size; | ||
62 | int i; | ||
63 | |||
64 | ls[LASAT_MTD_BOOTLOADER] = 0x40000; | ||
65 | ls[LASAT_MTD_SERVICE] = 0xC0000; | ||
66 | ls[LASAT_MTD_NORMAL] = 0x100000; | ||
67 | |||
68 | if (mips_machtype == MACH_LASAT_100) { | ||
69 | lasat_board_info.li_flash_base = 0x1e000000; | ||
70 | |||
71 | lb[LASAT_MTD_BOOTLOADER] = 0x1e400000; | ||
72 | |||
73 | if (lasat_board_info.li_flash_size > 0x200000) { | ||
74 | ls[LASAT_MTD_CONFIG] = 0x100000; | ||
75 | ls[LASAT_MTD_FS] = 0x500000; | ||
76 | } | ||
77 | } else { | ||
78 | lasat_board_info.li_flash_base = 0x10000000; | ||
79 | |||
80 | if (lasat_board_info.li_flash_size < 0x1000000) { | ||
81 | lb[LASAT_MTD_BOOTLOADER] = 0x10000000; | ||
82 | ls[LASAT_MTD_CONFIG] = 0x100000; | ||
83 | if (lasat_board_info.li_flash_size >= 0x400000) | ||
84 | ls[LASAT_MTD_FS] = | ||
85 | lasat_board_info.li_flash_size - 0x300000; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | for (i = 1; i < LASAT_MTD_LAST; i++) | ||
90 | lb[i] = lb[i-1] + ls[i-1]; | ||
91 | } | ||
92 | |||
93 | int lasat_init_board_info(void) | ||
94 | { | ||
95 | int c; | ||
96 | unsigned long crc; | ||
97 | unsigned long cfg0, cfg1; | ||
98 | const struct product_info *ppi; | ||
99 | int i_n_base_models = N_BASE_MODELS; | ||
100 | const char * const * i_txt_base_models = txt_base_models; | ||
101 | int i_n_prids = N_PRIDS; | ||
102 | |||
103 | memset(&lasat_board_info, 0, sizeof(lasat_board_info)); | ||
104 | |||
105 | /* First read the EEPROM info */ | ||
106 | EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, | ||
107 | sizeof(struct lasat_eeprom_struct)); | ||
108 | |||
109 | /* Check the CRC */ | ||
110 | crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), | ||
111 | sizeof(struct lasat_eeprom_struct) - 4); | ||
112 | |||
113 | if (crc != lasat_board_info.li_eeprom_info.crc32) { | ||
114 | printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does " | ||
115 | "not match calculated, attempting to soldier on...\n"); | ||
116 | } | ||
117 | |||
118 | if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) { | ||
119 | printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version " | ||
120 | "%d, wanted version %d, attempting to soldier on...\n", | ||
121 | (unsigned int)lasat_board_info.li_eeprom_info.version, | ||
122 | LASAT_EEPROM_VERSION); | ||
123 | } | ||
124 | |||
125 | cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; | ||
126 | cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; | ||
127 | |||
128 | if (LASAT_W0_DSCTYPE(cfg0) != 1) { | ||
129 | printk(KERN_WARNING "WARNING...\nWARNING...\n" | ||
130 | "Invalid configuration read from EEPROM, attempting to " | ||
131 | "soldier on..."); | ||
132 | } | ||
133 | /* We have a valid configuration */ | ||
134 | |||
135 | switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { | ||
136 | case 0: | ||
137 | lasat_board_info.li_memsize = 0x0800000; | ||
138 | break; | ||
139 | case 1: | ||
140 | lasat_board_info.li_memsize = 0x1000000; | ||
141 | break; | ||
142 | case 2: | ||
143 | lasat_board_info.li_memsize = 0x2000000; | ||
144 | break; | ||
145 | case 3: | ||
146 | lasat_board_info.li_memsize = 0x4000000; | ||
147 | break; | ||
148 | case 4: | ||
149 | lasat_board_info.li_memsize = 0x8000000; | ||
150 | break; | ||
151 | default: | ||
152 | lasat_board_info.li_memsize = 0; | ||
153 | } | ||
154 | |||
155 | switch (LASAT_W0_SDRAMBANKS(cfg0)) { | ||
156 | case 0: | ||
157 | break; | ||
158 | case 1: | ||
159 | lasat_board_info.li_memsize *= 2; | ||
160 | break; | ||
161 | default: | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | switch (LASAT_W0_BUSSPEED(cfg0)) { | ||
166 | case 0x0: | ||
167 | lasat_board_info.li_bus_hz = 60000000; | ||
168 | break; | ||
169 | case 0x1: | ||
170 | lasat_board_info.li_bus_hz = 66000000; | ||
171 | break; | ||
172 | case 0x2: | ||
173 | lasat_board_info.li_bus_hz = 66666667; | ||
174 | break; | ||
175 | case 0x3: | ||
176 | lasat_board_info.li_bus_hz = 80000000; | ||
177 | break; | ||
178 | case 0x4: | ||
179 | lasat_board_info.li_bus_hz = 83333333; | ||
180 | break; | ||
181 | case 0x5: | ||
182 | lasat_board_info.li_bus_hz = 100000000; | ||
183 | break; | ||
184 | } | ||
185 | |||
186 | switch (LASAT_W0_CPUCLK(cfg0)) { | ||
187 | case 0x0: | ||
188 | lasat_board_info.li_cpu_hz = | ||
189 | lasat_board_info.li_bus_hz; | ||
190 | break; | ||
191 | case 0x1: | ||
192 | lasat_board_info.li_cpu_hz = | ||
193 | lasat_board_info.li_bus_hz + | ||
194 | (lasat_board_info.li_bus_hz >> 1); | ||
195 | break; | ||
196 | case 0x2: | ||
197 | lasat_board_info.li_cpu_hz = | ||
198 | lasat_board_info.li_bus_hz + | ||
199 | lasat_board_info.li_bus_hz; | ||
200 | break; | ||
201 | case 0x3: | ||
202 | lasat_board_info.li_cpu_hz = | ||
203 | lasat_board_info.li_bus_hz + | ||
204 | lasat_board_info.li_bus_hz + | ||
205 | (lasat_board_info.li_bus_hz >> 1); | ||
206 | break; | ||
207 | case 0x4: | ||
208 | lasat_board_info.li_cpu_hz = | ||
209 | lasat_board_info.li_bus_hz + | ||
210 | lasat_board_info.li_bus_hz + | ||
211 | lasat_board_info.li_bus_hz; | ||
212 | break; | ||
213 | } | ||
214 | |||
215 | /* Flash size */ | ||
216 | switch (LASAT_W1_FLASHSIZE(cfg1)) { | ||
217 | case 0: | ||
218 | lasat_board_info.li_flash_size = 0x200000; | ||
219 | break; | ||
220 | case 1: | ||
221 | lasat_board_info.li_flash_size = 0x400000; | ||
222 | break; | ||
223 | case 2: | ||
224 | lasat_board_info.li_flash_size = 0x800000; | ||
225 | break; | ||
226 | case 3: | ||
227 | lasat_board_info.li_flash_size = 0x1000000; | ||
228 | break; | ||
229 | case 4: | ||
230 | lasat_board_info.li_flash_size = 0x2000000; | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | init_flash_sizes(); | ||
235 | |||
236 | lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); | ||
237 | lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; | ||
238 | if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) | ||
239 | lasat_board_info.li_prid = lasat_board_info.li_bmid; | ||
240 | |||
241 | /* Base model stuff */ | ||
242 | if (lasat_board_info.li_bmid > i_n_base_models) | ||
243 | lasat_board_info.li_bmid = i_n_base_models; | ||
244 | strcpy(lasat_board_info.li_bmstr, | ||
245 | i_txt_base_models[lasat_board_info.li_bmid]); | ||
246 | |||
247 | /* Product ID dependent values */ | ||
248 | c = lasat_board_info.li_prid; | ||
249 | if (c >= i_n_prids) { | ||
250 | strcpy(lasat_board_info.li_namestr, "Unknown Model"); | ||
251 | strcpy(lasat_board_info.li_typestr, "Unknown Type"); | ||
252 | } else { | ||
253 | ppi = &vendor_info_table[0].vi_product_info[c]; | ||
254 | strcpy(lasat_board_info.li_namestr, ppi->pi_name); | ||
255 | if (ppi->pi_type) | ||
256 | strcpy(lasat_board_info.li_typestr, ppi->pi_type); | ||
257 | else | ||
258 | sprintf(lasat_board_info.li_typestr, "%d", 10 * c); | ||
259 | } | ||
260 | |||
261 | #if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) | ||
262 | update_bcastaddr(); | ||
263 | #endif | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | void lasat_write_eeprom_info(void) | ||
269 | { | ||
270 | unsigned long crc; | ||
271 | |||
272 | /* Generate the CRC */ | ||
273 | crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), | ||
274 | sizeof(struct lasat_eeprom_struct) - 4); | ||
275 | lasat_board_info.li_eeprom_info.crc32 = crc; | ||
276 | |||
277 | /* Write the EEPROM info */ | ||
278 | EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, | ||
279 | sizeof(struct lasat_eeprom_struct)); | ||
280 | } | ||
diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h new file mode 100644 index 000000000000..e1cbd26ae1b3 --- /dev/null +++ b/arch/mips/lasat/lasat_models.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Model description tables | ||
3 | */ | ||
4 | #include <linux/kernel.h> | ||
5 | |||
6 | struct product_info { | ||
7 | const char *pi_name; | ||
8 | const char *pi_type; | ||
9 | }; | ||
10 | |||
11 | struct vendor_info { | ||
12 | const char *vi_name; | ||
13 | const struct product_info *vi_product_info; | ||
14 | }; | ||
15 | |||
16 | /* | ||
17 | * Base models | ||
18 | */ | ||
19 | static const char * const txt_base_models[] = { | ||
20 | "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", | ||
21 | "SP 1000", "Unknown" | ||
22 | }; | ||
23 | #define N_BASE_MODELS (ARRAY_SIZE(txt_base_models) - 1) | ||
24 | |||
25 | /* | ||
26 | * Eicon Networks | ||
27 | */ | ||
28 | static const char txt_en_mq[] = "Masquerade"; | ||
29 | static const char txt_en_sp[] = "Safepipe"; | ||
30 | |||
31 | static const struct product_info product_info_eicon[] = { | ||
32 | { txt_en_mq, "II" }, /* 0 */ | ||
33 | { txt_en_mq, "Pro" }, /* 1 */ | ||
34 | { txt_en_sp, "25" }, /* 2 */ | ||
35 | { txt_en_sp, "50" }, /* 3 */ | ||
36 | { txt_en_sp, "100" }, /* 4 */ | ||
37 | { txt_en_sp, "5000" }, /* 5 */ | ||
38 | { txt_en_sp, "7000" }, /* 6 */ | ||
39 | { txt_en_sp, "30" }, /* 7 */ | ||
40 | { txt_en_sp, "5100" }, /* 8 */ | ||
41 | { txt_en_sp, "7100" }, /* 9 */ | ||
42 | { txt_en_sp, "1110" }, /* 10 */ | ||
43 | { txt_en_sp, "3020" }, /* 11 */ | ||
44 | { txt_en_sp, "3030" }, /* 12 */ | ||
45 | { txt_en_sp, "5020" }, /* 13 */ | ||
46 | { txt_en_sp, "5030" }, /* 14 */ | ||
47 | { txt_en_sp, "1120" }, /* 15 */ | ||
48 | { txt_en_sp, "1130" }, /* 16 */ | ||
49 | { txt_en_sp, "6010" }, /* 17 */ | ||
50 | { txt_en_sp, "6110" }, /* 18 */ | ||
51 | { txt_en_sp, "6210" }, /* 19 */ | ||
52 | { txt_en_sp, "1020" }, /* 20 */ | ||
53 | { txt_en_sp, "1040" }, /* 21 */ | ||
54 | { txt_en_sp, "1050" }, /* 22 */ | ||
55 | { txt_en_sp, "1060" }, /* 23 */ | ||
56 | }; | ||
57 | |||
58 | #define N_PRIDS ARRAY_SIZE(product_info_eicon) | ||
59 | |||
60 | /* | ||
61 | * The vendor table | ||
62 | */ | ||
63 | static struct vendor_info const vendor_info_table[] = { | ||
64 | { "Eicon Networks", product_info_eicon }, | ||
65 | }; | ||
66 | |||
67 | #define N_VENDORS ARRAY_SIZE(vendor_info_table) | ||
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c new file mode 100644 index 000000000000..6471d0663fd8 --- /dev/null +++ b/arch/mips/lasat/picvue.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * Picvue PVC160206 display driver | ||
3 | * | ||
4 | * Brian Murphy <brian@murphy.dk> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <asm/bootinfo.h> | ||
10 | #include <asm/lasat/lasat.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/string.h> | ||
15 | |||
16 | #include "picvue.h" | ||
17 | |||
18 | #define PVC_BUSY 0x80 | ||
19 | #define PVC_NLINES 2 | ||
20 | #define PVC_DISPMEM 80 | ||
21 | #define PVC_LINELEN PVC_DISPMEM / PVC_NLINES | ||
22 | |||
23 | struct pvc_defs *picvue; | ||
24 | |||
25 | DECLARE_MUTEX(pvc_sem); | ||
26 | |||
27 | static void pvc_reg_write(u32 val) | ||
28 | { | ||
29 | *picvue->reg = val; | ||
30 | } | ||
31 | |||
32 | static u32 pvc_reg_read(void) | ||
33 | { | ||
34 | u32 tmp = *picvue->reg; | ||
35 | return tmp; | ||
36 | } | ||
37 | |||
38 | static void pvc_write_byte(u32 data, u8 byte) | ||
39 | { | ||
40 | data |= picvue->e; | ||
41 | pvc_reg_write(data); | ||
42 | data &= ~picvue->data_mask; | ||
43 | data |= byte << picvue->data_shift; | ||
44 | pvc_reg_write(data); | ||
45 | ndelay(220); | ||
46 | pvc_reg_write(data & ~picvue->e); | ||
47 | ndelay(220); | ||
48 | } | ||
49 | |||
50 | static u8 pvc_read_byte(u32 data) | ||
51 | { | ||
52 | u8 byte; | ||
53 | |||
54 | data |= picvue->e; | ||
55 | pvc_reg_write(data); | ||
56 | ndelay(220); | ||
57 | byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; | ||
58 | data &= ~picvue->e; | ||
59 | pvc_reg_write(data); | ||
60 | ndelay(220); | ||
61 | return byte; | ||
62 | } | ||
63 | |||
64 | static u8 pvc_read_data(void) | ||
65 | { | ||
66 | u32 data = pvc_reg_read(); | ||
67 | u8 byte; | ||
68 | data |= picvue->rw; | ||
69 | data &= ~picvue->rs; | ||
70 | pvc_reg_write(data); | ||
71 | ndelay(40); | ||
72 | byte = pvc_read_byte(data); | ||
73 | data |= picvue->rs; | ||
74 | pvc_reg_write(data); | ||
75 | return byte; | ||
76 | } | ||
77 | |||
78 | #define TIMEOUT 1000 | ||
79 | static int pvc_wait(void) | ||
80 | { | ||
81 | int i = TIMEOUT; | ||
82 | int err = 0; | ||
83 | |||
84 | while ((pvc_read_data() & PVC_BUSY) && i) | ||
85 | i--; | ||
86 | if (i == 0) | ||
87 | err = -ETIME; | ||
88 | |||
89 | return err; | ||
90 | } | ||
91 | |||
92 | #define MODE_INST 0 | ||
93 | #define MODE_DATA 1 | ||
94 | static void pvc_write(u8 byte, int mode) | ||
95 | { | ||
96 | u32 data = pvc_reg_read(); | ||
97 | data &= ~picvue->rw; | ||
98 | if (mode == MODE_DATA) | ||
99 | data |= picvue->rs; | ||
100 | else | ||
101 | data &= ~picvue->rs; | ||
102 | pvc_reg_write(data); | ||
103 | ndelay(40); | ||
104 | pvc_write_byte(data, byte); | ||
105 | if (mode == MODE_DATA) | ||
106 | data &= ~picvue->rs; | ||
107 | else | ||
108 | data |= picvue->rs; | ||
109 | pvc_reg_write(data); | ||
110 | pvc_wait(); | ||
111 | } | ||
112 | |||
113 | void pvc_write_string(const unsigned char *str, u8 addr, int line) | ||
114 | { | ||
115 | int i = 0; | ||
116 | |||
117 | if (line > 0 && (PVC_NLINES > 1)) | ||
118 | addr += 0x40 * line; | ||
119 | pvc_write(0x80 | addr, MODE_INST); | ||
120 | |||
121 | while (*str != 0 && i < PVC_LINELEN) { | ||
122 | pvc_write(*str++, MODE_DATA); | ||
123 | i++; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | void pvc_write_string_centered(const unsigned char *str, int line) | ||
128 | { | ||
129 | int len = strlen(str); | ||
130 | u8 addr; | ||
131 | |||
132 | if (len > PVC_VISIBLE_CHARS) | ||
133 | addr = 0; | ||
134 | else | ||
135 | addr = (PVC_VISIBLE_CHARS - strlen(str))/2; | ||
136 | |||
137 | pvc_write_string(str, addr, line); | ||
138 | } | ||
139 | |||
140 | void pvc_dump_string(const unsigned char *str) | ||
141 | { | ||
142 | int len = strlen(str); | ||
143 | |||
144 | pvc_write_string(str, 0, 0); | ||
145 | if (len > PVC_VISIBLE_CHARS) | ||
146 | pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); | ||
147 | } | ||
148 | |||
149 | #define BM_SIZE 8 | ||
150 | #define MAX_PROGRAMMABLE_CHARS 8 | ||
151 | int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) | ||
152 | { | ||
153 | int i; | ||
154 | int addr; | ||
155 | |||
156 | if (charnum > MAX_PROGRAMMABLE_CHARS) | ||
157 | return -ENOENT; | ||
158 | |||
159 | addr = charnum * 8; | ||
160 | pvc_write(0x40 | addr, MODE_INST); | ||
161 | |||
162 | for (i = 0; i < BM_SIZE; i++) | ||
163 | pvc_write(bitmap[i], MODE_DATA); | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | #define FUNC_SET_CMD 0x20 | ||
168 | #define EIGHT_BYTE (1 << 4) | ||
169 | #define FOUR_BYTE 0 | ||
170 | #define TWO_LINES (1 << 3) | ||
171 | #define ONE_LINE 0 | ||
172 | #define LARGE_FONT (1 << 2) | ||
173 | #define SMALL_FONT 0 | ||
174 | |||
175 | static void pvc_funcset(u8 cmd) | ||
176 | { | ||
177 | pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), | ||
178 | MODE_INST); | ||
179 | } | ||
180 | |||
181 | #define ENTRYMODE_CMD 0x4 | ||
182 | #define AUTO_INC (1 << 1) | ||
183 | #define AUTO_DEC 0 | ||
184 | #define CURSOR_FOLLOWS_DISP (1 << 0) | ||
185 | |||
186 | static void pvc_entrymode(u8 cmd) | ||
187 | { | ||
188 | pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), | ||
189 | MODE_INST); | ||
190 | } | ||
191 | |||
192 | #define DISP_CNT_CMD 0x08 | ||
193 | #define DISP_OFF 0 | ||
194 | #define DISP_ON (1 << 2) | ||
195 | #define CUR_ON (1 << 1) | ||
196 | #define CUR_BLINK (1 << 0) | ||
197 | void pvc_dispcnt(u8 cmd) | ||
198 | { | ||
199 | pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST); | ||
200 | } | ||
201 | |||
202 | #define MOVE_CMD 0x10 | ||
203 | #define DISPLAY (1 << 3) | ||
204 | #define CURSOR 0 | ||
205 | #define RIGHT (1 << 2) | ||
206 | #define LEFT 0 | ||
207 | void pvc_move(u8 cmd) | ||
208 | { | ||
209 | pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST); | ||
210 | } | ||
211 | |||
212 | #define CLEAR_CMD 0x1 | ||
213 | void pvc_clear(void) | ||
214 | { | ||
215 | pvc_write(CLEAR_CMD, MODE_INST); | ||
216 | } | ||
217 | |||
218 | #define HOME_CMD 0x2 | ||
219 | void pvc_home(void) | ||
220 | { | ||
221 | pvc_write(HOME_CMD, MODE_INST); | ||
222 | } | ||
223 | |||
224 | int pvc_init(void) | ||
225 | { | ||
226 | u8 cmd = EIGHT_BYTE; | ||
227 | |||
228 | if (PVC_NLINES == 2) | ||
229 | cmd |= (SMALL_FONT|TWO_LINES); | ||
230 | else | ||
231 | cmd |= (LARGE_FONT|ONE_LINE); | ||
232 | pvc_funcset(cmd); | ||
233 | pvc_dispcnt(DISP_ON); | ||
234 | pvc_entrymode(AUTO_INC); | ||
235 | |||
236 | pvc_clear(); | ||
237 | pvc_write_string_centered("Display", 0); | ||
238 | pvc_write_string_centered("Initialized", 1); | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | module_init(pvc_init); | ||
244 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h new file mode 100644 index 000000000000..2a96bf971897 --- /dev/null +++ b/arch/mips/lasat/picvue.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Picvue PVC160206 display driver | ||
3 | * | ||
4 | * Brian Murphy <brian.murphy@eicon.com> | ||
5 | * | ||
6 | */ | ||
7 | #include <asm/semaphore.h> | ||
8 | |||
9 | struct pvc_defs { | ||
10 | volatile u32 *reg; | ||
11 | u32 data_shift; | ||
12 | u32 data_mask; | ||
13 | u32 e; | ||
14 | u32 rw; | ||
15 | u32 rs; | ||
16 | }; | ||
17 | |||
18 | extern struct pvc_defs *picvue; | ||
19 | |||
20 | #define PVC_NLINES 2 | ||
21 | #define PVC_DISPMEM 80 | ||
22 | #define PVC_LINELEN PVC_DISPMEM / PVC_NLINES | ||
23 | #define PVC_VISIBLE_CHARS 16 | ||
24 | |||
25 | void pvc_write_string(const unsigned char *str, u8 addr, int line); | ||
26 | void pvc_write_string_centered(const unsigned char *str, int line); | ||
27 | void pvc_dump_string(const unsigned char *str); | ||
28 | |||
29 | #define BM_SIZE 8 | ||
30 | #define MAX_PROGRAMMABLE_CHARS 8 | ||
31 | int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); | ||
32 | |||
33 | void pvc_dispcnt(u8 cmd); | ||
34 | #define DISP_OFF 0 | ||
35 | #define DISP_ON (1 << 2) | ||
36 | #define CUR_ON (1 << 1) | ||
37 | #define CUR_BLINK (1 << 0) | ||
38 | |||
39 | void pvc_move(u8 cmd); | ||
40 | #define DISPLAY (1 << 3) | ||
41 | #define CURSOR 0 | ||
42 | #define RIGHT (1 << 2) | ||
43 | #define LEFT 0 | ||
44 | |||
45 | void pvc_clear(void); | ||
46 | void pvc_home(void); | ||
47 | |||
48 | extern struct semaphore pvc_sem; | ||
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c new file mode 100644 index 000000000000..9947c1525822 --- /dev/null +++ b/arch/mips/lasat/picvue_proc.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * Picvue PVC160206 display driver | ||
3 | * | ||
4 | * Brian Murphy <brian.murphy@eicon.com> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/errno.h> | ||
11 | |||
12 | #include <linux/proc_fs.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | |||
15 | #include <linux/timer.h> | ||
16 | |||
17 | #include "picvue.h" | ||
18 | |||
19 | static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; | ||
20 | static int pvc_linedata[PVC_NLINES]; | ||
21 | static struct proc_dir_entry *pvc_display_dir; | ||
22 | static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; | ||
23 | #define DISPLAY_DIR_NAME "display" | ||
24 | static int scroll_dir, scroll_interval; | ||
25 | |||
26 | static struct timer_list timer; | ||
27 | |||
28 | static void pvc_display(unsigned long data) | ||
29 | { | ||
30 | int i; | ||
31 | |||
32 | pvc_clear(); | ||
33 | for (i = 0; i < PVC_NLINES; i++) | ||
34 | pvc_write_string(pvc_lines[i], 0, i); | ||
35 | } | ||
36 | |||
37 | static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0); | ||
38 | |||
39 | static int pvc_proc_read_line(char *page, char **start, | ||
40 | off_t off, int count, | ||
41 | int *eof, void *data) | ||
42 | { | ||
43 | char *origpage = page; | ||
44 | int lineno = *(int *)data; | ||
45 | |||
46 | if (lineno < 0 || lineno > PVC_NLINES) { | ||
47 | printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | down(&pvc_sem); | ||
52 | page += sprintf(page, "%s\n", pvc_lines[lineno]); | ||
53 | up(&pvc_sem); | ||
54 | |||
55 | return page - origpage; | ||
56 | } | ||
57 | |||
58 | static int pvc_proc_write_line(struct file *file, const char *buffer, | ||
59 | unsigned long count, void *data) | ||
60 | { | ||
61 | int origcount = count; | ||
62 | int lineno = *(int *)data; | ||
63 | |||
64 | if (lineno < 0 || lineno > PVC_NLINES) { | ||
65 | printk(KERN_WARNING "proc_write_line: invalid lineno %d\n", | ||
66 | lineno); | ||
67 | return origcount; | ||
68 | } | ||
69 | |||
70 | if (count > PVC_LINELEN) | ||
71 | count = PVC_LINELEN; | ||
72 | |||
73 | if (buffer[count-1] == '\n') | ||
74 | count--; | ||
75 | |||
76 | down(&pvc_sem); | ||
77 | strncpy(pvc_lines[lineno], buffer, count); | ||
78 | pvc_lines[lineno][count] = '\0'; | ||
79 | up(&pvc_sem); | ||
80 | |||
81 | tasklet_schedule(&pvc_display_tasklet); | ||
82 | |||
83 | return origcount; | ||
84 | } | ||
85 | |||
86 | static int pvc_proc_write_scroll(struct file *file, const char *buffer, | ||
87 | unsigned long count, void *data) | ||
88 | { | ||
89 | int origcount = count; | ||
90 | int cmd = simple_strtol(buffer, NULL, 10); | ||
91 | |||
92 | down(&pvc_sem); | ||
93 | if (scroll_interval != 0) | ||
94 | del_timer(&timer); | ||
95 | |||
96 | if (cmd == 0) { | ||
97 | scroll_dir = 0; | ||
98 | scroll_interval = 0; | ||
99 | } else { | ||
100 | if (cmd < 0) { | ||
101 | scroll_dir = -1; | ||
102 | scroll_interval = -cmd; | ||
103 | } else { | ||
104 | scroll_dir = 1; | ||
105 | scroll_interval = cmd; | ||
106 | } | ||
107 | add_timer(&timer); | ||
108 | } | ||
109 | up(&pvc_sem); | ||
110 | |||
111 | return origcount; | ||
112 | } | ||
113 | |||
114 | static int pvc_proc_read_scroll(char *page, char **start, | ||
115 | off_t off, int count, | ||
116 | int *eof, void *data) | ||
117 | { | ||
118 | char *origpage = page; | ||
119 | |||
120 | down(&pvc_sem); | ||
121 | page += sprintf(page, "%d\n", scroll_dir * scroll_interval); | ||
122 | up(&pvc_sem); | ||
123 | |||
124 | return page - origpage; | ||
125 | } | ||
126 | |||
127 | |||
128 | void pvc_proc_timerfunc(unsigned long data) | ||
129 | { | ||
130 | if (scroll_dir < 0) | ||
131 | pvc_move(DISPLAY|RIGHT); | ||
132 | else if (scroll_dir > 0) | ||
133 | pvc_move(DISPLAY|LEFT); | ||
134 | |||
135 | timer.expires = jiffies + scroll_interval; | ||
136 | add_timer(&timer); | ||
137 | } | ||
138 | |||
139 | static void pvc_proc_cleanup(void) | ||
140 | { | ||
141 | int i; | ||
142 | for (i = 0; i < PVC_NLINES; i++) | ||
143 | remove_proc_entry(pvc_linename[i], pvc_display_dir); | ||
144 | remove_proc_entry("scroll", pvc_display_dir); | ||
145 | remove_proc_entry(DISPLAY_DIR_NAME, NULL); | ||
146 | |||
147 | del_timer(&timer); | ||
148 | } | ||
149 | |||
150 | static int __init pvc_proc_init(void) | ||
151 | { | ||
152 | struct proc_dir_entry *proc_entry; | ||
153 | int i; | ||
154 | |||
155 | pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL); | ||
156 | if (pvc_display_dir == NULL) | ||
157 | goto error; | ||
158 | |||
159 | for (i = 0; i < PVC_NLINES; i++) { | ||
160 | strcpy(pvc_lines[i], ""); | ||
161 | pvc_linedata[i] = i; | ||
162 | } | ||
163 | for (i = 0; i < PVC_NLINES; i++) { | ||
164 | proc_entry = create_proc_entry(pvc_linename[i], 0644, | ||
165 | pvc_display_dir); | ||
166 | if (proc_entry == NULL) | ||
167 | goto error; | ||
168 | |||
169 | proc_entry->read_proc = pvc_proc_read_line; | ||
170 | proc_entry->write_proc = pvc_proc_write_line; | ||
171 | proc_entry->data = &pvc_linedata[i]; | ||
172 | } | ||
173 | proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); | ||
174 | if (proc_entry == NULL) | ||
175 | goto error; | ||
176 | |||
177 | proc_entry->write_proc = pvc_proc_write_scroll; | ||
178 | proc_entry->read_proc = pvc_proc_read_scroll; | ||
179 | |||
180 | init_timer(&timer); | ||
181 | timer.function = pvc_proc_timerfunc; | ||
182 | |||
183 | return 0; | ||
184 | error: | ||
185 | pvc_proc_cleanup(); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | module_init(pvc_proc_init); | ||
190 | module_exit(pvc_proc_cleanup); | ||
191 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c new file mode 100644 index 000000000000..4b80fffcf262 --- /dev/null +++ b/arch/mips/lasat/prom.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * PROM interface routines. | ||
3 | */ | ||
4 | #include <linux/types.h> | ||
5 | #include <linux/init.h> | ||
6 | #include <linux/string.h> | ||
7 | #include <linux/ctype.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/bootmem.h> | ||
11 | #include <linux/ioport.h> | ||
12 | #include <asm/bootinfo.h> | ||
13 | #include <asm/lasat/lasat.h> | ||
14 | #include <asm/cpu.h> | ||
15 | |||
16 | #include "at93c.h" | ||
17 | #include <asm/lasat/eeprom.h> | ||
18 | #include "prom.h" | ||
19 | |||
20 | #define RESET_VECTOR 0xbfc00000 | ||
21 | #define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) | ||
22 | #define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) | ||
23 | #define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) | ||
24 | #define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) | ||
25 | |||
26 | static void null_prom_display(const char *string, int pos, int clear) | ||
27 | { | ||
28 | } | ||
29 | |||
30 | static void null_prom_monitor(void) | ||
31 | { | ||
32 | } | ||
33 | |||
34 | static void null_prom_putc(char c) | ||
35 | { | ||
36 | } | ||
37 | |||
38 | /* these are functions provided by the bootloader */ | ||
39 | static void (*__prom_putc)(char c) = null_prom_putc; | ||
40 | |||
41 | void prom_putchar(char c) | ||
42 | { | ||
43 | __prom_putc(c); | ||
44 | } | ||
45 | |||
46 | void (*prom_display)(const char *string, int pos, int clear) = | ||
47 | null_prom_display; | ||
48 | void (*prom_monitor)(void) = null_prom_monitor; | ||
49 | |||
50 | unsigned int lasat_ndelay_divider; | ||
51 | |||
52 | static void setup_prom_vectors(void) | ||
53 | { | ||
54 | u32 version = *(u32 *)(RESET_VECTOR + 0x90); | ||
55 | |||
56 | if (version >= 307) { | ||
57 | prom_display = (void *)PROM_DISPLAY_ADDR; | ||
58 | __prom_putc = (void *)PROM_PUTC_ADDR; | ||
59 | prom_monitor = (void *)PROM_MONITOR_ADDR; | ||
60 | } | ||
61 | printk(KERN_DEBUG "prom vectors set up\n"); | ||
62 | } | ||
63 | |||
64 | static struct at93c_defs at93c_defs[N_MACHTYPES] = { | ||
65 | { | ||
66 | .reg = (void *)AT93C_REG_100, | ||
67 | .rdata_reg = (void *)AT93C_RDATA_REG_100, | ||
68 | .rdata_shift = AT93C_RDATA_SHIFT_100, | ||
69 | .wdata_shift = AT93C_WDATA_SHIFT_100, | ||
70 | .cs = AT93C_CS_M_100, | ||
71 | .clk = AT93C_CLK_M_100 | ||
72 | }, { | ||
73 | .reg = (void *)AT93C_REG_200, | ||
74 | .rdata_reg = (void *)AT93C_RDATA_REG_200, | ||
75 | .rdata_shift = AT93C_RDATA_SHIFT_200, | ||
76 | .wdata_shift = AT93C_WDATA_SHIFT_200, | ||
77 | .cs = AT93C_CS_M_200, | ||
78 | .clk = AT93C_CLK_M_200 | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | void __init prom_init(void) | ||
83 | { | ||
84 | int argc = fw_arg0; | ||
85 | char **argv = (char **) fw_arg1; | ||
86 | |||
87 | setup_prom_vectors(); | ||
88 | |||
89 | if (current_cpu_data.cputype == CPU_R5000) { | ||
90 | printk(KERN_INFO "LASAT 200 board\n"); | ||
91 | mips_machtype = MACH_LASAT_200; | ||
92 | lasat_ndelay_divider = LASAT_200_DIVIDER; | ||
93 | } else { | ||
94 | printk(KERN_INFO "LASAT 100 board\n"); | ||
95 | mips_machtype = MACH_LASAT_100; | ||
96 | lasat_ndelay_divider = LASAT_100_DIVIDER; | ||
97 | } | ||
98 | |||
99 | at93c = &at93c_defs[mips_machtype]; | ||
100 | |||
101 | lasat_init_board_info(); /* Read info from EEPROM */ | ||
102 | |||
103 | mips_machgroup = MACH_GROUP_LASAT; | ||
104 | |||
105 | /* Get the command line */ | ||
106 | if (argc > 0) { | ||
107 | strncpy(arcs_cmdline, argv[0], CL_SIZE-1); | ||
108 | arcs_cmdline[CL_SIZE-1] = '\0'; | ||
109 | } | ||
110 | |||
111 | /* Set the I/O base address */ | ||
112 | set_io_port_base(KSEG1); | ||
113 | |||
114 | /* Set memory regions */ | ||
115 | ioport_resource.start = 0; | ||
116 | ioport_resource.end = 0xffffffff; /* Wrong, fixme. */ | ||
117 | |||
118 | add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); | ||
119 | } | ||
120 | |||
121 | void __init prom_free_prom_memory(void) | ||
122 | { | ||
123 | } | ||
124 | |||
125 | const char *get_system_type(void) | ||
126 | { | ||
127 | return lasat_board_info.li_bmstr; | ||
128 | } | ||
diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h new file mode 100644 index 000000000000..337acbc27442 --- /dev/null +++ b/arch/mips/lasat/prom.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __PROM_H | ||
2 | #define __PROM_H | ||
3 | |||
4 | extern void (*prom_display)(const char *string, int pos, int clear); | ||
5 | extern void (*prom_monitor)(void); | ||
6 | |||
7 | #endif /* __PROM_H */ | ||
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c new file mode 100644 index 000000000000..b1e7a89fb730 --- /dev/null +++ b/arch/mips/lasat/reset.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Thomas Horsten <thh@lasat.com> | ||
3 | * Copyright (C) 2000 LASAT Networks A/S. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Reset the LASAT board. | ||
19 | */ | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/pm.h> | ||
22 | |||
23 | #include <asm/reboot.h> | ||
24 | #include <asm/system.h> | ||
25 | #include <asm/lasat/lasat.h> | ||
26 | |||
27 | #include "picvue.h" | ||
28 | #include "prom.h" | ||
29 | |||
30 | static void lasat_machine_restart(char *command); | ||
31 | static void lasat_machine_halt(void); | ||
32 | |||
33 | /* Used to set machine to boot in service mode via /proc interface */ | ||
34 | int lasat_boot_to_service; | ||
35 | |||
36 | static void lasat_machine_restart(char *command) | ||
37 | { | ||
38 | local_irq_disable(); | ||
39 | |||
40 | if (lasat_boot_to_service) { | ||
41 | *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; | ||
42 | *(volatile unsigned int *)0xa00000fc = 0xfedeabba; | ||
43 | } | ||
44 | *lasat_misc->reset_reg = 0xbedead; | ||
45 | for (;;) ; | ||
46 | } | ||
47 | |||
48 | static void lasat_machine_halt(void) | ||
49 | { | ||
50 | local_irq_disable(); | ||
51 | |||
52 | prom_monitor(); | ||
53 | for (;;) ; | ||
54 | } | ||
55 | |||
56 | void lasat_reboot_setup(void) | ||
57 | { | ||
58 | _machine_restart = lasat_machine_restart; | ||
59 | _machine_halt = lasat_machine_halt; | ||
60 | pm_power_off = lasat_machine_halt; | ||
61 | } | ||
diff --git a/arch/mips/lasat/serial.c b/arch/mips/lasat/serial.c new file mode 100644 index 000000000000..205bd397d75b --- /dev/null +++ b/arch/mips/lasat/serial.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Registration of Lasat UART platform device. | ||
3 | * | ||
4 | * Copyright (C) 2007 Brian Murphy <brian@murphy.dk> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | |||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/lasat/lasat.h> | ||
28 | #include <asm/lasat/serial.h> | ||
29 | |||
30 | static struct resource lasat_serial_res[2] __initdata; | ||
31 | |||
32 | static struct plat_serial8250_port lasat_serial8250_port[] = { | ||
33 | { | ||
34 | .iotype = UPIO_MEM, | ||
35 | .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | | ||
36 | UPF_SKIP_TEST, | ||
37 | }, | ||
38 | {}, | ||
39 | }; | ||
40 | |||
41 | static __init int lasat_uart_add(void) | ||
42 | { | ||
43 | struct platform_device *pdev; | ||
44 | int retval; | ||
45 | |||
46 | pdev = platform_device_alloc("serial8250", -1); | ||
47 | if (!pdev) | ||
48 | return -ENOMEM; | ||
49 | |||
50 | if (mips_machtype == MACH_LASAT_100) { | ||
51 | lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_100); | ||
52 | lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_100 * 8 - 1; | ||
53 | lasat_serial_res[0].flags = IORESOURCE_MEM; | ||
54 | lasat_serial_res[1].start = LASATINT_UART_100; | ||
55 | lasat_serial_res[1].end = LASATINT_UART_100; | ||
56 | lasat_serial_res[1].flags = IORESOURCE_IRQ; | ||
57 | |||
58 | lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_100; | ||
59 | lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_100 * 16; | ||
60 | lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_100; | ||
61 | lasat_serial8250_port[0].irq = LASATINT_UART_100; | ||
62 | } else { | ||
63 | lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_200); | ||
64 | lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_200 * 8 - 1; | ||
65 | lasat_serial_res[0].flags = IORESOURCE_MEM; | ||
66 | lasat_serial_res[1].start = LASATINT_UART_200; | ||
67 | lasat_serial_res[1].end = LASATINT_UART_200; | ||
68 | lasat_serial_res[1].flags = IORESOURCE_IRQ; | ||
69 | |||
70 | lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_200; | ||
71 | lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_200 * 16; | ||
72 | lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_200; | ||
73 | lasat_serial8250_port[0].irq = LASATINT_UART_200; | ||
74 | } | ||
75 | |||
76 | pdev->id = PLAT8250_DEV_PLATFORM; | ||
77 | pdev->dev.platform_data = lasat_serial8250_port; | ||
78 | |||
79 | retval = platform_device_add_resources(pdev, lasat_serial_res, ARRAY_SIZE(lasat_serial_res)); | ||
80 | if (retval) | ||
81 | goto err_free_device; | ||
82 | |||
83 | retval = platform_device_add(pdev); | ||
84 | if (retval) | ||
85 | goto err_free_device; | ||
86 | |||
87 | return 0; | ||
88 | |||
89 | err_free_device: | ||
90 | platform_device_put(pdev); | ||
91 | |||
92 | return retval; | ||
93 | } | ||
94 | device_initcall(lasat_uart_add); | ||
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c new file mode 100644 index 000000000000..187e37821d93 --- /dev/null +++ b/arch/mips/lasat/setup.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * Thomas Horsten <thh@lasat.com> | ||
6 | * Copyright (C) 2000 LASAT Networks A/S. | ||
7 | * | ||
8 | * Brian Murphy <brian@murphy.dk> | ||
9 | * | ||
10 | * This program is free software; you can distribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License (Version 2) as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
17 | * for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
22 | * | ||
23 | * Lasat specific setup. | ||
24 | */ | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/pci.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/tty.h> | ||
30 | |||
31 | #include <asm/time.h> | ||
32 | #include <asm/cpu.h> | ||
33 | #include <asm/bootinfo.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/lasat/lasat.h> | ||
36 | #include <asm/lasat/serial.h> | ||
37 | |||
38 | #ifdef CONFIG_PICVUE | ||
39 | #include <linux/notifier.h> | ||
40 | #endif | ||
41 | |||
42 | #include "ds1603.h" | ||
43 | #include <asm/lasat/ds1603.h> | ||
44 | #include <asm/lasat/picvue.h> | ||
45 | #include <asm/lasat/eeprom.h> | ||
46 | |||
47 | #include "prom.h" | ||
48 | |||
49 | int lasat_command_line; | ||
50 | void lasatint_init(void); | ||
51 | |||
52 | extern void lasat_reboot_setup(void); | ||
53 | extern void pcisetup(void); | ||
54 | extern void edhac_init(void *, void *, void *); | ||
55 | extern void addrflt_init(void); | ||
56 | |||
57 | struct lasat_misc lasat_misc_info[N_MACHTYPES] = { | ||
58 | { | ||
59 | .reset_reg = (void *)KSEG1ADDR(0x1c840000), | ||
60 | .flash_wp_reg = (void *)KSEG1ADDR(0x1c800000), 2 | ||
61 | }, { | ||
62 | .reset_reg = (void *)KSEG1ADDR(0x11080000), | ||
63 | .flash_wp_reg = (void *)KSEG1ADDR(0x11000000), 6 | ||
64 | } | ||
65 | }; | ||
66 | |||
67 | struct lasat_misc *lasat_misc; | ||
68 | |||
69 | #ifdef CONFIG_DS1603 | ||
70 | static struct ds_defs ds_defs[N_MACHTYPES] = { | ||
71 | { (void *)DS1603_REG_100, (void *)DS1603_REG_100, | ||
72 | DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, | ||
73 | DS1603_DATA_SHIFT_100, 0, 0 }, | ||
74 | { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, | ||
75 | DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, | ||
76 | DS1603_DATA_READ_SHIFT_200, 1, 2000 } | ||
77 | }; | ||
78 | #endif | ||
79 | |||
80 | #ifdef CONFIG_PICVUE | ||
81 | #include "picvue.h" | ||
82 | static struct pvc_defs pvc_defs[N_MACHTYPES] = { | ||
83 | { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, | ||
84 | PVC_E_100, PVC_RW_100, PVC_RS_100 }, | ||
85 | { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, | ||
86 | PVC_E_200, PVC_RW_200, PVC_RS_200 } | ||
87 | }; | ||
88 | #endif | ||
89 | |||
90 | static int lasat_panic_display(struct notifier_block *this, | ||
91 | unsigned long event, void *ptr) | ||
92 | { | ||
93 | #ifdef CONFIG_PICVUE | ||
94 | unsigned char *string = ptr; | ||
95 | if (string == NULL) | ||
96 | string = "Kernel Panic"; | ||
97 | pvc_dump_string(string); | ||
98 | #endif | ||
99 | return NOTIFY_DONE; | ||
100 | } | ||
101 | |||
102 | static int lasat_panic_prom_monitor(struct notifier_block *this, | ||
103 | unsigned long event, void *ptr) | ||
104 | { | ||
105 | prom_monitor(); | ||
106 | return NOTIFY_DONE; | ||
107 | } | ||
108 | |||
109 | static struct notifier_block lasat_panic_block[] = | ||
110 | { | ||
111 | { | ||
112 | .notifier_call = lasat_panic_display, | ||
113 | .priority = INT_MAX | ||
114 | }, { | ||
115 | .notifier_call = lasat_panic_prom_monitor, | ||
116 | .priority = INT_MIN | ||
117 | } | ||
118 | }; | ||
119 | |||
120 | static void lasat_time_init(void) | ||
121 | { | ||
122 | mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; | ||
123 | } | ||
124 | |||
125 | void __init plat_timer_setup(struct irqaction *irq) | ||
126 | { | ||
127 | change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); | ||
128 | } | ||
129 | |||
130 | void __init plat_mem_setup(void) | ||
131 | { | ||
132 | int i; | ||
133 | lasat_misc = &lasat_misc_info[mips_machtype]; | ||
134 | #ifdef CONFIG_PICVUE | ||
135 | picvue = &pvc_defs[mips_machtype]; | ||
136 | #endif | ||
137 | |||
138 | /* Set up panic notifier */ | ||
139 | for (i = 0; i < ARRAY_SIZE(lasat_panic_block); i++) | ||
140 | atomic_notifier_chain_register(&panic_notifier_list, | ||
141 | &lasat_panic_block[i]); | ||
142 | |||
143 | lasat_reboot_setup(); | ||
144 | |||
145 | board_time_init = lasat_time_init; | ||
146 | |||
147 | #ifdef CONFIG_DS1603 | ||
148 | ds1603 = &ds_defs[mips_machtype]; | ||
149 | rtc_mips_get_time = ds1603_read; | ||
150 | rtc_mips_set_time = ds1603_set; | ||
151 | #endif | ||
152 | |||
153 | #ifdef DYNAMIC_SERIAL_INIT | ||
154 | serial_init(); | ||
155 | #endif | ||
156 | |||
157 | pr_info("Lasat specific initialization complete\n"); | ||
158 | } | ||
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c new file mode 100644 index 000000000000..4575a829766d --- /dev/null +++ b/arch/mips/lasat/sysctl.c | |||
@@ -0,0 +1,454 @@ | |||
1 | /* | ||
2 | * Thomas Horsten <thh@lasat.com> | ||
3 | * Copyright (C) 2000 LASAT Networks A/S. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Routines specific to the LASAT boards | ||
19 | */ | ||
20 | #include <linux/types.h> | ||
21 | #include <asm/lasat/lasat.h> | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/sysctl.h> | ||
25 | #include <linux/stddef.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/ctype.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/net.h> | ||
31 | #include <linux/inet.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | |||
35 | #include "sysctl.h" | ||
36 | #include "ds1603.h" | ||
37 | |||
38 | static DEFINE_MUTEX(lasat_info_mutex); | ||
39 | |||
40 | /* Strategy function to write EEPROM after changing string entry */ | ||
41 | int sysctl_lasatstring(ctl_table *table, int *name, int nlen, | ||
42 | void *oldval, size_t *oldlenp, | ||
43 | void *newval, size_t newlen) | ||
44 | { | ||
45 | int r; | ||
46 | |||
47 | mutex_lock(&lasat_info_mutex); | ||
48 | r = sysctl_string(table, name, | ||
49 | nlen, oldval, oldlenp, newval, newlen); | ||
50 | if (r < 0) { | ||
51 | mutex_unlock(&lasat_info_mutex); | ||
52 | return r; | ||
53 | } | ||
54 | if (newval && newlen) | ||
55 | lasat_write_eeprom_info(); | ||
56 | mutex_unlock(&lasat_info_mutex); | ||
57 | |||
58 | return 1; | ||
59 | } | ||
60 | |||
61 | |||
62 | /* And the same for proc */ | ||
63 | int proc_dolasatstring(ctl_table *table, int write, struct file *filp, | ||
64 | void *buffer, size_t *lenp, loff_t *ppos) | ||
65 | { | ||
66 | int r; | ||
67 | |||
68 | mutex_lock(&lasat_info_mutex); | ||
69 | r = proc_dostring(table, write, filp, buffer, lenp, ppos); | ||
70 | if ((!write) || r) { | ||
71 | mutex_unlock(&lasat_info_mutex); | ||
72 | return r; | ||
73 | } | ||
74 | lasat_write_eeprom_info(); | ||
75 | mutex_unlock(&lasat_info_mutex); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | /* proc function to write EEPROM after changing int entry */ | ||
81 | int proc_dolasatint(ctl_table *table, int write, struct file *filp, | ||
82 | void *buffer, size_t *lenp, loff_t *ppos) | ||
83 | { | ||
84 | int r; | ||
85 | |||
86 | mutex_lock(&lasat_info_mutex); | ||
87 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | ||
88 | if ((!write) || r) { | ||
89 | mutex_unlock(&lasat_info_mutex); | ||
90 | return r; | ||
91 | } | ||
92 | lasat_write_eeprom_info(); | ||
93 | mutex_unlock(&lasat_info_mutex); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int rtctmp; | ||
99 | |||
100 | #ifdef CONFIG_DS1603 | ||
101 | /* proc function to read/write RealTime Clock */ | ||
102 | int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, | ||
103 | void *buffer, size_t *lenp, loff_t *ppos) | ||
104 | { | ||
105 | int r; | ||
106 | |||
107 | mutex_lock(&lasat_info_mutex); | ||
108 | if (!write) { | ||
109 | rtctmp = ds1603_read(); | ||
110 | /* check for time < 0 and set to 0 */ | ||
111 | if (rtctmp < 0) | ||
112 | rtctmp = 0; | ||
113 | } | ||
114 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | ||
115 | if ((!write) || r) { | ||
116 | mutex_unlock(&lasat_info_mutex); | ||
117 | return r; | ||
118 | } | ||
119 | ds1603_set(rtctmp); | ||
120 | mutex_unlock(&lasat_info_mutex); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | /* Sysctl for setting the IP addresses */ | ||
127 | int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, | ||
128 | void *oldval, size_t *oldlenp, | ||
129 | void *newval, size_t newlen) | ||
130 | { | ||
131 | int r; | ||
132 | |||
133 | mutex_lock(&lasat_info_mutex); | ||
134 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | ||
135 | if (r < 0) { | ||
136 | mutex_unlock(&lasat_info_mutex); | ||
137 | return r; | ||
138 | } | ||
139 | if (newval && newlen) | ||
140 | lasat_write_eeprom_info(); | ||
141 | mutex_unlock(&lasat_info_mutex); | ||
142 | |||
143 | return 1; | ||
144 | } | ||
145 | |||
146 | #ifdef CONFIG_DS1603 | ||
147 | /* Same for RTC */ | ||
148 | int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, | ||
149 | void *oldval, size_t *oldlenp, | ||
150 | void *newval, size_t newlen) | ||
151 | { | ||
152 | int r; | ||
153 | |||
154 | mutex_lock(&lasat_info_mutex); | ||
155 | rtctmp = ds1603_read(); | ||
156 | if (rtctmp < 0) | ||
157 | rtctmp = 0; | ||
158 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | ||
159 | if (r < 0) { | ||
160 | mutex_unlock(&lasat_info_mutex); | ||
161 | return r; | ||
162 | } | ||
163 | if (newval && newlen) | ||
164 | ds1603_set(rtctmp); | ||
165 | mutex_unlock(&lasat_info_mutex); | ||
166 | |||
167 | return 1; | ||
168 | } | ||
169 | #endif | ||
170 | |||
171 | #ifdef CONFIG_INET | ||
172 | static char lasat_bcastaddr[16]; | ||
173 | |||
174 | void update_bcastaddr(void) | ||
175 | { | ||
176 | unsigned int ip; | ||
177 | |||
178 | ip = (lasat_board_info.li_eeprom_info.ipaddr & | ||
179 | lasat_board_info.li_eeprom_info.netmask) | | ||
180 | ~lasat_board_info.li_eeprom_info.netmask; | ||
181 | |||
182 | sprintf(lasat_bcastaddr, "%d.%d.%d.%d", | ||
183 | (ip) & 0xff, | ||
184 | (ip >> 8) & 0xff, | ||
185 | (ip >> 16) & 0xff, | ||
186 | (ip >> 24) & 0xff); | ||
187 | } | ||
188 | |||
189 | static char proc_lasat_ipbuf[32]; | ||
190 | |||
191 | /* Parsing of IP address */ | ||
192 | int proc_lasat_ip(ctl_table *table, int write, struct file *filp, | ||
193 | void *buffer, size_t *lenp, loff_t *ppos) | ||
194 | { | ||
195 | unsigned int ip; | ||
196 | char *p, c; | ||
197 | int len; | ||
198 | |||
199 | if (!table->data || !table->maxlen || !*lenp || | ||
200 | (*ppos && !write)) { | ||
201 | *lenp = 0; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | mutex_lock(&lasat_info_mutex); | ||
206 | if (write) { | ||
207 | len = 0; | ||
208 | p = buffer; | ||
209 | while (len < *lenp) { | ||
210 | if (get_user(c, p++)) { | ||
211 | mutex_unlock(&lasat_info_mutex); | ||
212 | return -EFAULT; | ||
213 | } | ||
214 | if (c == 0 || c == '\n') | ||
215 | break; | ||
216 | len++; | ||
217 | } | ||
218 | if (len >= sizeof(proc_lasat_ipbuf)-1) | ||
219 | len = sizeof(proc_lasat_ipbuf) - 1; | ||
220 | if (copy_from_user(proc_lasat_ipbuf, buffer, len)) { | ||
221 | mutex_unlock(&lasat_info_mutex); | ||
222 | return -EFAULT; | ||
223 | } | ||
224 | proc_lasat_ipbuf[len] = 0; | ||
225 | *ppos += *lenp; | ||
226 | /* Now see if we can convert it to a valid IP */ | ||
227 | ip = in_aton(proc_lasat_ipbuf); | ||
228 | *(unsigned int *)(table->data) = ip; | ||
229 | lasat_write_eeprom_info(); | ||
230 | } else { | ||
231 | ip = *(unsigned int *)(table->data); | ||
232 | sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", | ||
233 | (ip) & 0xff, | ||
234 | (ip >> 8) & 0xff, | ||
235 | (ip >> 16) & 0xff, | ||
236 | (ip >> 24) & 0xff); | ||
237 | len = strlen(proc_lasat_ipbuf); | ||
238 | if (len > *lenp) | ||
239 | len = *lenp; | ||
240 | if (len) | ||
241 | if (copy_to_user(buffer, proc_lasat_ipbuf, len)) { | ||
242 | mutex_unlock(&lasat_info_mutex); | ||
243 | return -EFAULT; | ||
244 | } | ||
245 | if (len < *lenp) { | ||
246 | if (put_user('\n', ((char *) buffer) + len)) { | ||
247 | mutex_unlock(&lasat_info_mutex); | ||
248 | return -EFAULT; | ||
249 | } | ||
250 | len++; | ||
251 | } | ||
252 | *lenp = len; | ||
253 | *ppos += len; | ||
254 | } | ||
255 | update_bcastaddr(); | ||
256 | mutex_unlock(&lasat_info_mutex); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | #endif /* defined(CONFIG_INET) */ | ||
261 | |||
262 | static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, | ||
263 | void *oldval, size_t *oldlenp, | ||
264 | void *newval, size_t newlen) | ||
265 | { | ||
266 | int r; | ||
267 | |||
268 | mutex_lock(&lasat_info_mutex); | ||
269 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | ||
270 | if (r < 0) { | ||
271 | mutex_unlock(&lasat_info_mutex); | ||
272 | return r; | ||
273 | } | ||
274 | |||
275 | if (newval && newlen) { | ||
276 | if (name && *name == LASAT_PRID) | ||
277 | lasat_board_info.li_eeprom_info.prid = *(int *)newval; | ||
278 | |||
279 | lasat_write_eeprom_info(); | ||
280 | lasat_init_board_info(); | ||
281 | } | ||
282 | mutex_unlock(&lasat_info_mutex); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, | ||
288 | void *buffer, size_t *lenp, loff_t *ppos) | ||
289 | { | ||
290 | int r; | ||
291 | |||
292 | mutex_lock(&lasat_info_mutex); | ||
293 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | ||
294 | if ((!write) || r) { | ||
295 | mutex_unlock(&lasat_info_mutex); | ||
296 | return r; | ||
297 | } | ||
298 | if (filp && filp->f_path.dentry) { | ||
299 | if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) | ||
300 | lasat_board_info.li_eeprom_info.prid = | ||
301 | lasat_board_info.li_prid; | ||
302 | if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) | ||
303 | lasat_board_info.li_eeprom_info.debugaccess = | ||
304 | lasat_board_info.li_debugaccess; | ||
305 | } | ||
306 | lasat_write_eeprom_info(); | ||
307 | mutex_unlock(&lasat_info_mutex); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | extern int lasat_boot_to_service; | ||
313 | |||
314 | #ifdef CONFIG_SYSCTL | ||
315 | |||
316 | static ctl_table lasat_table[] = { | ||
317 | { | ||
318 | .ctl_name = CTL_UNNUMBERED, | ||
319 | .procname = "cpu-hz", | ||
320 | .data = &lasat_board_info.li_cpu_hz, | ||
321 | .maxlen = sizeof(int), | ||
322 | .mode = 0444, | ||
323 | .proc_handler = &proc_dointvec, | ||
324 | .strategy = &sysctl_intvec | ||
325 | }, | ||
326 | { | ||
327 | .ctl_name = CTL_UNNUMBERED, | ||
328 | .procname = "bus-hz", | ||
329 | .data = &lasat_board_info.li_bus_hz, | ||
330 | .maxlen = sizeof(int), | ||
331 | .mode = 0444, | ||
332 | .proc_handler = &proc_dointvec, | ||
333 | .strategy = &sysctl_intvec | ||
334 | }, | ||
335 | { | ||
336 | .ctl_name = CTL_UNNUMBERED, | ||
337 | .procname = "bmid", | ||
338 | .data = &lasat_board_info.li_bmid, | ||
339 | .maxlen = sizeof(int), | ||
340 | .mode = 0444, | ||
341 | .proc_handler = &proc_dointvec, | ||
342 | .strategy = &sysctl_intvec | ||
343 | }, | ||
344 | { | ||
345 | .ctl_name = CTL_UNNUMBERED, | ||
346 | .procname = "prid", | ||
347 | .data = &lasat_board_info.li_prid, | ||
348 | .maxlen = sizeof(int), | ||
349 | .mode = 0644, | ||
350 | .proc_handler = &proc_lasat_eeprom_value, | ||
351 | .strategy = &sysctl_lasat_eeprom_value | ||
352 | }, | ||
353 | #ifdef CONFIG_INET | ||
354 | { | ||
355 | .ctl_name = CTL_UNNUMBERED, | ||
356 | .procname = "ipaddr", | ||
357 | .data = &lasat_board_info.li_eeprom_info.ipaddr, | ||
358 | .maxlen = sizeof(int), | ||
359 | .mode = 0644, | ||
360 | .proc_handler = &proc_lasat_ip, | ||
361 | .strategy = &sysctl_lasat_intvec | ||
362 | }, | ||
363 | { | ||
364 | .ctl_name = LASAT_NETMASK, | ||
365 | .procname = "netmask", | ||
366 | .data = &lasat_board_info.li_eeprom_info.netmask, | ||
367 | .maxlen = sizeof(int), | ||
368 | .mode = 0644, | ||
369 | .proc_handler = &proc_lasat_ip, | ||
370 | .strategy = &sysctl_lasat_intvec | ||
371 | }, | ||
372 | { | ||
373 | .ctl_name = CTL_UNNUMBERED, | ||
374 | .procname = "bcastaddr", | ||
375 | .data = &lasat_bcastaddr, | ||
376 | .maxlen = sizeof(lasat_bcastaddr), | ||
377 | .mode = 0600, | ||
378 | .proc_handler = &proc_dostring, | ||
379 | .strategy = &sysctl_string | ||
380 | }, | ||
381 | #endif | ||
382 | { | ||
383 | .ctl_name = CTL_UNNUMBERED, | ||
384 | .procname = "passwd_hash", | ||
385 | .data = &lasat_board_info.li_eeprom_info.passwd_hash, | ||
386 | .maxlen = | ||
387 | sizeof(lasat_board_info.li_eeprom_info.passwd_hash), | ||
388 | .mode = 0600, | ||
389 | .proc_handler = &proc_dolasatstring, | ||
390 | .strategy = &sysctl_lasatstring | ||
391 | }, | ||
392 | { | ||
393 | .ctl_name = CTL_UNNUMBERED, | ||
394 | .procname = "boot-service", | ||
395 | .data = &lasat_boot_to_service, | ||
396 | .maxlen = sizeof(int), | ||
397 | .mode = 0644, | ||
398 | .proc_handler = &proc_dointvec, | ||
399 | .strategy = &sysctl_intvec | ||
400 | }, | ||
401 | #ifdef CONFIG_DS1603 | ||
402 | { | ||
403 | .ctl_name = CTL_UNNUMBERED, | ||
404 | .procname = "rtc", | ||
405 | .data = &rtctmp, | ||
406 | .maxlen = sizeof(int), | ||
407 | .mode = 0644, | ||
408 | .proc_handler = &proc_dolasatrtc, | ||
409 | .strategy = &sysctl_lasat_rtc | ||
410 | }, | ||
411 | #endif | ||
412 | { | ||
413 | .ctl_name = CTL_UNNUMBERED, | ||
414 | .procname = "namestr", | ||
415 | .data = &lasat_board_info.li_namestr, | ||
416 | .maxlen = sizeof(lasat_board_info.li_namestr), | ||
417 | .mode = 0444, | ||
418 | .proc_handler = &proc_dostring, | ||
419 | .strategy = &sysctl_string | ||
420 | }, | ||
421 | { | ||
422 | .ctl_name = CTL_UNNUMBERED, | ||
423 | .procname = "typestr", | ||
424 | .data = &lasat_board_info.li_typestr, | ||
425 | .maxlen = sizeof(lasat_board_info.li_typestr), | ||
426 | .mode = 0444, | ||
427 | .proc_handler = &proc_dostring, | ||
428 | .strategy = &sysctl_string | ||
429 | }, | ||
430 | {} | ||
431 | }; | ||
432 | |||
433 | static ctl_table lasat_root_table[] = { | ||
434 | { | ||
435 | .ctl_name = CTL_UNNUMBERED, | ||
436 | .procname = "lasat", | ||
437 | .mode = 0555, | ||
438 | .child = lasat_table | ||
439 | }, | ||
440 | {} | ||
441 | }; | ||
442 | |||
443 | static int __init lasat_register_sysctl(void) | ||
444 | { | ||
445 | struct ctl_table_header *lasat_table_header; | ||
446 | |||
447 | lasat_table_header = | ||
448 | register_sysctl_table(lasat_root_table); | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | __initcall(lasat_register_sysctl); | ||
454 | #endif /* CONFIG_SYSCTL */ | ||
diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h new file mode 100644 index 000000000000..341b97933423 --- /dev/null +++ b/arch/mips/lasat/sysctl.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * LASAT sysctl values | ||
3 | */ | ||
4 | |||
5 | #ifndef _LASAT_SYSCTL_H | ||
6 | #define _LASAT_SYSCTL_H | ||
7 | |||
8 | /* /proc/sys/lasat */ | ||
9 | enum { | ||
10 | LASAT_CPU_HZ = 1, | ||
11 | LASAT_BUS_HZ, | ||
12 | LASAT_MODEL, | ||
13 | LASAT_PRID, | ||
14 | LASAT_IPADDR, | ||
15 | LASAT_NETMASK, | ||
16 | LASAT_BCAST, | ||
17 | LASAT_PASSWORD, | ||
18 | LASAT_SBOOT, | ||
19 | LASAT_RTC, | ||
20 | LASAT_NAMESTR, | ||
21 | LASAT_TYPESTR, | ||
22 | }; | ||
23 | |||
24 | #endif /* _LASAT_SYSCTL_H */ | ||