diff options
Diffstat (limited to 'arch/cris/arch-v10')
29 files changed, 2018 insertions, 704 deletions
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig index 2ca64cc40c63..44eb1b9accb3 100644 --- a/arch/cris/arch-v10/Kconfig +++ b/arch/cris/arch-v10/Kconfig | |||
@@ -260,6 +260,37 @@ config ETRAX_DEBUG_PORT_NULL | |||
260 | endchoice | 260 | endchoice |
261 | 261 | ||
262 | choice | 262 | choice |
263 | prompt "Kernel GDB port" | ||
264 | depends on ETRAX_KGDB | ||
265 | default ETRAX_KGDB_PORT0 | ||
266 | help | ||
267 | Choose a serial port for kernel debugging. NOTE: This port should | ||
268 | not be enabled under Drivers for built-in interfaces (as it has its | ||
269 | own initialization code) and should not be the same as the debug port. | ||
270 | |||
271 | config ETRAX_KGDB_PORT0 | ||
272 | bool "Serial-0" | ||
273 | help | ||
274 | Use serial port 0 for kernel debugging. | ||
275 | |||
276 | config ETRAX_KGDB_PORT1 | ||
277 | bool "Serial-1" | ||
278 | help | ||
279 | Use serial port 1 for kernel debugging. | ||
280 | |||
281 | config ETRAX_KGDB_PORT2 | ||
282 | bool "Serial-2" | ||
283 | help | ||
284 | Use serial port 2 for kernel debugging. | ||
285 | |||
286 | config ETRAX_KGDB_PORT3 | ||
287 | bool "Serial-3" | ||
288 | help | ||
289 | Use serial port 3 for kernel debugging. | ||
290 | |||
291 | endchoice | ||
292 | |||
293 | choice | ||
263 | prompt "Product rescue-port" | 294 | prompt "Product rescue-port" |
264 | depends on ETRAX_ARCH_V10 | 295 | depends on ETRAX_ARCH_V10 |
265 | default ETRAX_RESCUE_SER0 | 296 | default ETRAX_RESCUE_SER0 |
diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile index fe6650368e6a..e5b105851108 100644 --- a/arch/cris/arch-v10/boot/Makefile +++ b/arch/cris/arch-v10/boot/Makefile | |||
@@ -1,12 +1,13 @@ | |||
1 | # | 1 | # |
2 | # arch/cris/boot/Makefile | 2 | # arch/cris/boot/Makefile |
3 | # | 3 | # |
4 | target = $(target_boot_dir) | ||
5 | src = $(src_boot_dir) | ||
4 | 6 | ||
5 | zImage: compressed/vmlinuz | 7 | zImage: compressed/vmlinuz |
6 | 8 | ||
7 | compressed/vmlinuz: $(TOPDIR)/vmlinux | 9 | compressed/vmlinuz: |
8 | @$(MAKE) -C compressed vmlinuz | 10 | @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz |
9 | 11 | ||
10 | clean: | 12 | clean: |
11 | rm -f zImage tools/build compressed/vmlinux.out | 13 | @$(MAKE) -f $(src)/compressed/Makefile clean |
12 | @$(MAKE) -C compressed clean | ||
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile index 5f71c2c819e6..6584a44820f4 100644 --- a/arch/cris/arch-v10/boot/compressed/Makefile +++ b/arch/cris/arch-v10/boot/compressed/Makefile | |||
@@ -1,40 +1,45 @@ | |||
1 | # | 1 | # |
2 | # linux/arch/etrax100/boot/compressed/Makefile | 2 | # create a compressed vmlinuz image from the binary vmlinux.bin file |
3 | # | ||
4 | # create a compressed vmlinux image from the original vmlinux files and romfs | ||
5 | # | 3 | # |
4 | target = $(target_compressed_dir) | ||
5 | src = $(src_compressed_dir) | ||
6 | 6 | ||
7 | CC = gcc-cris -melf -I $(TOPDIR)/include | 7 | CC = gcc-cris -melf $(LINUXINCLUDE) |
8 | CFLAGS = -O2 | 8 | CFLAGS = -O2 |
9 | LD = ld-cris | 9 | LD = ld-cris |
10 | OBJCOPY = objcopy-cris | 10 | OBJCOPY = objcopy-cris |
11 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 11 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
12 | OBJECTS = head.o misc.o | 12 | OBJECTS = $(target)/head.o $(target)/misc.o |
13 | 13 | ||
14 | # files to compress | 14 | # files to compress |
15 | SYSTEM = $(TOPDIR)/vmlinux.bin | 15 | SYSTEM = $(objtree)/vmlinux.bin |
16 | 16 | ||
17 | all: vmlinuz | 17 | all: $(target_compressed_dir)/vmlinuz |
18 | 18 | ||
19 | decompress.bin: $(OBJECTS) | 19 | $(target)/decompress.bin: $(OBJECTS) |
20 | $(LD) -T decompress.ld -o decompress.o $(OBJECTS) | 20 | $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS) |
21 | $(OBJCOPY) $(OBJCOPYFLAGS) decompress.o decompress.bin | 21 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin |
22 | # save it for mkprod in the topdir. | ||
23 | cp decompress.bin $(TOPDIR) | ||
24 | 22 | ||
23 | # Create vmlinuz image in top-level build directory | ||
24 | $(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin | ||
25 | @echo " COMPR vmlinux.bin --> vmlinuz" | ||
26 | @cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz | ||
27 | @rm -f piggy.img | ||
25 | 28 | ||
26 | vmlinuz: piggy.img decompress.bin | 29 | $(target)/head.o: $(src)/head.S |
27 | cat decompress.bin piggy.img > vmlinuz | 30 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@ |
28 | rm -f piggy.img | ||
29 | 31 | ||
30 | head.o: head.S | 32 | $(target)/misc.o: $(src)/misc.c |
31 | $(CC) -D__ASSEMBLY__ -traditional -c head.S -o head.o | 33 | $(CC) -D__KERNEL__ -c $< -o $@ |
32 | 34 | ||
33 | # gzip the kernel image | 35 | # gzip the kernel image |
34 | 36 | ||
35 | piggy.img: $(SYSTEM) | 37 | piggy.img: $(SYSTEM) |
36 | cat $(SYSTEM) | gzip -f -9 > piggy.img | 38 | @cat $(SYSTEM) | gzip -f -9 > piggy.img |
39 | |||
40 | $(target): | ||
41 | mkdir -p $(target) | ||
37 | 42 | ||
38 | clean: | 43 | clean: |
39 | rm -f piggy.img vmlinuz vmlinuz.o | 44 | rm -f piggy.img $(objtree)/vmlinuz |
40 | 45 | ||
diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/arch-v10/boot/compressed/head.S index 4cbdd4b1d9d6..e73f44c998d9 100644 --- a/arch/cris/arch-v10/boot/compressed/head.S +++ b/arch/cris/arch-v10/boot/compressed/head.S | |||
@@ -13,7 +13,8 @@ | |||
13 | #include <asm/arch/sv_addr_ag.h> | 13 | #include <asm/arch/sv_addr_ag.h> |
14 | 14 | ||
15 | #define RAM_INIT_MAGIC 0x56902387 | 15 | #define RAM_INIT_MAGIC 0x56902387 |
16 | 16 | #define COMMAND_LINE_MAGIC 0x87109563 | |
17 | |||
17 | ;; Exported symbols | 18 | ;; Exported symbols |
18 | 19 | ||
19 | .globl _input_data | 20 | .globl _input_data |
@@ -88,6 +89,12 @@ basse: move.d pc, r5 | |||
88 | cmp.d r2, r1 | 89 | cmp.d r2, r1 |
89 | bcs 1b | 90 | bcs 1b |
90 | nop | 91 | nop |
92 | |||
93 | ;; Save command line magic and address. | ||
94 | move.d _cmd_line_magic, $r12 | ||
95 | move.d $r10, [$r12] | ||
96 | move.d _cmd_line_addr, $r12 | ||
97 | move.d $r11, [$r12] | ||
91 | 98 | ||
92 | ;; Do the decompression and save compressed size in _inptr | 99 | ;; Do the decompression and save compressed size in _inptr |
93 | 100 | ||
@@ -98,7 +105,13 @@ basse: move.d pc, r5 | |||
98 | 105 | ||
99 | move.d [_input_data], r9 ; flash address of compressed kernel | 106 | move.d [_input_data], r9 ; flash address of compressed kernel |
100 | add.d [_inptr], r9 ; size of compressed kernel | 107 | add.d [_inptr], r9 ; size of compressed kernel |
101 | 108 | ||
109 | ;; Restore command line magic and address. | ||
110 | move.d _cmd_line_magic, $r10 | ||
111 | move.d [$r10], $r10 | ||
112 | move.d _cmd_line_addr, $r11 | ||
113 | move.d [$r11], $r11 | ||
114 | |||
102 | ;; Enter the decompressed kernel | 115 | ;; Enter the decompressed kernel |
103 | move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized | 116 | move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized |
104 | jump 0x40004000 ; kernel is linked to this address | 117 | jump 0x40004000 ; kernel is linked to this address |
@@ -107,5 +120,8 @@ basse: move.d pc, r5 | |||
107 | 120 | ||
108 | _input_data: | 121 | _input_data: |
109 | .dword 0 ; used by the decompressor | 122 | .dword 0 ; used by the decompressor |
110 | 123 | _cmd_line_magic: | |
124 | .dword 0 | ||
125 | _cmd_line_addr: | ||
126 | .dword 0 | ||
111 | #include "../../lib/hw_settings.S" | 127 | #include "../../lib/hw_settings.S" |
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile index e9f2ba2ad02c..8be9b3130312 100644 --- a/arch/cris/arch-v10/boot/rescue/Makefile +++ b/arch/cris/arch-v10/boot/rescue/Makefile | |||
@@ -1,52 +1,53 @@ | |||
1 | # | 1 | # |
2 | # Makefile for rescue code | 2 | # Makefile for rescue code |
3 | # | 3 | # |
4 | ifndef TOPDIR | 4 | target = $(target_rescue_dir) |
5 | TOPDIR = ../../../.. | 5 | src = $(src_rescue_dir) |
6 | endif | 6 | |
7 | CC = gcc-cris -mlinux -I $(TOPDIR)/include | 7 | CC = gcc-cris -mlinux $(LINUXINCLUDE) |
8 | CFLAGS = -O2 | 8 | CFLAGS = -O2 |
9 | LD = gcc-cris -mlinux -nostdlib | 9 | LD = gcc-cris -mlinux -nostdlib |
10 | OBJCOPY = objcopy-cris | 10 | OBJCOPY = objcopy-cris |
11 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 11 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
12 | 12 | ||
13 | all: rescue.bin testrescue.bin kimagerescue.bin | 13 | all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin |
14 | |||
15 | rescue: rescue.bin | ||
16 | # do nothing | ||
17 | 14 | ||
18 | rescue.bin: head.o | 15 | $(target)/rescue.bin: $(target) $(target)/head.o |
19 | $(LD) -T rescue.ld -o rescue.o head.o | 16 | $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o |
20 | $(OBJCOPY) $(OBJCOPYFLAGS) rescue.o rescue.bin | 17 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin |
21 | cp rescue.bin $(TOPDIR) | 18 | # Place a copy in top-level build directory |
19 | cp -p $(target)/rescue.bin $(objtree) | ||
22 | 20 | ||
23 | testrescue.bin: testrescue.o | 21 | $(target)/testrescue.bin: $(target) $(target)/testrescue.o |
24 | $(OBJCOPY) $(OBJCOPYFLAGS) testrescue.o tr.bin | 22 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin |
25 | # Pad it to 784 bytes | 23 | # Pad it to 784 bytes |
26 | dd if=/dev/zero of=tmp2423 bs=1 count=784 | 24 | dd if=/dev/zero of=tmp2423 bs=1 count=784 |
27 | cat tr.bin tmp2423 >testrescue_tmp.bin | 25 | cat tr.bin tmp2423 >testrescue_tmp.bin |
28 | dd if=testrescue_tmp.bin of=testrescue.bin bs=1 count=784 | 26 | dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784 |
29 | rm tr.bin tmp2423 testrescue_tmp.bin | 27 | rm tr.bin tmp2423 testrescue_tmp.bin |
30 | 28 | ||
31 | kimagerescue.bin: kimagerescue.o | 29 | $(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o |
32 | $(OBJCOPY) $(OBJCOPYFLAGS) kimagerescue.o ktr.bin | 30 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin |
33 | # Pad it to 784 bytes, that's what the rescue loader expects | 31 | # Pad it to 784 bytes, that's what the rescue loader expects |
34 | dd if=/dev/zero of=tmp2423 bs=1 count=784 | 32 | dd if=/dev/zero of=tmp2423 bs=1 count=784 |
35 | cat ktr.bin tmp2423 >kimagerescue_tmp.bin | 33 | cat ktr.bin tmp2423 >kimagerescue_tmp.bin |
36 | dd if=kimagerescue_tmp.bin of=kimagerescue.bin bs=1 count=784 | 34 | dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784 |
37 | rm ktr.bin tmp2423 kimagerescue_tmp.bin | 35 | rm ktr.bin tmp2423 kimagerescue_tmp.bin |
38 | 36 | ||
39 | head.o: head.S | 37 | $(target): |
38 | mkdir -p $(target) | ||
39 | |||
40 | $(target)/head.o: $(src)/head.S | ||
40 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | 41 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o |
41 | 42 | ||
42 | testrescue.o: testrescue.S | 43 | $(target)/testrescue.o: $(src)/testrescue.S |
43 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | 44 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o |
44 | 45 | ||
45 | kimagerescue.o: kimagerescue.S | 46 | $(target)/kimagerescue.o: $(src)/kimagerescue.S |
46 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | 47 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o |
47 | 48 | ||
48 | clean: | 49 | clean: |
49 | rm -f *.o *.bin | 50 | rm -f $(target)/*.o $(target)/*.bin |
50 | 51 | ||
51 | fastdep: | 52 | fastdep: |
52 | 53 | ||
diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/arch-v10/boot/rescue/head.S index 8689ea972c46..addb2194de0f 100644 --- a/arch/cris/arch-v10/boot/rescue/head.S +++ b/arch/cris/arch-v10/boot/rescue/head.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: head.S,v 1.6 2003/04/09 08:12:43 pkj Exp $ | 1 | /* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $ |
2 | * | 2 | * |
3 | * Rescue code, made to reside at the beginning of the | 3 | * Rescue code, made to reside at the beginning of the |
4 | * flash-memory. when it starts, it checks a partition | 4 | * flash-memory. when it starts, it checks a partition |
@@ -121,12 +121,13 @@ | |||
121 | ;; 0x80000000 if loaded in flash (as it should be) | 121 | ;; 0x80000000 if loaded in flash (as it should be) |
122 | ;; since etrax actually starts at address 2 when booting from flash, we | 122 | ;; since etrax actually starts at address 2 when booting from flash, we |
123 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di | 123 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di |
124 | 124 | ||
125 | nop | 125 | nop |
126 | di | 126 | di |
127 | 127 | ||
128 | jump in_cache ; enter cached area instead | 128 | jump in_cache ; enter cached area instead |
129 | in_cache: | 129 | in_cache: |
130 | |||
130 | 131 | ||
131 | ;; first put a jump test to give a possibility of upgrading the rescue code | 132 | ;; first put a jump test to give a possibility of upgrading the rescue code |
132 | ;; without erasing/reflashing the sector. we put a longword of -1 here and if | 133 | ;; without erasing/reflashing the sector. we put a longword of -1 here and if |
@@ -325,9 +326,29 @@ flash_ok: | |||
325 | ;; result will be in r0 | 326 | ;; result will be in r0 |
326 | checksum: | 327 | checksum: |
327 | moveq 0, $r0 | 328 | moveq 0, $r0 |
328 | 1: addu.b [$r1+], $r0 | 329 | moveq CONFIG_ETRAX_FLASH1_SIZE, $r6 |
329 | subq 1, $r2 | 330 | |
330 | bne 1b | 331 | ;; If the first physical flash memory is exceeded wrap to the second one. |
332 | btstq 26, $r1 ; Are we addressing first flash? | ||
333 | bpl 1f | ||
334 | nop | ||
335 | clear.d $r6 | ||
336 | |||
337 | 1: test.d $r6 ; 0 = no wrapping | ||
338 | beq 2f | ||
339 | nop | ||
340 | lslq 20, $r6 ; Convert MB to bytes | ||
341 | sub.d $r1, $r6 | ||
342 | |||
343 | 2: addu.b [$r1+], $r0 | ||
344 | subq 1, $r6 ; Flash memory left | ||
345 | beq 3f | ||
346 | subq 1, $r2 ; Length left | ||
347 | bne 2b | ||
331 | nop | 348 | nop |
332 | ret | 349 | ret |
333 | nop | 350 | nop |
351 | |||
352 | 3: move.d MEM_CSE1_START, $r1 ; wrap to second flash | ||
353 | ba 2b | ||
354 | nop | ||
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 748374f25b87..8b50e8402954 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig | |||
@@ -1,17 +1,11 @@ | |||
1 | config ETRAX_ETHERNET | 1 | config ETRAX_ETHERNET |
2 | bool "Ethernet support" | 2 | bool "Ethernet support" |
3 | depends on ETRAX_ARCH_V10 | 3 | depends on ETRAX_ARCH_V10 |
4 | select NET_ETHERNET | ||
4 | help | 5 | help |
5 | This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet | 6 | This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet |
6 | controller. | 7 | controller. |
7 | 8 | ||
8 | # this is just so that the user does not have to go into the | ||
9 | # normal ethernet driver section just to enable ethernetworking | ||
10 | config NET_ETHERNET | ||
11 | bool | ||
12 | depends on ETRAX_ETHERNET | ||
13 | default y | ||
14 | |||
15 | choice | 9 | choice |
16 | prompt "Network LED behavior" | 10 | prompt "Network LED behavior" |
17 | depends on ETRAX_ETHERNET | 11 | depends on ETRAX_ETHERNET |
@@ -20,26 +14,26 @@ choice | |||
20 | config ETRAX_NETWORK_LED_ON_WHEN_LINK | 14 | config ETRAX_NETWORK_LED_ON_WHEN_LINK |
21 | bool "LED_on_when_link" | 15 | bool "LED_on_when_link" |
22 | help | 16 | help |
23 | Selecting LED_on_when_link will light the LED when there is a | 17 | Selecting LED_on_when_link will light the LED when there is a |
24 | connection and will flash off when there is activity. | 18 | connection and will flash off when there is activity. |
25 | 19 | ||
26 | Selecting LED_on_when_activity will light the LED only when | 20 | Selecting LED_on_when_activity will light the LED only when |
27 | there is activity. | 21 | there is activity. |
28 | 22 | ||
29 | This setting will also affect the behaviour of other activity LEDs | 23 | This setting will also affect the behaviour of other activity LEDs |
30 | e.g. Bluetooth. | 24 | e.g. Bluetooth. |
31 | 25 | ||
32 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | 26 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY |
33 | bool "LED_on_when_activity" | 27 | bool "LED_on_when_activity" |
34 | help | 28 | help |
35 | Selecting LED_on_when_link will light the LED when there is a | 29 | Selecting LED_on_when_link will light the LED when there is a |
36 | connection and will flash off when there is activity. | 30 | connection and will flash off when there is activity. |
37 | 31 | ||
38 | Selecting LED_on_when_activity will light the LED only when | 32 | Selecting LED_on_when_activity will light the LED only when |
39 | there is activity. | 33 | there is activity. |
40 | 34 | ||
41 | This setting will also affect the behaviour of other activity LEDs | 35 | This setting will also affect the behaviour of other activity LEDs |
42 | e.g. Bluetooth. | 36 | e.g. Bluetooth. |
43 | 37 | ||
44 | endchoice | 38 | endchoice |
45 | 39 | ||
@@ -91,11 +85,11 @@ choice | |||
91 | depends on ETRAX_SERIAL_PORT0 | 85 | depends on ETRAX_SERIAL_PORT0 |
92 | default ETRAX_SERIAL_PORT0_DMA6_OUT | 86 | default ETRAX_SERIAL_PORT0_DMA6_OUT |
93 | 87 | ||
94 | config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT | 88 | config ETRAX_SERIAL_PORT0_NO_DMA_OUT |
95 | bool "No DMA out" | 89 | bool "No DMA out" |
96 | 90 | ||
97 | config CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT | 91 | config ETRAX_SERIAL_PORT0_DMA6_OUT |
98 | bool "DMA 6" | 92 | bool "DMA 6" |
99 | 93 | ||
100 | endchoice | 94 | endchoice |
101 | 95 | ||
@@ -104,11 +98,11 @@ choice | |||
104 | depends on ETRAX_SERIAL_PORT0 | 98 | depends on ETRAX_SERIAL_PORT0 |
105 | default ETRAX_SERIAL_PORT0_DMA7_IN | 99 | default ETRAX_SERIAL_PORT0_DMA7_IN |
106 | 100 | ||
107 | config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN | 101 | config ETRAX_SERIAL_PORT0_NO_DMA_IN |
108 | bool "No DMA in" | 102 | bool "No DMA in" |
109 | 103 | ||
110 | config CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN | 104 | config ETRAX_SERIAL_PORT0_DMA7_IN |
111 | bool "DMA 7" | 105 | bool "DMA 7" |
112 | 106 | ||
113 | endchoice | 107 | endchoice |
114 | 108 | ||
@@ -205,11 +199,11 @@ choice | |||
205 | depends on ETRAX_SERIAL_PORT1 | 199 | depends on ETRAX_SERIAL_PORT1 |
206 | default ETRAX_SERIAL_PORT1_DMA8_OUT | 200 | default ETRAX_SERIAL_PORT1_DMA8_OUT |
207 | 201 | ||
208 | config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT | 202 | config ETRAX_SERIAL_PORT1_NO_DMA_OUT |
209 | bool "No DMA out" | 203 | bool "No DMA out" |
210 | 204 | ||
211 | config CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT | 205 | config ETRAX_SERIAL_PORT1_DMA8_OUT |
212 | bool "DMA 8" | 206 | bool "DMA 8" |
213 | 207 | ||
214 | endchoice | 208 | endchoice |
215 | 209 | ||
@@ -218,11 +212,11 @@ choice | |||
218 | depends on ETRAX_SERIAL_PORT1 | 212 | depends on ETRAX_SERIAL_PORT1 |
219 | default ETRAX_SERIAL_PORT1_DMA9_IN | 213 | default ETRAX_SERIAL_PORT1_DMA9_IN |
220 | 214 | ||
221 | config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN | 215 | config ETRAX_SERIAL_PORT1_NO_DMA_IN |
222 | bool "No DMA in" | 216 | bool "No DMA in" |
223 | 217 | ||
224 | config CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN | 218 | config ETRAX_SERIAL_PORT1_DMA9_IN |
225 | bool "DMA 9" | 219 | bool "DMA 9" |
226 | 220 | ||
227 | endchoice | 221 | endchoice |
228 | 222 | ||
@@ -308,7 +302,7 @@ config ETRAX_SER1_CD_ON_PB_BIT | |||
308 | Specify the pin of the PB port to carry the CD signal for serial | 302 | Specify the pin of the PB port to carry the CD signal for serial |
309 | port 1. | 303 | port 1. |
310 | 304 | ||
311 | comment "Make sure you dont have the same PB bits more than once!" | 305 | comment "Make sure you do not have the same PB bits more than once!" |
312 | depends on ETRAX_SERIAL && ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && ETRAX_SER1_DTR_RI_DSR_CD_ON_PB | 306 | depends on ETRAX_SERIAL && ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && ETRAX_SER1_DTR_RI_DSR_CD_ON_PB |
313 | 307 | ||
314 | config ETRAX_SERIAL_PORT2 | 308 | config ETRAX_SERIAL_PORT2 |
@@ -322,11 +316,11 @@ choice | |||
322 | depends on ETRAX_SERIAL_PORT2 | 316 | depends on ETRAX_SERIAL_PORT2 |
323 | default ETRAX_SERIAL_PORT2_DMA2_OUT | 317 | default ETRAX_SERIAL_PORT2_DMA2_OUT |
324 | 318 | ||
325 | config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT | 319 | config ETRAX_SERIAL_PORT2_NO_DMA_OUT |
326 | bool "No DMA out" | 320 | bool "No DMA out" |
327 | 321 | ||
328 | config CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT | 322 | config ETRAX_SERIAL_PORT2_DMA2_OUT |
329 | bool "DMA 2" | 323 | bool "DMA 2" |
330 | 324 | ||
331 | endchoice | 325 | endchoice |
332 | 326 | ||
@@ -335,11 +329,11 @@ choice | |||
335 | depends on ETRAX_SERIAL_PORT2 | 329 | depends on ETRAX_SERIAL_PORT2 |
336 | default ETRAX_SERIAL_PORT2_DMA3_IN | 330 | default ETRAX_SERIAL_PORT2_DMA3_IN |
337 | 331 | ||
338 | config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN | 332 | config ETRAX_SERIAL_PORT2_NO_DMA_IN |
339 | bool "No DMA in" | 333 | bool "No DMA in" |
340 | 334 | ||
341 | config CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN | 335 | config ETRAX_SERIAL_PORT2_DMA3_IN |
342 | bool "DMA 3" | 336 | bool "DMA 3" |
343 | 337 | ||
344 | endchoice | 338 | endchoice |
345 | 339 | ||
@@ -436,11 +430,11 @@ choice | |||
436 | depends on ETRAX_SERIAL_PORT3 | 430 | depends on ETRAX_SERIAL_PORT3 |
437 | default ETRAX_SERIAL_PORT3_DMA4_OUT | 431 | default ETRAX_SERIAL_PORT3_DMA4_OUT |
438 | 432 | ||
439 | config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT | 433 | config ETRAX_SERIAL_PORT3_NO_DMA_OUT |
440 | bool "No DMA out" | 434 | bool "No DMA out" |
441 | 435 | ||
442 | config CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT | 436 | config ETRAX_SERIAL_PORT3_DMA4_OUT |
443 | bool "DMA 4" | 437 | bool "DMA 4" |
444 | 438 | ||
445 | endchoice | 439 | endchoice |
446 | 440 | ||
@@ -449,11 +443,11 @@ choice | |||
449 | depends on ETRAX_SERIAL_PORT3 | 443 | depends on ETRAX_SERIAL_PORT3 |
450 | default ETRAX_SERIAL_PORT3_DMA5_IN | 444 | default ETRAX_SERIAL_PORT3_DMA5_IN |
451 | 445 | ||
452 | config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN | 446 | config ETRAX_SERIAL_PORT3_NO_DMA_IN |
453 | bool "No DMA in" | 447 | bool "No DMA in" |
454 | 448 | ||
455 | config CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN | 449 | config ETRAX_SERIAL_PORT3_DMA5_IN |
456 | bool "DMA 5" | 450 | bool "DMA 5" |
457 | 451 | ||
458 | endchoice | 452 | endchoice |
459 | 453 | ||
@@ -554,7 +548,6 @@ config ETRAX_IDE | |||
554 | select BLK_DEV_IDEDISK | 548 | select BLK_DEV_IDEDISK |
555 | select BLK_DEV_IDECD | 549 | select BLK_DEV_IDECD |
556 | select BLK_DEV_IDEDMA | 550 | select BLK_DEV_IDEDMA |
557 | select DMA_NONPCI | ||
558 | help | 551 | help |
559 | Enable this to get support for ATA/IDE. | 552 | Enable this to get support for ATA/IDE. |
560 | You can't use paralell ports or SCSI ports | 553 | You can't use paralell ports or SCSI ports |
@@ -579,7 +572,7 @@ config ETRAX_IDE_PB7_RESET | |||
579 | IDE reset on pin 7 on port B | 572 | IDE reset on pin 7 on port B |
580 | 573 | ||
581 | config ETRAX_IDE_G27_RESET | 574 | config ETRAX_IDE_G27_RESET |
582 | bool "Port_G_Bit_27" | 575 | bool "Port_G_Bit_27" |
583 | help | 576 | help |
584 | IDE reset on pin 27 on port G | 577 | IDE reset on pin 27 on port G |
585 | 578 | ||
@@ -588,30 +581,36 @@ endchoice | |||
588 | 581 | ||
589 | config ETRAX_USB_HOST | 582 | config ETRAX_USB_HOST |
590 | bool "USB host" | 583 | bool "USB host" |
584 | select USB | ||
591 | help | 585 | help |
592 | This option enables the host functionality of the ETRAX 100LX | 586 | This option enables the host functionality of the ETRAX 100LX |
593 | built-in USB controller. In host mode the controller is designed | 587 | built-in USB controller. In host mode the controller is designed |
594 | for CTRL and BULK traffic only, INTR traffic may work as well | 588 | for CTRL and BULK traffic only, INTR traffic may work as well |
595 | however (depending on the requirements of timeliness). | 589 | however (depending on the requirements of timeliness). |
596 | 590 | ||
597 | config USB | ||
598 | tristate | ||
599 | depends on ETRAX_USB_HOST | ||
600 | default y | ||
601 | |||
602 | config ETRAX_USB_HOST_PORT1 | 591 | config ETRAX_USB_HOST_PORT1 |
603 | bool " USB port 1 enabled" | 592 | bool "USB port 1 enabled" |
604 | depends on ETRAX_USB_HOST | 593 | depends on ETRAX_USB_HOST |
605 | default n | 594 | default n |
606 | 595 | ||
607 | config ETRAX_USB_HOST_PORT2 | 596 | config ETRAX_USB_HOST_PORT2 |
608 | bool " USB port 2 enabled" | 597 | bool "USB port 2 enabled" |
609 | depends on ETRAX_USB_HOST | 598 | depends on ETRAX_USB_HOST |
610 | default n | 599 | default n |
611 | 600 | ||
612 | config ETRAX_AXISFLASHMAP | 601 | config ETRAX_AXISFLASHMAP |
613 | bool "Axis flash-map support" | 602 | bool "Axis flash-map support" |
614 | depends on ETRAX_ARCH_V10 | 603 | depends on ETRAX_ARCH_V10 |
604 | select MTD | ||
605 | select MTD_CFI | ||
606 | select MTD_CFI_AMDSTD | ||
607 | select MTD_OBSOLETE_CHIPS | ||
608 | select MTD_AMDSTD | ||
609 | select MTD_CHAR | ||
610 | select MTD_BLOCK | ||
611 | select MTD_PARTITIONS | ||
612 | select MTD_CONCAT | ||
613 | select MTD_COMPLEX_MAPPINGS | ||
615 | help | 614 | help |
616 | This option enables MTD mapping of flash devices. Needed to use | 615 | This option enables MTD mapping of flash devices. Needed to use |
617 | flash memories. If unsure, say Y. | 616 | flash memories. If unsure, say Y. |
@@ -627,119 +626,6 @@ config ETRAX_PTABLE_SECTOR | |||
627 | for changing this is when the flash block size is bigger | 626 | for changing this is when the flash block size is bigger |
628 | than 64kB (e.g. when using two parallel 16 bit flashes). | 627 | than 64kB (e.g. when using two parallel 16 bit flashes). |
629 | 628 | ||
630 | # here we define the CONFIG_'s necessary to enable MTD support | ||
631 | # for the flash | ||
632 | config MTD | ||
633 | tristate | ||
634 | depends on ETRAX_AXISFLASHMAP | ||
635 | default y | ||
636 | help | ||
637 | Memory Technology Devices are flash, RAM and similar chips, often | ||
638 | used for solid state file systems on embedded devices. This option | ||
639 | will provide the generic support for MTD drivers to register | ||
640 | themselves with the kernel and for potential users of MTD devices | ||
641 | to enumerate the devices which are present and obtain a handle on | ||
642 | them. It will also allow you to select individual drivers for | ||
643 | particular hardware and users of MTD devices. If unsure, say N. | ||
644 | |||
645 | config MTD_CFI | ||
646 | tristate | ||
647 | depends on ETRAX_AXISFLASHMAP | ||
648 | default y | ||
649 | help | ||
650 | The Common Flash Interface specification was developed by Intel, | ||
651 | AMD and other flash manufactures that provides a universal method | ||
652 | for probing the capabilities of flash devices. If you wish to | ||
653 | support any device that is CFI-compliant, you need to enable this | ||
654 | option. Visit <http://www.amd.com/products/nvd/overview/cfi.html> | ||
655 | for more information on CFI. | ||
656 | |||
657 | config MTD_CFI_AMDSTD | ||
658 | tristate | ||
659 | depends on ETRAX_AXISFLASHMAP | ||
660 | default y | ||
661 | help | ||
662 | The Common Flash Interface defines a number of different command | ||
663 | sets which a CFI-compliant chip may claim to implement. This code | ||
664 | provides support for one of those command sets, used on chips | ||
665 | chips including the AMD Am29LV320. | ||
666 | |||
667 | config MTD_OBSOLETE_CHIPS | ||
668 | bool | ||
669 | depends on ETRAX_AXISFLASHMAP | ||
670 | default y | ||
671 | help | ||
672 | This option does not enable any code directly, but will allow you to | ||
673 | select some other chip drivers which are now considered obsolete, | ||
674 | because the generic CONFIG_JEDEC_PROBE code above should now detect | ||
675 | the chips which are supported by these drivers, and allow the generic | ||
676 | CFI-compatible drivers to drive the chips. Say 'N' here unless you have | ||
677 | already tried the CONFIG_JEDEC_PROBE method and reported its failure | ||
678 | to the MTD mailing list at <linux-mtd@lists.infradead.org> | ||
679 | |||
680 | config MTD_AMDSTD | ||
681 | tristate | ||
682 | depends on ETRAX_AXISFLASHMAP | ||
683 | default y | ||
684 | help | ||
685 | This option enables support for flash chips using AMD-compatible | ||
686 | commands, including some which are not CFI-compatible and hence | ||
687 | cannot be used with the CONFIG_MTD_CFI_AMDSTD option. | ||
688 | |||
689 | It also works on AMD compatible chips that do conform to CFI. | ||
690 | |||
691 | config MTD_CHAR | ||
692 | tristate | ||
693 | depends on ETRAX_AXISFLASHMAP | ||
694 | default y | ||
695 | help | ||
696 | This provides a character device for each MTD device present in | ||
697 | the system, allowing the user to read and write directly to the | ||
698 | memory chips, and also use ioctl() to obtain information about | ||
699 | the device, or to erase parts of it. | ||
700 | |||
701 | config MTD_BLOCK | ||
702 | tristate | ||
703 | depends on ETRAX_AXISFLASHMAP | ||
704 | default y | ||
705 | ---help--- | ||
706 | Although most flash chips have an erase size too large to be useful | ||
707 | as block devices, it is possible to use MTD devices which are based | ||
708 | on RAM chips in this manner. This block device is a user of MTD | ||
709 | devices performing that function. | ||
710 | |||
711 | At the moment, it is also required for the Journalling Flash File | ||
712 | System(s) to obtain a handle on the MTD device when it's mounted | ||
713 | (although JFFS and JFFS2 don't actually use any of the functionality | ||
714 | of the mtdblock device). | ||
715 | |||
716 | Later, it may be extended to perform read/erase/modify/write cycles | ||
717 | on flash chips to emulate a smaller block size. Needless to say, | ||
718 | this is very unsafe, but could be useful for file systems which are | ||
719 | almost never written to. | ||
720 | |||
721 | You do not need this option for use with the DiskOnChip devices. For | ||
722 | those, enable NFTL support (CONFIG_NFTL) instead. | ||
723 | |||
724 | config MTD_PARTITIONS | ||
725 | tristate | ||
726 | depends on ETRAX_AXISFLASHMAP | ||
727 | default y | ||
728 | help | ||
729 | If you have a device which needs to divide its flash chip(s) up | ||
730 | into multiple 'partitions', each of which appears to the user as | ||
731 | a separate MTD device, you require this option to be enabled. If | ||
732 | unsure, say 'Y'. | ||
733 | |||
734 | Note, however, that you don't need this option for the DiskOnChip | ||
735 | devices. Partitioning on NFTL 'devices' is a different - that's the | ||
736 | 'normal' form of partitioning used on a block device. | ||
737 | |||
738 | config MTD_CONCAT | ||
739 | tristate | ||
740 | depends on ETRAX_AXISFLASHMAP | ||
741 | default y | ||
742 | |||
743 | config ETRAX_I2C | 629 | config ETRAX_I2C |
744 | bool "I2C support" | 630 | bool "I2C support" |
745 | depends on ETRAX_ARCH_V10 | 631 | depends on ETRAX_ARCH_V10 |
@@ -752,7 +638,7 @@ config ETRAX_I2C | |||
752 | val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg); | 638 | val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg); |
753 | 639 | ||
754 | # this is true for most products since PB-I2C seems to be somewhat | 640 | # this is true for most products since PB-I2C seems to be somewhat |
755 | # flawed.. | 641 | # flawed.. |
756 | config ETRAX_I2C_USES_PB_NOT_PB_I2C | 642 | config ETRAX_I2C_USES_PB_NOT_PB_I2C |
757 | bool "I2C uses PB not PB-I2C" | 643 | bool "I2C uses PB not PB-I2C" |
758 | depends on ETRAX_I2C | 644 | depends on ETRAX_I2C |
@@ -886,7 +772,7 @@ config ETRAX_RTC | |||
886 | bool "Real Time Clock support" | 772 | bool "Real Time Clock support" |
887 | depends on ETRAX_ARCH_V10 | 773 | depends on ETRAX_ARCH_V10 |
888 | help | 774 | help |
889 | Enables drivers for the Real-Time Clock battery-backed chips on | 775 | Enables drivers for the Real-Time Clock battery-backed chips on |
890 | some products. The kernel reads the time when booting, and | 776 | some products. The kernel reads the time when booting, and |
891 | the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a | 777 | the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a |
892 | rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc | 778 | rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc |
@@ -903,13 +789,13 @@ config ETRAX_DS1302 | |||
903 | bool "DS1302" | 789 | bool "DS1302" |
904 | help | 790 | help |
905 | Enables the driver for the DS1302 Real-Time Clock battery-backed | 791 | Enables the driver for the DS1302 Real-Time Clock battery-backed |
906 | chip on some products. | 792 | chip on some products. |
907 | 793 | ||
908 | config ETRAX_PCF8563 | 794 | config ETRAX_PCF8563 |
909 | bool "PCF8563" | 795 | bool "PCF8563" |
910 | help | 796 | help |
911 | Enables the driver for the PCF8563 Real-Time Clock battery-backed | 797 | Enables the driver for the PCF8563 Real-Time Clock battery-backed |
912 | chip on some products. | 798 | chip on some products. |
913 | 799 | ||
914 | endchoice | 800 | endchoice |
915 | 801 | ||
@@ -954,10 +840,8 @@ config ETRAX_DS1302_TRICKLE_CHARGE | |||
954 | help | 840 | help |
955 | This controls the initial value of the trickle charge register. | 841 | This controls the initial value of the trickle charge register. |
956 | 0 = disabled (use this if you are unsure or have a non rechargable battery) | 842 | 0 = disabled (use this if you are unsure or have a non rechargable battery) |
957 | Otherwise the following values can be OR:ed together to control the | 843 | Otherwise the following values can be OR:ed together to control the |
958 | charge current: | 844 | charge current: |
959 | 1 = 2kohm, 2 = 4kohm, 3 = 4kohm | 845 | 1 = 2kohm, 2 = 4kohm, 3 = 4kohm |
960 | 4 = 1 diode, 8 = 2 diodes | 846 | 4 = 1 diode, 8 = 2 diodes |
961 | Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 | 847 | Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 |
962 | |||
963 | |||
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index fb7d4855ea62..11ab3836aac6 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * partition split defined below. | 11 | * partition split defined below. |
12 | * | 12 | * |
13 | * $Log: axisflashmap.c,v $ | 13 | * $Log: axisflashmap.c,v $ |
14 | * Revision 1.11 2004/11/15 10:27:14 starvik | ||
15 | * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>). | ||
16 | * | ||
14 | * Revision 1.10 2004/08/16 12:37:22 starvik | 17 | * Revision 1.10 2004/08/16 12:37:22 starvik |
15 | * Merge of Linux 2.6.8 | 18 | * Merge of Linux 2.6.8 |
16 | * | 19 | * |
@@ -161,7 +164,7 @@ | |||
161 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 | 164 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 |
162 | #define flash_data __u16 | 165 | #define flash_data __u16 |
163 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 | 166 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 |
164 | #define flash_data __u16 | 167 | #define flash_data __u32 |
165 | #endif | 168 | #endif |
166 | 169 | ||
167 | /* From head.S */ | 170 | /* From head.S */ |
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c index fba530fcfaeb..10795f67f687 100644 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ b/arch/cris/arch-v10/drivers/ds1302.c | |||
@@ -7,6 +7,15 @@ | |||
7 | *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init | 7 | *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init |
8 | *! | 8 | *! |
9 | *! $Log: ds1302.c,v $ | 9 | *! $Log: ds1302.c,v $ |
10 | *! Revision 1.18 2005/01/24 09:11:26 mikaelam | ||
11 | *! Minor changes to get DS1302 RTC chip driver to work | ||
12 | *! | ||
13 | *! Revision 1.17 2005/01/05 06:11:22 starvik | ||
14 | *! No need to do local_irq_disable after local_irq_save. | ||
15 | *! | ||
16 | *! Revision 1.16 2004/12/13 12:21:52 starvik | ||
17 | *! Added I/O and DMA allocators from Linux 2.4 | ||
18 | *! | ||
10 | *! Revision 1.14 2004/08/24 06:48:43 starvik | 19 | *! Revision 1.14 2004/08/24 06:48:43 starvik |
11 | *! Whitespace cleanup | 20 | *! Whitespace cleanup |
12 | *! | 21 | *! |
@@ -124,9 +133,9 @@ | |||
124 | *! | 133 | *! |
125 | *! --------------------------------------------------------------------------- | 134 | *! --------------------------------------------------------------------------- |
126 | *! | 135 | *! |
127 | *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN | 136 | *! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN |
128 | *! | 137 | *! |
129 | *! $Id: ds1302.c,v 1.14 2004/08/24 06:48:43 starvik Exp $ | 138 | *! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $ |
130 | *! | 139 | *! |
131 | *!***************************************************************************/ | 140 | *!***************************************************************************/ |
132 | 141 | ||
@@ -145,6 +154,7 @@ | |||
145 | #include <asm/arch/svinto.h> | 154 | #include <asm/arch/svinto.h> |
146 | #include <asm/io.h> | 155 | #include <asm/io.h> |
147 | #include <asm/rtc.h> | 156 | #include <asm/rtc.h> |
157 | #include <asm/arch/io_interface_mux.h> | ||
148 | 158 | ||
149 | #define RTC_MAJOR_NR 121 /* local major, change later */ | 159 | #define RTC_MAJOR_NR 121 /* local major, change later */ |
150 | 160 | ||
@@ -320,7 +330,6 @@ get_rtc_time(struct rtc_time *rtc_tm) | |||
320 | unsigned long flags; | 330 | unsigned long flags; |
321 | 331 | ||
322 | local_irq_save(flags); | 332 | local_irq_save(flags); |
323 | local_irq_disable(); | ||
324 | 333 | ||
325 | rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); | 334 | rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); |
326 | rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); | 335 | rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); |
@@ -358,7 +367,7 @@ static int | |||
358 | rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 367 | rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
359 | unsigned long arg) | 368 | unsigned long arg) |
360 | { | 369 | { |
361 | unsigned long flags; | 370 | unsigned long flags; |
362 | 371 | ||
363 | switch(cmd) { | 372 | switch(cmd) { |
364 | case RTC_RD_TIME: /* read the time/date from RTC */ | 373 | case RTC_RD_TIME: /* read the time/date from RTC */ |
@@ -382,7 +391,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
382 | return -EPERM; | 391 | return -EPERM; |
383 | 392 | ||
384 | if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) | 393 | if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) |
385 | return -EFAULT; | 394 | return -EFAULT; |
386 | 395 | ||
387 | yrs = rtc_tm.tm_year + 1900; | 396 | yrs = rtc_tm.tm_year + 1900; |
388 | mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ | 397 | mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ |
@@ -419,7 +428,6 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
419 | BIN_TO_BCD(yrs); | 428 | BIN_TO_BCD(yrs); |
420 | 429 | ||
421 | local_irq_save(flags); | 430 | local_irq_save(flags); |
422 | local_irq_disable(); | ||
423 | CMOS_WRITE(yrs, RTC_YEAR); | 431 | CMOS_WRITE(yrs, RTC_YEAR); |
424 | CMOS_WRITE(mon, RTC_MONTH); | 432 | CMOS_WRITE(mon, RTC_MONTH); |
425 | CMOS_WRITE(day, RTC_DAY_OF_MONTH); | 433 | CMOS_WRITE(day, RTC_DAY_OF_MONTH); |
@@ -438,7 +446,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
438 | 446 | ||
439 | case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */ | 447 | case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */ |
440 | { | 448 | { |
441 | int tcs_val; | 449 | int tcs_val; |
442 | 450 | ||
443 | if (!capable(CAP_SYS_TIME)) | 451 | if (!capable(CAP_SYS_TIME)) |
444 | return -EPERM; | 452 | return -EPERM; |
@@ -492,8 +500,8 @@ print_rtc_status(void) | |||
492 | /* The various file operations we support. */ | 500 | /* The various file operations we support. */ |
493 | 501 | ||
494 | static struct file_operations rtc_fops = { | 502 | static struct file_operations rtc_fops = { |
495 | .owner = THIS_MODULE, | 503 | .owner = THIS_MODULE, |
496 | .ioctl = rtc_ioctl, | 504 | .ioctl = rtc_ioctl, |
497 | }; | 505 | }; |
498 | 506 | ||
499 | /* Probe for the chip by writing something to its RAM and try reading it back. */ | 507 | /* Probe for the chip by writing something to its RAM and try reading it back. */ |
@@ -532,7 +540,7 @@ ds1302_probe(void) | |||
532 | "PB", | 540 | "PB", |
533 | #endif | 541 | #endif |
534 | CONFIG_ETRAX_DS1302_RSTBIT); | 542 | CONFIG_ETRAX_DS1302_RSTBIT); |
535 | print_rtc_status(); | 543 | print_rtc_status(); |
536 | retval = 1; | 544 | retval = 1; |
537 | } else { | 545 | } else { |
538 | stop(); | 546 | stop(); |
@@ -548,7 +556,9 @@ ds1302_probe(void) | |||
548 | int __init | 556 | int __init |
549 | ds1302_init(void) | 557 | ds1302_init(void) |
550 | { | 558 | { |
559 | #ifdef CONFIG_ETRAX_I2C | ||
551 | i2c_init(); | 560 | i2c_init(); |
561 | #endif | ||
552 | 562 | ||
553 | if (!ds1302_probe()) { | 563 | if (!ds1302_probe()) { |
554 | #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT | 564 | #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT |
@@ -558,25 +568,42 @@ ds1302_init(void) | |||
558 | * | 568 | * |
559 | * Make sure that R_GEN_CONFIG is setup correct. | 569 | * Make sure that R_GEN_CONFIG is setup correct. |
560 | */ | 570 | */ |
561 | genconfig_shadow = ((genconfig_shadow & | 571 | /* Allocating the ATA interface will grab almost all |
562 | ~IO_MASK(R_GEN_CONFIG, ata)) | | 572 | * pins in I/O groups a, b, c and d. A consequence of |
563 | (IO_STATE(R_GEN_CONFIG, ata, select))); | 573 | * allocating the ATA interface is that the fixed |
564 | *R_GEN_CONFIG = genconfig_shadow; | 574 | * interfaces shared RAM, parallel port 0, parallel |
575 | * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port | ||
576 | * 1, SCSI-W, serial port 2, serial port 3, | ||
577 | * synchronous serial port 3 and USB port 2 and almost | ||
578 | * all GPIO pins on port g cannot be used. | ||
579 | */ | ||
580 | if (cris_request_io_interface(if_ata, "ds1302/ATA")) { | ||
581 | printk(KERN_WARNING "ds1302: Failed to get IO interface\n"); | ||
582 | return -1; | ||
583 | } | ||
584 | |||
565 | #elif CONFIG_ETRAX_DS1302_RSTBIT == 0 | 585 | #elif CONFIG_ETRAX_DS1302_RSTBIT == 0 |
566 | 586 | if (cris_io_interface_allocate_pins(if_gpio_grp_a, | |
567 | /* Set the direction of this bit to out. */ | 587 | 'g', |
568 | genconfig_shadow = ((genconfig_shadow & | 588 | CONFIG_ETRAX_DS1302_RSTBIT, |
569 | ~IO_MASK(R_GEN_CONFIG, g0dir)) | | 589 | CONFIG_ETRAX_DS1302_RSTBIT)) { |
570 | (IO_STATE(R_GEN_CONFIG, g0dir, out))); | 590 | printk(KERN_WARNING "ds1302: Failed to get IO interface\n"); |
571 | *R_GEN_CONFIG = genconfig_shadow; | 591 | return -1; |
592 | } | ||
593 | |||
594 | /* Set the direction of this bit to out. */ | ||
595 | genconfig_shadow = ((genconfig_shadow & | ||
596 | ~IO_MASK(R_GEN_CONFIG, g0dir)) | | ||
597 | (IO_STATE(R_GEN_CONFIG, g0dir, out))); | ||
598 | *R_GEN_CONFIG = genconfig_shadow; | ||
572 | #endif | 599 | #endif |
573 | if (!ds1302_probe()) { | 600 | if (!ds1302_probe()) { |
574 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); | 601 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); |
575 | return -1; | 602 | return -1; |
576 | } | 603 | } |
577 | #else | 604 | #else |
578 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); | 605 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); |
579 | return -1; | 606 | return -1; |
580 | #endif | 607 | #endif |
581 | } | 608 | } |
582 | /* Initialise trickle charger */ | 609 | /* Initialise trickle charger */ |
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 316ca15d6802..512f16dec060 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c | |||
@@ -20,6 +20,12 @@ | |||
20 | *! in the spin-lock. | 20 | *! in the spin-lock. |
21 | *! | 21 | *! |
22 | *! $Log: eeprom.c,v $ | 22 | *! $Log: eeprom.c,v $ |
23 | *! Revision 1.12 2005/06/19 17:06:46 starvik | ||
24 | *! Merge of Linux 2.6.12. | ||
25 | *! | ||
26 | *! Revision 1.11 2005/01/26 07:14:46 starvik | ||
27 | *! Applied diff from kernel janitors (Nish Aravamudan). | ||
28 | *! | ||
23 | *! Revision 1.10 2003/09/11 07:29:48 starvik | 29 | *! Revision 1.10 2003/09/11 07:29:48 starvik |
24 | *! Merge of Linux 2.6.0-test5 | 30 | *! Merge of Linux 2.6.0-test5 |
25 | *! | 31 | *! |
@@ -94,6 +100,7 @@ | |||
94 | #include <linux/init.h> | 100 | #include <linux/init.h> |
95 | #include <linux/delay.h> | 101 | #include <linux/delay.h> |
96 | #include <linux/interrupt.h> | 102 | #include <linux/interrupt.h> |
103 | #include <linux/wait.h> | ||
97 | #include <asm/uaccess.h> | 104 | #include <asm/uaccess.h> |
98 | #include "i2c.h" | 105 | #include "i2c.h" |
99 | 106 | ||
@@ -526,15 +533,10 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t | |||
526 | return -EFAULT; | 533 | return -EFAULT; |
527 | } | 534 | } |
528 | 535 | ||
529 | while(eeprom.busy) | 536 | wait_event_interruptible(eeprom.wait_q, !eeprom.busy); |
530 | { | 537 | if (signal_pending(current)) |
531 | interruptible_sleep_on(&eeprom.wait_q); | 538 | return -EINTR; |
532 | 539 | ||
533 | /* bail out if we get interrupted */ | ||
534 | if (signal_pending(current)) | ||
535 | return -EINTR; | ||
536 | |||
537 | } | ||
538 | eeprom.busy++; | 540 | eeprom.busy++; |
539 | 541 | ||
540 | page = (unsigned char) (p >> 8); | 542 | page = (unsigned char) (p >> 8); |
@@ -604,13 +606,10 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | |||
604 | return -EFAULT; | 606 | return -EFAULT; |
605 | } | 607 | } |
606 | 608 | ||
607 | while(eeprom.busy) | 609 | wait_event_interruptible(eeprom.wait_q, !eeprom.busy); |
608 | { | 610 | /* bail out if we get interrupted */ |
609 | interruptible_sleep_on(&eeprom.wait_q); | 611 | if (signal_pending(current)) |
610 | /* bail out if we get interrupted */ | 612 | return -EINTR; |
611 | if (signal_pending(current)) | ||
612 | return -EINTR; | ||
613 | } | ||
614 | eeprom.busy++; | 613 | eeprom.busy++; |
615 | for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) | 614 | for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) |
616 | { | 615 | { |
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index c095de82a0da..09963fe299a7 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: gpio.c,v 1.12 2004/08/24 07:19:59 starvik Exp $ | 1 | /* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $ |
2 | * | 2 | * |
3 | * Etrax general port I/O device | 3 | * Etrax general port I/O device |
4 | * | 4 | * |
@@ -9,6 +9,18 @@ | |||
9 | * Johan Adolfsson (read/set directions, write, port G) | 9 | * Johan Adolfsson (read/set directions, write, port G) |
10 | * | 10 | * |
11 | * $Log: gpio.c,v $ | 11 | * $Log: gpio.c,v $ |
12 | * Revision 1.17 2005/06/19 17:06:46 starvik | ||
13 | * Merge of Linux 2.6.12. | ||
14 | * | ||
15 | * Revision 1.16 2005/03/07 13:02:29 starvik | ||
16 | * Protect driver global states with spinlock | ||
17 | * | ||
18 | * Revision 1.15 2005/01/05 06:08:55 starvik | ||
19 | * No need to do local_irq_disable after local_irq_save. | ||
20 | * | ||
21 | * Revision 1.14 2004/12/13 12:21:52 starvik | ||
22 | * Added I/O and DMA allocators from Linux 2.4 | ||
23 | * | ||
12 | * Revision 1.12 2004/08/24 07:19:59 starvik | 24 | * Revision 1.12 2004/08/24 07:19:59 starvik |
13 | * Whitespace cleanup | 25 | * Whitespace cleanup |
14 | * | 26 | * |
@@ -142,6 +154,7 @@ | |||
142 | #include <asm/io.h> | 154 | #include <asm/io.h> |
143 | #include <asm/system.h> | 155 | #include <asm/system.h> |
144 | #include <asm/irq.h> | 156 | #include <asm/irq.h> |
157 | #include <asm/arch/io_interface_mux.h> | ||
145 | 158 | ||
146 | #define GPIO_MAJOR 120 /* experimental MAJOR number */ | 159 | #define GPIO_MAJOR 120 /* experimental MAJOR number */ |
147 | 160 | ||
@@ -194,6 +207,8 @@ static struct gpio_private *alarmlist = 0; | |||
194 | static int gpio_some_alarms = 0; /* Set if someone uses alarm */ | 207 | static int gpio_some_alarms = 0; /* Set if someone uses alarm */ |
195 | static unsigned long gpio_pa_irq_enabled_mask = 0; | 208 | static unsigned long gpio_pa_irq_enabled_mask = 0; |
196 | 209 | ||
210 | static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */ | ||
211 | |||
197 | /* Port A and B use 8 bit access, but Port G is 32 bit */ | 212 | /* Port A and B use 8 bit access, but Port G is 32 bit */ |
198 | #define NUM_PORTS (GPIO_MINOR_B+1) | 213 | #define NUM_PORTS (GPIO_MINOR_B+1) |
199 | 214 | ||
@@ -241,6 +256,9 @@ static volatile unsigned char *dir_shadow[NUM_PORTS] = { | |||
241 | &port_pb_dir_shadow | 256 | &port_pb_dir_shadow |
242 | }; | 257 | }; |
243 | 258 | ||
259 | /* All bits in port g that can change dir. */ | ||
260 | static const unsigned long int changeable_dir_g_mask = 0x01FFFF01; | ||
261 | |||
244 | /* Port G is 32 bit, handle it special, some bits are both inputs | 262 | /* Port G is 32 bit, handle it special, some bits are both inputs |
245 | and outputs at the same time, only some of the bits can change direction | 263 | and outputs at the same time, only some of the bits can change direction |
246 | and some of them in groups of 8 bit. */ | 264 | and some of them in groups of 8 bit. */ |
@@ -260,6 +278,7 @@ gpio_poll(struct file *file, | |||
260 | unsigned int mask = 0; | 278 | unsigned int mask = 0; |
261 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 279 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
262 | unsigned long data; | 280 | unsigned long data; |
281 | spin_lock(&gpio_lock); | ||
263 | poll_wait(file, &priv->alarm_wq, wait); | 282 | poll_wait(file, &priv->alarm_wq, wait); |
264 | if (priv->minor == GPIO_MINOR_A) { | 283 | if (priv->minor == GPIO_MINOR_A) { |
265 | unsigned long flags; | 284 | unsigned long flags; |
@@ -270,10 +289,10 @@ gpio_poll(struct file *file, | |||
270 | */ | 289 | */ |
271 | tmp = ~data & priv->highalarm & 0xFF; | 290 | tmp = ~data & priv->highalarm & 0xFF; |
272 | tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); | 291 | tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); |
273 | save_flags(flags); cli(); | 292 | local_irq_save(flags); |
274 | gpio_pa_irq_enabled_mask |= tmp; | 293 | gpio_pa_irq_enabled_mask |= tmp; |
275 | *R_IRQ_MASK1_SET = tmp; | 294 | *R_IRQ_MASK1_SET = tmp; |
276 | restore_flags(flags); | 295 | local_irq_restore(flags); |
277 | 296 | ||
278 | } else if (priv->minor == GPIO_MINOR_B) | 297 | } else if (priv->minor == GPIO_MINOR_B) |
279 | data = *R_PORT_PB_DATA; | 298 | data = *R_PORT_PB_DATA; |
@@ -286,8 +305,11 @@ gpio_poll(struct file *file, | |||
286 | (~data & priv->lowalarm)) { | 305 | (~data & priv->lowalarm)) { |
287 | mask = POLLIN|POLLRDNORM; | 306 | mask = POLLIN|POLLRDNORM; |
288 | } | 307 | } |
308 | |||
309 | spin_unlock(&gpio_lock); | ||
289 | 310 | ||
290 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); | 311 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); |
312 | |||
291 | return mask; | 313 | return mask; |
292 | } | 314 | } |
293 | 315 | ||
@@ -296,6 +318,7 @@ int etrax_gpio_wake_up_check(void) | |||
296 | struct gpio_private *priv = alarmlist; | 318 | struct gpio_private *priv = alarmlist; |
297 | unsigned long data = 0; | 319 | unsigned long data = 0; |
298 | int ret = 0; | 320 | int ret = 0; |
321 | spin_lock(&gpio_lock); | ||
299 | while (priv) { | 322 | while (priv) { |
300 | if (USE_PORTS(priv)) { | 323 | if (USE_PORTS(priv)) { |
301 | data = *priv->port; | 324 | data = *priv->port; |
@@ -310,6 +333,7 @@ int etrax_gpio_wake_up_check(void) | |||
310 | } | 333 | } |
311 | priv = priv->next; | 334 | priv = priv->next; |
312 | } | 335 | } |
336 | spin_unlock(&gpio_lock); | ||
313 | return ret; | 337 | return ret; |
314 | } | 338 | } |
315 | 339 | ||
@@ -327,6 +351,7 @@ static irqreturn_t | |||
327 | gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 351 | gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
328 | { | 352 | { |
329 | unsigned long tmp; | 353 | unsigned long tmp; |
354 | spin_lock(&gpio_lock); | ||
330 | /* Find what PA interrupts are active */ | 355 | /* Find what PA interrupts are active */ |
331 | tmp = (*R_IRQ_READ1); | 356 | tmp = (*R_IRQ_READ1); |
332 | 357 | ||
@@ -337,6 +362,8 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
337 | *R_IRQ_MASK1_CLR = tmp; | 362 | *R_IRQ_MASK1_CLR = tmp; |
338 | gpio_pa_irq_enabled_mask &= ~tmp; | 363 | gpio_pa_irq_enabled_mask &= ~tmp; |
339 | 364 | ||
365 | spin_unlock(&gpio_lock); | ||
366 | |||
340 | if (gpio_some_alarms) { | 367 | if (gpio_some_alarms) { |
341 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); | 368 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); |
342 | } | 369 | } |
@@ -350,6 +377,9 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
350 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 377 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
351 | unsigned char data, clk_mask, data_mask, write_msb; | 378 | unsigned char data, clk_mask, data_mask, write_msb; |
352 | unsigned long flags; | 379 | unsigned long flags; |
380 | |||
381 | spin_lock(&gpio_lock); | ||
382 | |||
353 | ssize_t retval = count; | 383 | ssize_t retval = count; |
354 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { | 384 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { |
355 | return -EFAULT; | 385 | return -EFAULT; |
@@ -372,7 +402,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
372 | data = *buf++; | 402 | data = *buf++; |
373 | if (priv->write_msb) { | 403 | if (priv->write_msb) { |
374 | for (i = 7; i >= 0;i--) { | 404 | for (i = 7; i >= 0;i--) { |
375 | local_irq_save(flags); local_irq_disable(); | 405 | local_irq_save(flags); |
376 | *priv->port = *priv->shadow &= ~clk_mask; | 406 | *priv->port = *priv->shadow &= ~clk_mask; |
377 | if (data & 1<<i) | 407 | if (data & 1<<i) |
378 | *priv->port = *priv->shadow |= data_mask; | 408 | *priv->port = *priv->shadow |= data_mask; |
@@ -384,7 +414,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
384 | } | 414 | } |
385 | } else { | 415 | } else { |
386 | for (i = 0; i <= 7;i++) { | 416 | for (i = 0; i <= 7;i++) { |
387 | local_irq_save(flags); local_irq_disable(); | 417 | local_irq_save(flags); |
388 | *priv->port = *priv->shadow &= ~clk_mask; | 418 | *priv->port = *priv->shadow &= ~clk_mask; |
389 | if (data & 1<<i) | 419 | if (data & 1<<i) |
390 | *priv->port = *priv->shadow |= data_mask; | 420 | *priv->port = *priv->shadow |= data_mask; |
@@ -396,6 +426,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
396 | } | 426 | } |
397 | } | 427 | } |
398 | } | 428 | } |
429 | spin_unlock(&gpio_lock); | ||
399 | return retval; | 430 | return retval; |
400 | } | 431 | } |
401 | 432 | ||
@@ -452,9 +483,14 @@ gpio_open(struct inode *inode, struct file *filp) | |||
452 | static int | 483 | static int |
453 | gpio_release(struct inode *inode, struct file *filp) | 484 | gpio_release(struct inode *inode, struct file *filp) |
454 | { | 485 | { |
455 | struct gpio_private *p = alarmlist; | 486 | struct gpio_private *p; |
456 | struct gpio_private *todel = (struct gpio_private *)filp->private_data; | 487 | struct gpio_private *todel; |
457 | 488 | ||
489 | spin_lock(&gpio_lock); | ||
490 | |||
491 | p = alarmlist; | ||
492 | todel = (struct gpio_private *)filp->private_data; | ||
493 | |||
458 | /* unlink from alarmlist and free the private structure */ | 494 | /* unlink from alarmlist and free the private structure */ |
459 | 495 | ||
460 | if (p == todel) { | 496 | if (p == todel) { |
@@ -476,7 +512,7 @@ gpio_release(struct inode *inode, struct file *filp) | |||
476 | p = p->next; | 512 | p = p->next; |
477 | } | 513 | } |
478 | gpio_some_alarms = 0; | 514 | gpio_some_alarms = 0; |
479 | 515 | spin_unlock(&gpio_lock); | |
480 | return 0; | 516 | return 0; |
481 | } | 517 | } |
482 | 518 | ||
@@ -491,14 +527,14 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | |||
491 | */ | 527 | */ |
492 | unsigned long flags; | 528 | unsigned long flags; |
493 | if (USE_PORTS(priv)) { | 529 | if (USE_PORTS(priv)) { |
494 | local_irq_save(flags); local_irq_disable(); | 530 | local_irq_save(flags); |
495 | *priv->dir = *priv->dir_shadow &= | 531 | *priv->dir = *priv->dir_shadow &= |
496 | ~((unsigned char)arg & priv->changeable_dir); | 532 | ~((unsigned char)arg & priv->changeable_dir); |
497 | local_irq_restore(flags); | 533 | local_irq_restore(flags); |
498 | return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ | 534 | return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ |
499 | } else if (priv->minor == GPIO_MINOR_G) { | 535 | } else if (priv->minor == GPIO_MINOR_G) { |
500 | /* We must fiddle with R_GEN_CONFIG to change dir */ | 536 | /* We must fiddle with R_GEN_CONFIG to change dir */ |
501 | save_flags(flags); cli(); | 537 | local_irq_save(flags); |
502 | if (((arg & dir_g_in_bits) != arg) && | 538 | if (((arg & dir_g_in_bits) != arg) && |
503 | (arg & changeable_dir_g)) { | 539 | (arg & changeable_dir_g)) { |
504 | arg &= changeable_dir_g; | 540 | arg &= changeable_dir_g; |
@@ -533,7 +569,7 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | |||
533 | /* Must be a >120 ns delay before writing this again */ | 569 | /* Must be a >120 ns delay before writing this again */ |
534 | 570 | ||
535 | } | 571 | } |
536 | restore_flags(flags); | 572 | local_irq_restore(flags); |
537 | return dir_g_in_bits; | 573 | return dir_g_in_bits; |
538 | } | 574 | } |
539 | return 0; | 575 | return 0; |
@@ -543,14 +579,14 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) | |||
543 | { | 579 | { |
544 | unsigned long flags; | 580 | unsigned long flags; |
545 | if (USE_PORTS(priv)) { | 581 | if (USE_PORTS(priv)) { |
546 | local_irq_save(flags); local_irq_disable(); | 582 | local_irq_save(flags); |
547 | *priv->dir = *priv->dir_shadow |= | 583 | *priv->dir = *priv->dir_shadow |= |
548 | ((unsigned char)arg & priv->changeable_dir); | 584 | ((unsigned char)arg & priv->changeable_dir); |
549 | local_irq_restore(flags); | 585 | local_irq_restore(flags); |
550 | return *priv->dir_shadow; | 586 | return *priv->dir_shadow; |
551 | } else if (priv->minor == GPIO_MINOR_G) { | 587 | } else if (priv->minor == GPIO_MINOR_G) { |
552 | /* We must fiddle with R_GEN_CONFIG to change dir */ | 588 | /* We must fiddle with R_GEN_CONFIG to change dir */ |
553 | save_flags(flags); cli(); | 589 | local_irq_save(flags); |
554 | if (((arg & dir_g_out_bits) != arg) && | 590 | if (((arg & dir_g_out_bits) != arg) && |
555 | (arg & changeable_dir_g)) { | 591 | (arg & changeable_dir_g)) { |
556 | /* Set bits in genconfig to set to output */ | 592 | /* Set bits in genconfig to set to output */ |
@@ -583,7 +619,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) | |||
583 | *R_GEN_CONFIG = genconfig_shadow; | 619 | *R_GEN_CONFIG = genconfig_shadow; |
584 | /* Must be a >120 ns delay before writing this again */ | 620 | /* Must be a >120 ns delay before writing this again */ |
585 | } | 621 | } |
586 | restore_flags(flags); | 622 | local_irq_restore(flags); |
587 | return dir_g_out_bits & 0x7FFFFFFF; | 623 | return dir_g_out_bits & 0x7FFFFFFF; |
588 | } | 624 | } |
589 | return 0; | 625 | return 0; |
@@ -598,22 +634,26 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
598 | { | 634 | { |
599 | unsigned long flags; | 635 | unsigned long flags; |
600 | unsigned long val; | 636 | unsigned long val; |
637 | int ret = 0; | ||
638 | |||
601 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 639 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
602 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { | 640 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { |
603 | return -EINVAL; | 641 | return -EINVAL; |
604 | } | 642 | } |
605 | 643 | ||
644 | spin_lock(&gpio_lock); | ||
645 | |||
606 | switch (_IOC_NR(cmd)) { | 646 | switch (_IOC_NR(cmd)) { |
607 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ | 647 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ |
608 | // read the port | 648 | // read the port |
609 | if (USE_PORTS(priv)) { | 649 | if (USE_PORTS(priv)) { |
610 | return *priv->port; | 650 | ret = *priv->port; |
611 | } else if (priv->minor == GPIO_MINOR_G) { | 651 | } else if (priv->minor == GPIO_MINOR_G) { |
612 | return (*R_PORT_G_DATA) & 0x7FFFFFFF; | 652 | ret = (*R_PORT_G_DATA) & 0x7FFFFFFF; |
613 | } | 653 | } |
614 | break; | 654 | break; |
615 | case IO_SETBITS: | 655 | case IO_SETBITS: |
616 | local_irq_save(flags); local_irq_disable(); | 656 | local_irq_save(flags); |
617 | // set changeable bits with a 1 in arg | 657 | // set changeable bits with a 1 in arg |
618 | if (USE_PORTS(priv)) { | 658 | if (USE_PORTS(priv)) { |
619 | *priv->port = *priv->shadow |= | 659 | *priv->port = *priv->shadow |= |
@@ -624,7 +664,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
624 | local_irq_restore(flags); | 664 | local_irq_restore(flags); |
625 | break; | 665 | break; |
626 | case IO_CLRBITS: | 666 | case IO_CLRBITS: |
627 | local_irq_save(flags); local_irq_disable(); | 667 | local_irq_save(flags); |
628 | // clear changeable bits with a 1 in arg | 668 | // clear changeable bits with a 1 in arg |
629 | if (USE_PORTS(priv)) { | 669 | if (USE_PORTS(priv)) { |
630 | *priv->port = *priv->shadow &= | 670 | *priv->port = *priv->shadow &= |
@@ -666,33 +706,34 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
666 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ | 706 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ |
667 | /* Read direction 0=input 1=output */ | 707 | /* Read direction 0=input 1=output */ |
668 | if (USE_PORTS(priv)) { | 708 | if (USE_PORTS(priv)) { |
669 | return *priv->dir_shadow; | 709 | ret = *priv->dir_shadow; |
670 | } else if (priv->minor == GPIO_MINOR_G) { | 710 | } else if (priv->minor == GPIO_MINOR_G) { |
671 | /* Note: Some bits are both in and out, | 711 | /* Note: Some bits are both in and out, |
672 | * Those that are dual is set here as well. | 712 | * Those that are dual is set here as well. |
673 | */ | 713 | */ |
674 | return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF; | 714 | ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF; |
675 | } | 715 | } |
716 | break; | ||
676 | case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */ | 717 | case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */ |
677 | /* Set direction 0=unchanged 1=input, | 718 | /* Set direction 0=unchanged 1=input, |
678 | * return mask with 1=input | 719 | * return mask with 1=input |
679 | */ | 720 | */ |
680 | return setget_input(priv, arg) & 0x7FFFFFFF; | 721 | ret = setget_input(priv, arg) & 0x7FFFFFFF; |
681 | break; | 722 | break; |
682 | case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */ | 723 | case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */ |
683 | /* Set direction 0=unchanged 1=output, | 724 | /* Set direction 0=unchanged 1=output, |
684 | * return mask with 1=output | 725 | * return mask with 1=output |
685 | */ | 726 | */ |
686 | return setget_output(priv, arg) & 0x7FFFFFFF; | 727 | ret = setget_output(priv, arg) & 0x7FFFFFFF; |
687 | 728 | break; | |
688 | case IO_SHUTDOWN: | 729 | case IO_SHUTDOWN: |
689 | SOFT_SHUTDOWN(); | 730 | SOFT_SHUTDOWN(); |
690 | break; | 731 | break; |
691 | case IO_GET_PWR_BT: | 732 | case IO_GET_PWR_BT: |
692 | #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN) | 733 | #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN) |
693 | return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT)); | 734 | ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT)); |
694 | #else | 735 | #else |
695 | return 0; | 736 | ret = 0; |
696 | #endif | 737 | #endif |
697 | break; | 738 | break; |
698 | case IO_CFG_WRITE_MODE: | 739 | case IO_CFG_WRITE_MODE: |
@@ -709,7 +750,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
709 | { | 750 | { |
710 | priv->clk_mask = 0; | 751 | priv->clk_mask = 0; |
711 | priv->data_mask = 0; | 752 | priv->data_mask = 0; |
712 | return -EPERM; | 753 | ret = -EPERM; |
713 | } | 754 | } |
714 | break; | 755 | break; |
715 | case IO_READ_INBITS: | 756 | case IO_READ_INBITS: |
@@ -720,8 +761,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
720 | val = *R_PORT_G_DATA; | 761 | val = *R_PORT_G_DATA; |
721 | } | 762 | } |
722 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 763 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) |
723 | return -EFAULT; | 764 | ret = -EFAULT; |
724 | return 0; | ||
725 | break; | 765 | break; |
726 | case IO_READ_OUTBITS: | 766 | case IO_READ_OUTBITS: |
727 | /* *arg is result of reading the output shadow */ | 767 | /* *arg is result of reading the output shadow */ |
@@ -731,36 +771,43 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
731 | val = port_g_data_shadow; | 771 | val = port_g_data_shadow; |
732 | } | 772 | } |
733 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 773 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) |
734 | return -EFAULT; | 774 | ret = -EFAULT; |
735 | break; | 775 | break; |
736 | case IO_SETGET_INPUT: | 776 | case IO_SETGET_INPUT: |
737 | /* bits set in *arg is set to input, | 777 | /* bits set in *arg is set to input, |
738 | * *arg updated with current input pins. | 778 | * *arg updated with current input pins. |
739 | */ | 779 | */ |
740 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 780 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) |
741 | return -EFAULT; | 781 | { |
782 | ret = -EFAULT; | ||
783 | break; | ||
784 | } | ||
742 | val = setget_input(priv, val); | 785 | val = setget_input(priv, val); |
743 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 786 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) |
744 | return -EFAULT; | 787 | ret = -EFAULT; |
745 | break; | 788 | break; |
746 | case IO_SETGET_OUTPUT: | 789 | case IO_SETGET_OUTPUT: |
747 | /* bits set in *arg is set to output, | 790 | /* bits set in *arg is set to output, |
748 | * *arg updated with current output pins. | 791 | * *arg updated with current output pins. |
749 | */ | 792 | */ |
750 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 793 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) |
751 | return -EFAULT; | 794 | { |
795 | ret = -EFAULT; | ||
796 | break; | ||
797 | } | ||
752 | val = setget_output(priv, val); | 798 | val = setget_output(priv, val); |
753 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 799 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) |
754 | return -EFAULT; | 800 | ret = -EFAULT; |
755 | break; | 801 | break; |
756 | default: | 802 | default: |
757 | if (priv->minor == GPIO_MINOR_LEDS) | 803 | if (priv->minor == GPIO_MINOR_LEDS) |
758 | return gpio_leds_ioctl(cmd, arg); | 804 | ret = gpio_leds_ioctl(cmd, arg); |
759 | else | 805 | else |
760 | return -EINVAL; | 806 | ret = -EINVAL; |
761 | } /* switch */ | 807 | } /* switch */ |
762 | 808 | ||
763 | return 0; | 809 | spin_unlock(&gpio_lock); |
810 | return ret; | ||
764 | } | 811 | } |
765 | 812 | ||
766 | static int | 813 | static int |
@@ -802,60 +849,20 @@ struct file_operations gpio_fops = { | |||
802 | }; | 849 | }; |
803 | 850 | ||
804 | 851 | ||
805 | static void __init gpio_init_port_g(void) | 852 | void ioif_watcher(const unsigned int gpio_in_available, |
853 | const unsigned int gpio_out_available, | ||
854 | const unsigned char pa_available, | ||
855 | const unsigned char pb_available) | ||
806 | { | 856 | { |
807 | #define GROUPA (0x0000FF3F) | 857 | unsigned long int flags; |
808 | #define GROUPB (1<<6 | 1<<7) | 858 | D(printk("gpio.c: ioif_watcher called\n")); |
809 | #define GROUPC (1<<30 | 1<<31) | 859 | D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n", |
810 | #define GROUPD (0x3FFF0000) | 860 | gpio_in_available, gpio_out_available, pa_available, pb_available)); |
811 | #define GROUPD_LOW (0x00FF0000) | ||
812 | unsigned long used_in_bits = 0; | ||
813 | unsigned long used_out_bits = 0; | ||
814 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){ | ||
815 | used_in_bits |= GROUPA | GROUPB | 0 | 0; | ||
816 | used_out_bits |= GROUPA | GROUPB | 0 | 0; | ||
817 | } | ||
818 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) { | ||
819 | used_in_bits |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26)); | ||
820 | used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD; | ||
821 | } | ||
822 | 861 | ||
823 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) { | 862 | spin_lock_irqsave(&gpio_lock, flags); |
824 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0; | ||
825 | used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0; | ||
826 | } | ||
827 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) { | ||
828 | used_in_bits |= 0 | GROUPB | 0 | 0; | ||
829 | used_out_bits |= 0 | GROUPB | 0 | 0; | ||
830 | } | ||
831 | /* mio same as shared RAM ? */ | ||
832 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) { | ||
833 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW; | ||
834 | used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW; | ||
835 | } | ||
836 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) { | ||
837 | used_in_bits |= 0 | 0 | GROUPC | GROUPD; | ||
838 | used_out_bits |= 0 | 0 | GROUPC | GROUPD; | ||
839 | } | ||
840 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) { | ||
841 | used_in_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24); | ||
842 | used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26); | ||
843 | } | ||
844 | 863 | ||
845 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) { | 864 | dir_g_in_bits = gpio_in_available; |
846 | used_in_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24)); | 865 | dir_g_out_bits = gpio_out_available; |
847 | used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24)); | ||
848 | } | ||
849 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) { | ||
850 | used_in_bits |= 0 | 0 | GROUPC | 0; | ||
851 | used_out_bits |= 0 | 0 | GROUPC | 0; | ||
852 | } | ||
853 | /* mio same as shared RAM-W? */ | ||
854 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) { | ||
855 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW; | ||
856 | used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW; | ||
857 | } | ||
858 | /* TODO: USB p2, parw, sync ser3? */ | ||
859 | 866 | ||
860 | /* Initialise the dir_g_shadow etc. depending on genconfig */ | 867 | /* Initialise the dir_g_shadow etc. depending on genconfig */ |
861 | /* 0=input 1=output */ | 868 | /* 0=input 1=output */ |
@@ -868,10 +875,7 @@ static void __init gpio_init_port_g(void) | |||
868 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out)) | 875 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out)) |
869 | dir_g_shadow |= (1 << 24); | 876 | dir_g_shadow |= (1 << 24); |
870 | 877 | ||
871 | dir_g_in_bits = ~used_in_bits; | 878 | changeable_dir_g = changeable_dir_g_mask; |
872 | dir_g_out_bits = ~used_out_bits; | ||
873 | |||
874 | changeable_dir_g = 0x01FFFF01; /* all that can change dir */ | ||
875 | changeable_dir_g &= dir_g_out_bits; | 879 | changeable_dir_g &= dir_g_out_bits; |
876 | changeable_dir_g &= dir_g_in_bits; | 880 | changeable_dir_g &= dir_g_in_bits; |
877 | /* Correct the bits that can change direction */ | 881 | /* Correct the bits that can change direction */ |
@@ -880,6 +884,7 @@ static void __init gpio_init_port_g(void) | |||
880 | dir_g_in_bits &= ~changeable_dir_g; | 884 | dir_g_in_bits &= ~changeable_dir_g; |
881 | dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); | 885 | dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); |
882 | 886 | ||
887 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
883 | 888 | ||
884 | printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", | 889 | printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", |
885 | dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); | 890 | dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); |
@@ -896,6 +901,7 @@ gpio_init(void) | |||
896 | #if defined (CONFIG_ETRAX_CSP0_LEDS) | 901 | #if defined (CONFIG_ETRAX_CSP0_LEDS) |
897 | int i; | 902 | int i; |
898 | #endif | 903 | #endif |
904 | printk("gpio init\n"); | ||
899 | 905 | ||
900 | /* do the formalities */ | 906 | /* do the formalities */ |
901 | 907 | ||
@@ -919,8 +925,13 @@ gpio_init(void) | |||
919 | #endif | 925 | #endif |
920 | 926 | ||
921 | #endif | 927 | #endif |
922 | gpio_init_port_g(); | 928 | /* The I/O interface allocation watcher will be called when |
923 | printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); | 929 | * registering it. */ |
930 | if (cris_io_interface_register_watcher(ioif_watcher)){ | ||
931 | printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n"); | ||
932 | } | ||
933 | |||
934 | printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n"); | ||
924 | /* We call etrax_gpio_wake_up_check() from timer interrupt and | 935 | /* We call etrax_gpio_wake_up_check() from timer interrupt and |
925 | * from cpu_idle() in kernel/process.c | 936 | * from cpu_idle() in kernel/process.c |
926 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms | 937 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms |
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index 8bbe233ba7b1..b38267d60d30 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c | |||
@@ -12,6 +12,15 @@ | |||
12 | *! don't use PB_I2C if DS1302 uses same bits, | 12 | *! don't use PB_I2C if DS1302 uses same bits, |
13 | *! use PB. | 13 | *! use PB. |
14 | *! $Log: i2c.c,v $ | 14 | *! $Log: i2c.c,v $ |
15 | *! Revision 1.13 2005/03/07 13:13:07 starvik | ||
16 | *! Added spinlocks to protect states etc | ||
17 | *! | ||
18 | *! Revision 1.12 2005/01/05 06:11:22 starvik | ||
19 | *! No need to do local_irq_disable after local_irq_save. | ||
20 | *! | ||
21 | *! Revision 1.11 2004/12/13 12:21:52 starvik | ||
22 | *! Added I/O and DMA allocators from Linux 2.4 | ||
23 | *! | ||
15 | *! Revision 1.9 2004/08/24 06:49:14 starvik | 24 | *! Revision 1.9 2004/08/24 06:49:14 starvik |
16 | *! Whitespace cleanup | 25 | *! Whitespace cleanup |
17 | *! | 26 | *! |
@@ -75,7 +84,7 @@ | |||
75 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN | 84 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN |
76 | *! | 85 | *! |
77 | *!***************************************************************************/ | 86 | *!***************************************************************************/ |
78 | /* $Id: i2c.c,v 1.9 2004/08/24 06:49:14 starvik Exp $ */ | 87 | /* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */ |
79 | 88 | ||
80 | /****************** INCLUDE FILES SECTION ***********************************/ | 89 | /****************** INCLUDE FILES SECTION ***********************************/ |
81 | 90 | ||
@@ -95,6 +104,7 @@ | |||
95 | #include <asm/arch/svinto.h> | 104 | #include <asm/arch/svinto.h> |
96 | #include <asm/io.h> | 105 | #include <asm/io.h> |
97 | #include <asm/delay.h> | 106 | #include <asm/delay.h> |
107 | #include <asm/arch/io_interface_mux.h> | ||
98 | 108 | ||
99 | #include "i2c.h" | 109 | #include "i2c.h" |
100 | 110 | ||
@@ -184,6 +194,7 @@ static const char i2c_name[] = "i2c"; | |||
184 | 194 | ||
185 | #define i2c_delay(usecs) udelay(usecs) | 195 | #define i2c_delay(usecs) udelay(usecs) |
186 | 196 | ||
197 | static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */ | ||
187 | 198 | ||
188 | /****************** FUNCTION DEFINITION SECTION *************************/ | 199 | /****************** FUNCTION DEFINITION SECTION *************************/ |
189 | 200 | ||
@@ -488,13 +499,14 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, | |||
488 | int error, cntr = 3; | 499 | int error, cntr = 3; |
489 | unsigned long flags; | 500 | unsigned long flags; |
490 | 501 | ||
502 | spin_lock(&i2c_lock); | ||
503 | |||
491 | do { | 504 | do { |
492 | error = 0; | 505 | error = 0; |
493 | /* | 506 | /* |
494 | * we don't like to be interrupted | 507 | * we don't like to be interrupted |
495 | */ | 508 | */ |
496 | local_irq_save(flags); | 509 | local_irq_save(flags); |
497 | local_irq_disable(); | ||
498 | 510 | ||
499 | i2c_start(); | 511 | i2c_start(); |
500 | /* | 512 | /* |
@@ -538,6 +550,8 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, | |||
538 | 550 | ||
539 | i2c_delay(CLOCK_LOW_TIME); | 551 | i2c_delay(CLOCK_LOW_TIME); |
540 | 552 | ||
553 | spin_unlock(&i2c_lock); | ||
554 | |||
541 | return -error; | 555 | return -error; |
542 | } | 556 | } |
543 | 557 | ||
@@ -555,13 +569,14 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
555 | int error, cntr = 3; | 569 | int error, cntr = 3; |
556 | unsigned long flags; | 570 | unsigned long flags; |
557 | 571 | ||
572 | spin_lock(&i2c_lock); | ||
573 | |||
558 | do { | 574 | do { |
559 | error = 0; | 575 | error = 0; |
560 | /* | 576 | /* |
561 | * we don't like to be interrupted | 577 | * we don't like to be interrupted |
562 | */ | 578 | */ |
563 | local_irq_save(flags); | 579 | local_irq_save(flags); |
564 | local_irq_disable(); | ||
565 | /* | 580 | /* |
566 | * generate start condition | 581 | * generate start condition |
567 | */ | 582 | */ |
@@ -620,6 +635,8 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
620 | 635 | ||
621 | } while(error && cntr--); | 636 | } while(error && cntr--); |
622 | 637 | ||
638 | spin_unlock(&i2c_lock); | ||
639 | |||
623 | return b; | 640 | return b; |
624 | } | 641 | } |
625 | 642 | ||
@@ -686,15 +703,26 @@ static struct file_operations i2c_fops = { | |||
686 | int __init | 703 | int __init |
687 | i2c_init(void) | 704 | i2c_init(void) |
688 | { | 705 | { |
706 | static int res = 0; | ||
707 | static int first = 1; | ||
708 | |||
709 | if (!first) { | ||
710 | return res; | ||
711 | } | ||
712 | |||
689 | /* Setup and enable the Port B I2C interface */ | 713 | /* Setup and enable the Port B I2C interface */ |
690 | 714 | ||
691 | #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C | 715 | #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C |
716 | if ((res = cris_request_io_interface(if_i2c, "I2C"))) { | ||
717 | printk(KERN_CRIT "i2c_init: Failed to get IO interface\n"); | ||
718 | return res; | ||
719 | } | ||
720 | |||
692 | *R_PORT_PB_I2C = port_pb_i2c_shadow |= | 721 | *R_PORT_PB_I2C = port_pb_i2c_shadow |= |
693 | IO_STATE(R_PORT_PB_I2C, i2c_en, on) | | 722 | IO_STATE(R_PORT_PB_I2C, i2c_en, on) | |
694 | IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) | | 723 | IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) | |
695 | IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) | | 724 | IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) | |
696 | IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable); | 725 | IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable); |
697 | #endif | ||
698 | 726 | ||
699 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0); | 727 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0); |
700 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1); | 728 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1); |
@@ -702,8 +730,26 @@ i2c_init(void) | |||
702 | *R_PORT_PB_DIR = (port_pb_dir_shadow |= | 730 | *R_PORT_PB_DIR = (port_pb_dir_shadow |= |
703 | IO_STATE(R_PORT_PB_DIR, dir0, input) | | 731 | IO_STATE(R_PORT_PB_DIR, dir0, input) | |
704 | IO_STATE(R_PORT_PB_DIR, dir1, output)); | 732 | IO_STATE(R_PORT_PB_DIR, dir1, output)); |
733 | #else | ||
734 | if ((res = cris_io_interface_allocate_pins(if_i2c, | ||
735 | 'b', | ||
736 | CONFIG_ETRAX_I2C_DATA_PORT, | ||
737 | CONFIG_ETRAX_I2C_DATA_PORT))) { | ||
738 | printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n"); | ||
739 | return res; | ||
740 | } else if ((res = cris_io_interface_allocate_pins(if_i2c, | ||
741 | 'b', | ||
742 | CONFIG_ETRAX_I2C_CLK_PORT, | ||
743 | CONFIG_ETRAX_I2C_CLK_PORT))) { | ||
744 | cris_io_interface_free_pins(if_i2c, | ||
745 | 'b', | ||
746 | CONFIG_ETRAX_I2C_DATA_PORT, | ||
747 | CONFIG_ETRAX_I2C_DATA_PORT); | ||
748 | printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n"); | ||
749 | } | ||
750 | #endif | ||
705 | 751 | ||
706 | return 0; | 752 | return res; |
707 | } | 753 | } |
708 | 754 | ||
709 | static int __init | 755 | static int __init |
@@ -711,14 +757,16 @@ i2c_register(void) | |||
711 | { | 757 | { |
712 | int res; | 758 | int res; |
713 | 759 | ||
714 | i2c_init(); | 760 | res = i2c_init(); |
761 | if (res < 0) | ||
762 | return res; | ||
715 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); | 763 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); |
716 | if(res < 0) { | 764 | if(res < 0) { |
717 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); | 765 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); |
718 | return res; | 766 | return res; |
719 | } | 767 | } |
720 | 768 | ||
721 | printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); | 769 | printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n"); |
722 | 770 | ||
723 | return 0; | 771 | return 0; |
724 | } | 772 | } |
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index b3dfdf7b8fc5..201f4c90d961 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * | 15 | * |
16 | * Author: Tobias Anderberg <tobiasa@axis.com>. | 16 | * Author: Tobias Anderberg <tobiasa@axis.com>. |
17 | * | 17 | * |
18 | * $Id: pcf8563.c,v 1.8 2004/08/24 06:42:51 starvik Exp $ | 18 | * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $ |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
@@ -40,7 +40,7 @@ | |||
40 | #define PCF8563_MAJOR 121 /* Local major number. */ | 40 | #define PCF8563_MAJOR 121 /* Local major number. */ |
41 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ | 41 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ |
42 | #define PCF8563_NAME "PCF8563" | 42 | #define PCF8563_NAME "PCF8563" |
43 | #define DRIVER_VERSION "$Revision: 1.8 $" | 43 | #define DRIVER_VERSION "$Revision: 1.11 $" |
44 | 44 | ||
45 | /* I2C bus slave registers. */ | 45 | /* I2C bus slave registers. */ |
46 | #define RTC_I2C_READ 0xa3 | 46 | #define RTC_I2C_READ 0xa3 |
@@ -49,6 +49,8 @@ | |||
49 | /* Two simple wrapper macros, saves a few keystrokes. */ | 49 | /* Two simple wrapper macros, saves a few keystrokes. */ |
50 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) | 50 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) |
51 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) | 51 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) |
52 | |||
53 | static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */ | ||
52 | 54 | ||
53 | static const unsigned char days_in_month[] = | 55 | static const unsigned char days_in_month[] = |
54 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | 56 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
@@ -125,9 +127,12 @@ get_rtc_time(struct rtc_time *tm) | |||
125 | int __init | 127 | int __init |
126 | pcf8563_init(void) | 128 | pcf8563_init(void) |
127 | { | 129 | { |
128 | unsigned char ret; | 130 | int ret; |
129 | 131 | ||
130 | i2c_init(); | 132 | if ((ret = i2c_init())) { |
133 | printk(KERN_CRIT "pcf8563_init: failed to init i2c\n"); | ||
134 | return ret; | ||
135 | } | ||
131 | 136 | ||
132 | /* | 137 | /* |
133 | * First of all we need to reset the chip. This is done by | 138 | * First of all we need to reset the chip. This is done by |
@@ -200,12 +205,15 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
200 | { | 205 | { |
201 | struct rtc_time tm; | 206 | struct rtc_time tm; |
202 | 207 | ||
208 | spin_lock(&rtc_lock); | ||
203 | get_rtc_time(&tm); | 209 | get_rtc_time(&tm); |
204 | 210 | ||
205 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { | 211 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { |
212 | spin_unlock(&rtc_lock); | ||
206 | return -EFAULT; | 213 | return -EFAULT; |
207 | } | 214 | } |
208 | 215 | ||
216 | spin_unlock(&rtc_lock); | ||
209 | return 0; | 217 | return 0; |
210 | } | 218 | } |
211 | break; | 219 | break; |
@@ -250,6 +258,8 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
250 | BIN_TO_BCD(tm.tm_min); | 258 | BIN_TO_BCD(tm.tm_min); |
251 | BIN_TO_BCD(tm.tm_sec); | 259 | BIN_TO_BCD(tm.tm_sec); |
252 | tm.tm_mon |= century; | 260 | tm.tm_mon |= century; |
261 | |||
262 | spin_lock(&rtc_lock); | ||
253 | 263 | ||
254 | rtc_write(RTC_YEAR, tm.tm_year); | 264 | rtc_write(RTC_YEAR, tm.tm_year); |
255 | rtc_write(RTC_MONTH, tm.tm_mon); | 265 | rtc_write(RTC_MONTH, tm.tm_mon); |
@@ -258,6 +268,8 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
258 | rtc_write(RTC_MINUTES, tm.tm_min); | 268 | rtc_write(RTC_MINUTES, tm.tm_min); |
259 | rtc_write(RTC_SECONDS, tm.tm_sec); | 269 | rtc_write(RTC_SECONDS, tm.tm_sec); |
260 | 270 | ||
271 | spin_unlock(&rtc_lock); | ||
272 | |||
261 | return 0; | 273 | return 0; |
262 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ | 274 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ |
263 | } | 275 | } |
diff --git a/arch/cris/arch-v10/kernel/Makefile b/arch/cris/arch-v10/kernel/Makefile index 52761603b6a5..dcfec41d3533 100644 --- a/arch/cris/arch-v10/kernel/Makefile +++ b/arch/cris/arch-v10/kernel/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile,v 1.5 2004/06/02 08:24:38 starvik Exp $ | 1 | # $Id: Makefile,v 1.6 2004/12/13 12:21:51 starvik Exp $ |
2 | # | 2 | # |
3 | # Makefile for the linux kernel. | 3 | # Makefile for the linux kernel. |
4 | # | 4 | # |
@@ -7,7 +7,8 @@ extra-y := head.o | |||
7 | 7 | ||
8 | 8 | ||
9 | obj-y := entry.o traps.o shadows.o debugport.o irq.o \ | 9 | obj-y := entry.o traps.o shadows.o debugport.o irq.o \ |
10 | process.o setup.o signal.o traps.o time.o ptrace.o | 10 | process.o setup.o signal.o traps.o time.o ptrace.o \ |
11 | dma.o io_interface_mux.o | ||
11 | 12 | ||
12 | obj-$(CONFIG_ETRAX_KGDB) += kgdb.o | 13 | obj-$(CONFIG_ETRAX_KGDB) += kgdb.o |
13 | obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o | 14 | obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o |
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 6cf069e5e7b6..f3a85b77c17e 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c | |||
@@ -12,6 +12,31 @@ | |||
12 | * init_etrax_debug() | 12 | * init_etrax_debug() |
13 | * | 13 | * |
14 | * $Log: debugport.c,v $ | 14 | * $Log: debugport.c,v $ |
15 | * Revision 1.27 2005/06/10 10:34:14 starvik | ||
16 | * Real console support | ||
17 | * | ||
18 | * Revision 1.26 2005/06/07 07:06:07 starvik | ||
19 | * Added LF->CR translation to make ETRAX customers happy. | ||
20 | * | ||
21 | * Revision 1.25 2005/03/08 08:56:47 mikaelam | ||
22 | * Do only set index as port->index if port is defined, otherwise use the index from the command line | ||
23 | * | ||
24 | * Revision 1.24 2005/01/19 10:26:33 mikaelam | ||
25 | * Return the cris serial driver in console device driver callback function | ||
26 | * | ||
27 | * Revision 1.23 2005/01/14 10:12:17 starvik | ||
28 | * KGDB on separate port. | ||
29 | * Console fixes from 2.4. | ||
30 | * | ||
31 | * Revision 1.22 2005/01/11 16:06:13 starvik | ||
32 | * typo | ||
33 | * | ||
34 | * Revision 1.21 2005/01/11 13:49:14 starvik | ||
35 | * Added raw_printk to be used where we don't trust the console. | ||
36 | * | ||
37 | * Revision 1.20 2004/12/27 11:18:32 starvik | ||
38 | * Merge of Linux 2.6.10 (not functional yet). | ||
39 | * | ||
15 | * Revision 1.19 2004/10/21 07:26:16 starvik | 40 | * Revision 1.19 2004/10/21 07:26:16 starvik |
16 | * Made it possible to specify console settings on kernel command line. | 41 | * Made it possible to specify console settings on kernel command line. |
17 | * | 42 | * |
@@ -114,7 +139,11 @@ struct dbg_port ports[]= | |||
114 | R_SERIAL0_BAUD, | 139 | R_SERIAL0_BAUD, |
115 | R_SERIAL0_TR_CTRL, | 140 | R_SERIAL0_TR_CTRL, |
116 | R_SERIAL0_REC_CTRL, | 141 | R_SERIAL0_REC_CTRL, |
117 | IO_STATE(R_IRQ_MASK1_SET, ser0_data, set) | 142 | IO_STATE(R_IRQ_MASK1_SET, ser0_data, set), |
143 | 0, | ||
144 | 115200, | ||
145 | 'N', | ||
146 | 8 | ||
118 | }, | 147 | }, |
119 | { | 148 | { |
120 | 1, | 149 | 1, |
@@ -124,7 +153,11 @@ struct dbg_port ports[]= | |||
124 | R_SERIAL1_BAUD, | 153 | R_SERIAL1_BAUD, |
125 | R_SERIAL1_TR_CTRL, | 154 | R_SERIAL1_TR_CTRL, |
126 | R_SERIAL1_REC_CTRL, | 155 | R_SERIAL1_REC_CTRL, |
127 | IO_STATE(R_IRQ_MASK1_SET, ser1_data, set) | 156 | IO_STATE(R_IRQ_MASK1_SET, ser1_data, set), |
157 | 0, | ||
158 | 115200, | ||
159 | 'N', | ||
160 | 8 | ||
128 | }, | 161 | }, |
129 | { | 162 | { |
130 | 2, | 163 | 2, |
@@ -134,7 +167,11 @@ struct dbg_port ports[]= | |||
134 | R_SERIAL2_BAUD, | 167 | R_SERIAL2_BAUD, |
135 | R_SERIAL2_TR_CTRL, | 168 | R_SERIAL2_TR_CTRL, |
136 | R_SERIAL2_REC_CTRL, | 169 | R_SERIAL2_REC_CTRL, |
137 | IO_STATE(R_IRQ_MASK1_SET, ser2_data, set) | 170 | IO_STATE(R_IRQ_MASK1_SET, ser2_data, set), |
171 | 0, | ||
172 | 115200, | ||
173 | 'N', | ||
174 | 8 | ||
138 | }, | 175 | }, |
139 | { | 176 | { |
140 | 3, | 177 | 3, |
@@ -144,11 +181,15 @@ struct dbg_port ports[]= | |||
144 | R_SERIAL3_BAUD, | 181 | R_SERIAL3_BAUD, |
145 | R_SERIAL3_TR_CTRL, | 182 | R_SERIAL3_TR_CTRL, |
146 | R_SERIAL3_REC_CTRL, | 183 | R_SERIAL3_REC_CTRL, |
147 | IO_STATE(R_IRQ_MASK1_SET, ser3_data, set) | 184 | IO_STATE(R_IRQ_MASK1_SET, ser3_data, set), |
185 | 0, | ||
186 | 115200, | ||
187 | 'N', | ||
188 | 8 | ||
148 | } | 189 | } |
149 | }; | 190 | }; |
150 | 191 | ||
151 | static struct tty_driver *serial_driver; | 192 | extern struct tty_driver *serial_driver; |
152 | 193 | ||
153 | struct dbg_port* port = | 194 | struct dbg_port* port = |
154 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) | 195 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) |
@@ -162,37 +203,44 @@ struct dbg_port* port = | |||
162 | #else | 203 | #else |
163 | NULL; | 204 | NULL; |
164 | #endif | 205 | #endif |
165 | /* Used by serial.c to register a debug_write_function so that the normal | ||
166 | * serial driver is used for kernel debug output | ||
167 | */ | ||
168 | typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len); | ||
169 | 206 | ||
170 | debugport_write_function debug_write_function = NULL; | 207 | static struct dbg_port* kgdb_port = |
208 | #if defined(CONFIG_ETRAX_KGDB_PORT0) | ||
209 | &ports[0]; | ||
210 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) | ||
211 | &ports[1]; | ||
212 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) | ||
213 | &ports[2]; | ||
214 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) | ||
215 | &ports[3]; | ||
216 | #else | ||
217 | NULL; | ||
218 | #endif | ||
171 | 219 | ||
172 | static void | 220 | static void |
173 | start_port(void) | 221 | start_port(struct dbg_port* p) |
174 | { | 222 | { |
175 | unsigned long rec_ctrl = 0; | 223 | unsigned long rec_ctrl = 0; |
176 | unsigned long tr_ctrl = 0; | 224 | unsigned long tr_ctrl = 0; |
177 | 225 | ||
178 | if (!port) | 226 | if (!p) |
179 | return; | 227 | return; |
180 | 228 | ||
181 | if (port->started) | 229 | if (p->started) |
182 | return; | 230 | return; |
183 | port->started = 1; | 231 | p->started = 1; |
184 | 232 | ||
185 | if (port->index == 0) | 233 | if (p->index == 0) |
186 | { | 234 | { |
187 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); | 235 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); |
188 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); | 236 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); |
189 | } | 237 | } |
190 | else if (port->index == 1) | 238 | else if (p->index == 1) |
191 | { | 239 | { |
192 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); | 240 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); |
193 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); | 241 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); |
194 | } | 242 | } |
195 | else if (port->index == 2) | 243 | else if (p->index == 2) |
196 | { | 244 | { |
197 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); | 245 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); |
198 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); | 246 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); |
@@ -211,69 +259,69 @@ start_port(void) | |||
211 | 259 | ||
212 | *R_GEN_CONFIG = genconfig_shadow; | 260 | *R_GEN_CONFIG = genconfig_shadow; |
213 | 261 | ||
214 | *port->xoff = | 262 | *p->xoff = |
215 | IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) | | 263 | IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) | |
216 | IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) | | 264 | IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) | |
217 | IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0); | 265 | IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0); |
218 | 266 | ||
219 | switch (port->baudrate) | 267 | switch (p->baudrate) |
220 | { | 268 | { |
221 | case 0: | 269 | case 0: |
222 | case 115200: | 270 | case 115200: |
223 | *port->baud = | 271 | *p->baud = |
224 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | | 272 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | |
225 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); | 273 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); |
226 | break; | 274 | break; |
227 | case 1200: | 275 | case 1200: |
228 | *port->baud = | 276 | *p->baud = |
229 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) | | 277 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) | |
230 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz); | 278 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz); |
231 | break; | 279 | break; |
232 | case 2400: | 280 | case 2400: |
233 | *port->baud = | 281 | *p->baud = |
234 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) | | 282 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) | |
235 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz); | 283 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz); |
236 | break; | 284 | break; |
237 | case 4800: | 285 | case 4800: |
238 | *port->baud = | 286 | *p->baud = |
239 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) | | 287 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) | |
240 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz); | 288 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz); |
241 | break; | 289 | break; |
242 | case 9600: | 290 | case 9600: |
243 | *port->baud = | 291 | *p->baud = |
244 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) | | 292 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) | |
245 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz); | 293 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz); |
246 | break; | 294 | break; |
247 | case 19200: | 295 | case 19200: |
248 | *port->baud = | 296 | *p->baud = |
249 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) | | 297 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) | |
250 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz); | 298 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz); |
251 | break; | 299 | break; |
252 | case 38400: | 300 | case 38400: |
253 | *port->baud = | 301 | *p->baud = |
254 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) | | 302 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) | |
255 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz); | 303 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz); |
256 | break; | 304 | break; |
257 | case 57600: | 305 | case 57600: |
258 | *port->baud = | 306 | *p->baud = |
259 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) | | 307 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) | |
260 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz); | 308 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz); |
261 | break; | 309 | break; |
262 | default: | 310 | default: |
263 | *port->baud = | 311 | *p->baud = |
264 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | | 312 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | |
265 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); | 313 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); |
266 | break; | 314 | break; |
267 | } | 315 | } |
268 | 316 | ||
269 | if (port->parity == 'E') { | 317 | if (p->parity == 'E') { |
270 | rec_ctrl = | 318 | rec_ctrl = |
271 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) | | 319 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) | |
272 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); | 320 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); |
273 | tr_ctrl = | 321 | tr_ctrl = |
274 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | | 322 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | |
275 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable); | 323 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable); |
276 | } else if (port->parity == 'O') { | 324 | } else if (p->parity == 'O') { |
277 | rec_ctrl = | 325 | rec_ctrl = |
278 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) | | 326 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) | |
279 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); | 327 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); |
@@ -288,8 +336,7 @@ start_port(void) | |||
288 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | | 336 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | |
289 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable); | 337 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable); |
290 | } | 338 | } |
291 | 339 | if (p->bits == 7) | |
292 | if (port->bits == 7) | ||
293 | { | 340 | { |
294 | rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit); | 341 | rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit); |
295 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit); | 342 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit); |
@@ -300,7 +347,7 @@ start_port(void) | |||
300 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit); | 347 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit); |
301 | } | 348 | } |
302 | 349 | ||
303 | *port->rec_ctrl = | 350 | *p->rec_ctrl = |
304 | IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) | | 351 | IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) | |
305 | IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) | | 352 | IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) | |
306 | IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) | | 353 | IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) | |
@@ -308,7 +355,7 @@ start_port(void) | |||
308 | IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) | | 355 | IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) | |
309 | rec_ctrl; | 356 | rec_ctrl; |
310 | 357 | ||
311 | *port->tr_ctrl = | 358 | *p->tr_ctrl = |
312 | IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) | | 359 | IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) | |
313 | IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) | | 360 | IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) | |
314 | IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) | | 361 | IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) | |
@@ -323,8 +370,18 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
323 | int i; | 370 | int i; |
324 | unsigned long flags; | 371 | unsigned long flags; |
325 | local_irq_save(flags); | 372 | local_irq_save(flags); |
373 | |||
374 | if (!port) | ||
375 | return; | ||
376 | |||
326 | /* Send data */ | 377 | /* Send data */ |
327 | for (i = 0; i < len; i++) { | 378 | for (i = 0; i < len; i++) { |
379 | /* LF -> CRLF */ | ||
380 | if (buf[i] == '\n') { | ||
381 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | ||
382 | ; | ||
383 | *port->write = '\r'; | ||
384 | } | ||
328 | /* Wait until transmitter is ready and send.*/ | 385 | /* Wait until transmitter is ready and send.*/ |
329 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | 386 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) |
330 | ; | 387 | ; |
@@ -333,6 +390,25 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
333 | local_irq_restore(flags); | 390 | local_irq_restore(flags); |
334 | } | 391 | } |
335 | 392 | ||
393 | int raw_printk(const char *fmt, ...) | ||
394 | { | ||
395 | static char buf[1024]; | ||
396 | int printed_len; | ||
397 | static int first = 1; | ||
398 | if (first) { | ||
399 | /* Force reinitialization of the port to get manual mode. */ | ||
400 | port->started = 0; | ||
401 | start_port(port); | ||
402 | first = 0; | ||
403 | } | ||
404 | va_list args; | ||
405 | va_start(args, fmt); | ||
406 | printed_len = vsnprintf(buf, sizeof(buf), fmt, args); | ||
407 | va_end(args); | ||
408 | console_write_direct(NULL, buf, strlen(buf)); | ||
409 | return printed_len; | ||
410 | } | ||
411 | |||
336 | static void | 412 | static void |
337 | console_write(struct console *co, const char *buf, unsigned int len) | 413 | console_write(struct console *co, const char *buf, unsigned int len) |
338 | { | 414 | { |
@@ -345,18 +421,7 @@ console_write(struct console *co, const char *buf, unsigned int len) | |||
345 | return; | 421 | return; |
346 | #endif | 422 | #endif |
347 | 423 | ||
348 | start_port(); | 424 | console_write_direct(co, buf, len); |
349 | |||
350 | #ifdef CONFIG_ETRAX_KGDB | ||
351 | /* kgdb needs to output debug info using the gdb protocol */ | ||
352 | putDebugString(buf, len); | ||
353 | return; | ||
354 | #endif | ||
355 | |||
356 | if (debug_write_function) | ||
357 | debug_write_function(co->index, buf, len); | ||
358 | else | ||
359 | console_write_direct(co, buf, len); | ||
360 | } | 425 | } |
361 | 426 | ||
362 | /* legacy function */ | 427 | /* legacy function */ |
@@ -374,8 +439,11 @@ getDebugChar(void) | |||
374 | { | 439 | { |
375 | unsigned long readval; | 440 | unsigned long readval; |
376 | 441 | ||
442 | if (!kgdb_port) | ||
443 | return 0; | ||
444 | |||
377 | do { | 445 | do { |
378 | readval = *port->read; | 446 | readval = *kgdb_port->read; |
379 | } while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail))); | 447 | } while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail))); |
380 | 448 | ||
381 | return (readval & IO_MASK(R_SERIAL0_READ, data_in)); | 449 | return (readval & IO_MASK(R_SERIAL0_READ, data_in)); |
@@ -386,9 +454,12 @@ getDebugChar(void) | |||
386 | void | 454 | void |
387 | putDebugChar(int val) | 455 | putDebugChar(int val) |
388 | { | 456 | { |
389 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | 457 | if (!kgdb_port) |
458 | return; | ||
459 | |||
460 | while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | ||
390 | ; | 461 | ; |
391 | *port->write = val; | 462 | *kgdb_port->write = val; |
392 | } | 463 | } |
393 | 464 | ||
394 | /* Enable irq for receiving chars on the debug port, used by kgdb */ | 465 | /* Enable irq for receiving chars on the debug port, used by kgdb */ |
@@ -396,19 +467,16 @@ putDebugChar(int val) | |||
396 | void | 467 | void |
397 | enableDebugIRQ(void) | 468 | enableDebugIRQ(void) |
398 | { | 469 | { |
399 | *R_IRQ_MASK1_SET = port->irq; | 470 | if (!kgdb_port) |
471 | return; | ||
472 | |||
473 | *R_IRQ_MASK1_SET = kgdb_port->irq; | ||
400 | /* use R_VECT_MASK directly, since we really bypass Linux normal | 474 | /* use R_VECT_MASK directly, since we really bypass Linux normal |
401 | * IRQ handling in kgdb anyway, we don't need to use enable_irq | 475 | * IRQ handling in kgdb anyway, we don't need to use enable_irq |
402 | */ | 476 | */ |
403 | *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); | 477 | *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); |
404 | 478 | ||
405 | *port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); | 479 | *kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); |
406 | } | ||
407 | |||
408 | static struct tty_driver* | ||
409 | etrax_console_device(struct console* co, int *index) | ||
410 | { | ||
411 | return serial_driver; | ||
412 | } | 480 | } |
413 | 481 | ||
414 | static int __init | 482 | static int __init |
@@ -428,11 +496,69 @@ console_setup(struct console *co, char *options) | |||
428 | if (*s) port->parity = *s++; | 496 | if (*s) port->parity = *s++; |
429 | if (*s) port->bits = *s++ - '0'; | 497 | if (*s) port->bits = *s++ - '0'; |
430 | port->started = 0; | 498 | port->started = 0; |
431 | start_port(); | 499 | start_port(0); |
432 | } | 500 | } |
433 | return 0; | 501 | return 0; |
434 | } | 502 | } |
435 | 503 | ||
504 | /* This is a dummy serial device that throws away anything written to it. | ||
505 | * This is used when no debug output is wanted. | ||
506 | */ | ||
507 | static struct tty_driver dummy_driver; | ||
508 | |||
509 | static int dummy_open(struct tty_struct *tty, struct file * filp) | ||
510 | { | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static void dummy_close(struct tty_struct *tty, struct file * filp) | ||
515 | { | ||
516 | } | ||
517 | |||
518 | static int dummy_write(struct tty_struct * tty, | ||
519 | const unsigned char *buf, int count) | ||
520 | { | ||
521 | return count; | ||
522 | } | ||
523 | |||
524 | static int | ||
525 | dummy_write_room(struct tty_struct *tty) | ||
526 | { | ||
527 | return 8192; | ||
528 | } | ||
529 | |||
530 | void __init | ||
531 | init_dummy_console(void) | ||
532 | { | ||
533 | memset(&dummy_driver, 0, sizeof(struct tty_driver)); | ||
534 | dummy_driver.driver_name = "serial"; | ||
535 | dummy_driver.name = "ttyS"; | ||
536 | dummy_driver.major = TTY_MAJOR; | ||
537 | dummy_driver.minor_start = 68; | ||
538 | dummy_driver.num = 1; /* etrax100 has 4 serial ports */ | ||
539 | dummy_driver.type = TTY_DRIVER_TYPE_SERIAL; | ||
540 | dummy_driver.subtype = SERIAL_TYPE_NORMAL; | ||
541 | dummy_driver.init_termios = tty_std_termios; | ||
542 | dummy_driver.init_termios.c_cflag = | ||
543 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | ||
544 | dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | ||
545 | |||
546 | dummy_driver.open = dummy_open; | ||
547 | dummy_driver.close = dummy_close; | ||
548 | dummy_driver.write = dummy_write; | ||
549 | dummy_driver.write_room = dummy_write_room; | ||
550 | if (tty_register_driver(&dummy_driver)) | ||
551 | panic("Couldn't register dummy serial driver\n"); | ||
552 | } | ||
553 | |||
554 | static struct tty_driver* | ||
555 | etrax_console_device(struct console* co, int *index) | ||
556 | { | ||
557 | if (port) | ||
558 | *index = port->index; | ||
559 | return port ? serial_driver : &dummy_driver; | ||
560 | } | ||
561 | |||
436 | static struct console sercons = { | 562 | static struct console sercons = { |
437 | name : "ttyS", | 563 | name : "ttyS", |
438 | write: console_write, | 564 | write: console_write, |
@@ -504,28 +630,21 @@ init_etrax_debug(void) | |||
504 | static int first = 1; | 630 | static int first = 1; |
505 | 631 | ||
506 | if (!first) { | 632 | if (!first) { |
507 | if (!port) { | 633 | unregister_console(&sercons); |
508 | register_console(&sercons0); | 634 | register_console(&sercons0); |
509 | register_console(&sercons1); | 635 | register_console(&sercons1); |
510 | register_console(&sercons2); | 636 | register_console(&sercons2); |
511 | register_console(&sercons3); | 637 | register_console(&sercons3); |
512 | unregister_console(&sercons); | 638 | init_dummy_console(); |
513 | } | ||
514 | return 0; | 639 | return 0; |
515 | } | 640 | } |
516 | first = 0; | ||
517 | if (port) | ||
518 | register_console(&sercons); | ||
519 | return 0; | ||
520 | } | ||
521 | 641 | ||
522 | int __init | 642 | first = 0; |
523 | init_console(void) | 643 | register_console(&sercons); |
524 | { | 644 | start_port(port); |
525 | serial_driver = alloc_tty_driver(1); | 645 | #ifdef CONFIG_ETRAX_KGDB |
526 | if (!serial_driver) | 646 | start_port(kgdb_port); |
527 | return -ENOMEM; | 647 | #endif |
528 | return 0; | 648 | return 0; |
529 | } | 649 | } |
530 | |||
531 | __initcall(init_etrax_debug); | 650 | __initcall(init_etrax_debug); |
diff --git a/arch/cris/arch-v10/kernel/dma.c b/arch/cris/arch-v10/kernel/dma.c new file mode 100644 index 000000000000..e9a0311b141d --- /dev/null +++ b/arch/cris/arch-v10/kernel/dma.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* Wrapper for DMA channel allocator that updates DMA client muxing. | ||
2 | * Copyright 2004, Axis Communications AB | ||
3 | * $Id: dma.c,v 1.1 2004/12/13 12:21:51 starvik Exp $ | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/errno.h> | ||
9 | |||
10 | #include <asm/dma.h> | ||
11 | #include <asm/arch/svinto.h> | ||
12 | |||
13 | /* Macro to access ETRAX 100 registers */ | ||
14 | #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ | ||
15 | IO_STATE_(reg##_, field##_, _##val) | ||
16 | |||
17 | |||
18 | static char used_dma_channels[MAX_DMA_CHANNELS]; | ||
19 | static const char * used_dma_channels_users[MAX_DMA_CHANNELS]; | ||
20 | |||
21 | int cris_request_dma(unsigned int dmanr, const char * device_id, | ||
22 | unsigned options, enum dma_owner owner) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | unsigned long int gens; | ||
26 | int fail = -EINVAL; | ||
27 | |||
28 | if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { | ||
29 | printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr); | ||
30 | return -EINVAL; | ||
31 | } | ||
32 | |||
33 | local_irq_save(flags); | ||
34 | if (used_dma_channels[dmanr]) { | ||
35 | local_irq_restore(flags); | ||
36 | if (options & DMA_VERBOSE_ON_ERROR) { | ||
37 | printk(KERN_CRIT "Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]); | ||
38 | } | ||
39 | if (options & DMA_PANIC_ON_ERROR) { | ||
40 | panic("request_dma error!"); | ||
41 | } | ||
42 | return -EBUSY; | ||
43 | } | ||
44 | |||
45 | gens = genconfig_shadow; | ||
46 | |||
47 | switch(owner) | ||
48 | { | ||
49 | case dma_eth: | ||
50 | if ((dmanr != NETWORK_TX_DMA_NBR) && | ||
51 | (dmanr != NETWORK_RX_DMA_NBR)) { | ||
52 | printk(KERN_CRIT "Invalid DMA channel for eth\n"); | ||
53 | goto bail; | ||
54 | } | ||
55 | break; | ||
56 | case dma_ser0: | ||
57 | if (dmanr == SER0_TX_DMA_NBR) { | ||
58 | SETS(gens, R_GEN_CONFIG, dma6, serial0); | ||
59 | } else if (dmanr == SER0_RX_DMA_NBR) { | ||
60 | SETS(gens, R_GEN_CONFIG, dma7, serial0); | ||
61 | } else { | ||
62 | printk(KERN_CRIT "Invalid DMA channel for ser0\n"); | ||
63 | goto bail; | ||
64 | } | ||
65 | break; | ||
66 | case dma_ser1: | ||
67 | if (dmanr == SER1_TX_DMA_NBR) { | ||
68 | SETS(gens, R_GEN_CONFIG, dma8, serial1); | ||
69 | } else if (dmanr == SER1_RX_DMA_NBR) { | ||
70 | SETS(gens, R_GEN_CONFIG, dma9, serial1); | ||
71 | } else { | ||
72 | printk(KERN_CRIT "Invalid DMA channel for ser1\n"); | ||
73 | goto bail; | ||
74 | } | ||
75 | break; | ||
76 | case dma_ser2: | ||
77 | if (dmanr == SER2_TX_DMA_NBR) { | ||
78 | SETS(gens, R_GEN_CONFIG, dma2, serial2); | ||
79 | } else if (dmanr == SER2_RX_DMA_NBR) { | ||
80 | SETS(gens, R_GEN_CONFIG, dma3, serial2); | ||
81 | } else { | ||
82 | printk(KERN_CRIT "Invalid DMA channel for ser2\n"); | ||
83 | goto bail; | ||
84 | } | ||
85 | break; | ||
86 | case dma_ser3: | ||
87 | if (dmanr == SER3_TX_DMA_NBR) { | ||
88 | SETS(gens, R_GEN_CONFIG, dma4, serial3); | ||
89 | } else if (dmanr == SER3_RX_DMA_NBR) { | ||
90 | SETS(gens, R_GEN_CONFIG, dma5, serial3); | ||
91 | } else { | ||
92 | printk(KERN_CRIT "Invalid DMA channel for ser3\n"); | ||
93 | goto bail; | ||
94 | } | ||
95 | break; | ||
96 | case dma_ata: | ||
97 | if (dmanr == ATA_TX_DMA_NBR) { | ||
98 | SETS(gens, R_GEN_CONFIG, dma2, ata); | ||
99 | } else if (dmanr == ATA_RX_DMA_NBR) { | ||
100 | SETS(gens, R_GEN_CONFIG, dma3, ata); | ||
101 | } else { | ||
102 | printk(KERN_CRIT "Invalid DMA channel for ata\n"); | ||
103 | goto bail; | ||
104 | } | ||
105 | break; | ||
106 | case dma_ext0: | ||
107 | if (dmanr == EXTDMA0_TX_DMA_NBR) { | ||
108 | SETS(gens, R_GEN_CONFIG, dma4, extdma0); | ||
109 | } else if (dmanr == EXTDMA0_RX_DMA_NBR) { | ||
110 | SETS(gens, R_GEN_CONFIG, dma5, extdma0); | ||
111 | } else { | ||
112 | printk(KERN_CRIT "Invalid DMA channel for ext0\n"); | ||
113 | goto bail; | ||
114 | } | ||
115 | break; | ||
116 | case dma_ext1: | ||
117 | if (dmanr == EXTDMA1_TX_DMA_NBR) { | ||
118 | SETS(gens, R_GEN_CONFIG, dma6, extdma1); | ||
119 | } else if (dmanr == EXTDMA1_RX_DMA_NBR) { | ||
120 | SETS(gens, R_GEN_CONFIG, dma7, extdma1); | ||
121 | } else { | ||
122 | printk(KERN_CRIT "Invalid DMA channel for ext1\n"); | ||
123 | goto bail; | ||
124 | } | ||
125 | break; | ||
126 | case dma_int6: | ||
127 | if (dmanr == MEM2MEM_RX_DMA_NBR) { | ||
128 | SETS(gens, R_GEN_CONFIG, dma7, intdma6); | ||
129 | } else { | ||
130 | printk(KERN_CRIT "Invalid DMA channel for int6\n"); | ||
131 | goto bail; | ||
132 | } | ||
133 | break; | ||
134 | case dma_int7: | ||
135 | if (dmanr == MEM2MEM_TX_DMA_NBR) { | ||
136 | SETS(gens, R_GEN_CONFIG, dma6, intdma7); | ||
137 | } else { | ||
138 | printk(KERN_CRIT "Invalid DMA channel for int7\n"); | ||
139 | goto bail; | ||
140 | } | ||
141 | break; | ||
142 | case dma_usb: | ||
143 | if (dmanr == USB_TX_DMA_NBR) { | ||
144 | SETS(gens, R_GEN_CONFIG, dma8, usb); | ||
145 | } else if (dmanr == USB_RX_DMA_NBR) { | ||
146 | SETS(gens, R_GEN_CONFIG, dma9, usb); | ||
147 | } else { | ||
148 | printk(KERN_CRIT "Invalid DMA channel for usb\n"); | ||
149 | goto bail; | ||
150 | } | ||
151 | break; | ||
152 | case dma_scsi0: | ||
153 | if (dmanr == SCSI0_TX_DMA_NBR) { | ||
154 | SETS(gens, R_GEN_CONFIG, dma2, scsi0); | ||
155 | } else if (dmanr == SCSI0_RX_DMA_NBR) { | ||
156 | SETS(gens, R_GEN_CONFIG, dma3, scsi0); | ||
157 | } else { | ||
158 | printk(KERN_CRIT "Invalid DMA channel for scsi0\n"); | ||
159 | goto bail; | ||
160 | } | ||
161 | break; | ||
162 | case dma_scsi1: | ||
163 | if (dmanr == SCSI1_TX_DMA_NBR) { | ||
164 | SETS(gens, R_GEN_CONFIG, dma4, scsi1); | ||
165 | } else if (dmanr == SCSI1_RX_DMA_NBR) { | ||
166 | SETS(gens, R_GEN_CONFIG, dma5, scsi1); | ||
167 | } else { | ||
168 | printk(KERN_CRIT "Invalid DMA channel for scsi1\n"); | ||
169 | goto bail; | ||
170 | } | ||
171 | break; | ||
172 | case dma_par0: | ||
173 | if (dmanr == PAR0_TX_DMA_NBR) { | ||
174 | SETS(gens, R_GEN_CONFIG, dma2, par0); | ||
175 | } else if (dmanr == PAR0_RX_DMA_NBR) { | ||
176 | SETS(gens, R_GEN_CONFIG, dma3, par0); | ||
177 | } else { | ||
178 | printk(KERN_CRIT "Invalid DMA channel for par0\n"); | ||
179 | goto bail; | ||
180 | } | ||
181 | break; | ||
182 | case dma_par1: | ||
183 | if (dmanr == PAR1_TX_DMA_NBR) { | ||
184 | SETS(gens, R_GEN_CONFIG, dma4, par1); | ||
185 | } else if (dmanr == PAR1_RX_DMA_NBR) { | ||
186 | SETS(gens, R_GEN_CONFIG, dma5, par1); | ||
187 | } else { | ||
188 | printk(KERN_CRIT "Invalid DMA channel for par1\n"); | ||
189 | goto bail; | ||
190 | } | ||
191 | break; | ||
192 | default: | ||
193 | printk(KERN_CRIT "Invalid DMA owner.\n"); | ||
194 | goto bail; | ||
195 | } | ||
196 | |||
197 | used_dma_channels[dmanr] = 1; | ||
198 | used_dma_channels_users[dmanr] = device_id; | ||
199 | |||
200 | { | ||
201 | volatile int i; | ||
202 | genconfig_shadow = gens; | ||
203 | *R_GEN_CONFIG = genconfig_shadow; | ||
204 | /* Wait 12 cycles before doing any DMA command */ | ||
205 | for(i = 6; i > 0; i--) | ||
206 | nop(); | ||
207 | } | ||
208 | fail = 0; | ||
209 | bail: | ||
210 | local_irq_restore(flags); | ||
211 | return fail; | ||
212 | } | ||
213 | |||
214 | void cris_free_dma(unsigned int dmanr, const char * device_id) | ||
215 | { | ||
216 | unsigned long flags; | ||
217 | if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { | ||
218 | printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | local_irq_save(flags); | ||
223 | if (!used_dma_channels[dmanr]) { | ||
224 | printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated\n", dmanr); | ||
225 | } else if (device_id != used_dma_channels_users[dmanr]) { | ||
226 | printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated by device\n", dmanr); | ||
227 | } else { | ||
228 | switch(dmanr) | ||
229 | { | ||
230 | case 0: | ||
231 | *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset); | ||
232 | while (IO_EXTRACT(R_DMA_CH0_CMD, cmd, *R_DMA_CH0_CMD) == | ||
233 | IO_STATE_VALUE(R_DMA_CH0_CMD, cmd, reset)); | ||
234 | break; | ||
235 | case 1: | ||
236 | *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset); | ||
237 | while (IO_EXTRACT(R_DMA_CH1_CMD, cmd, *R_DMA_CH1_CMD) == | ||
238 | IO_STATE_VALUE(R_DMA_CH1_CMD, cmd, reset)); | ||
239 | break; | ||
240 | case 2: | ||
241 | *R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, reset); | ||
242 | while (IO_EXTRACT(R_DMA_CH2_CMD, cmd, *R_DMA_CH2_CMD) == | ||
243 | IO_STATE_VALUE(R_DMA_CH2_CMD, cmd, reset)); | ||
244 | break; | ||
245 | case 3: | ||
246 | *R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, reset); | ||
247 | while (IO_EXTRACT(R_DMA_CH3_CMD, cmd, *R_DMA_CH3_CMD) == | ||
248 | IO_STATE_VALUE(R_DMA_CH3_CMD, cmd, reset)); | ||
249 | break; | ||
250 | case 4: | ||
251 | *R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, reset); | ||
252 | while (IO_EXTRACT(R_DMA_CH4_CMD, cmd, *R_DMA_CH4_CMD) == | ||
253 | IO_STATE_VALUE(R_DMA_CH4_CMD, cmd, reset)); | ||
254 | break; | ||
255 | case 5: | ||
256 | *R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, reset); | ||
257 | while (IO_EXTRACT(R_DMA_CH5_CMD, cmd, *R_DMA_CH5_CMD) == | ||
258 | IO_STATE_VALUE(R_DMA_CH5_CMD, cmd, reset)); | ||
259 | break; | ||
260 | case 6: | ||
261 | *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, reset); | ||
262 | while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *R_DMA_CH6_CMD) == | ||
263 | IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); | ||
264 | break; | ||
265 | case 7: | ||
266 | *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, reset); | ||
267 | while (IO_EXTRACT(R_DMA_CH7_CMD, cmd, *R_DMA_CH7_CMD) == | ||
268 | IO_STATE_VALUE(R_DMA_CH7_CMD, cmd, reset)); | ||
269 | break; | ||
270 | case 8: | ||
271 | *R_DMA_CH8_CMD = IO_STATE(R_DMA_CH8_CMD, cmd, reset); | ||
272 | while (IO_EXTRACT(R_DMA_CH8_CMD, cmd, *R_DMA_CH8_CMD) == | ||
273 | IO_STATE_VALUE(R_DMA_CH8_CMD, cmd, reset)); | ||
274 | break; | ||
275 | case 9: | ||
276 | *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, reset); | ||
277 | while (IO_EXTRACT(R_DMA_CH9_CMD, cmd, *R_DMA_CH9_CMD) == | ||
278 | IO_STATE_VALUE(R_DMA_CH9_CMD, cmd, reset)); | ||
279 | break; | ||
280 | } | ||
281 | used_dma_channels[dmanr] = 0; | ||
282 | } | ||
283 | local_irq_restore(flags); | ||
284 | } | ||
285 | |||
286 | EXPORT_SYMBOL(cris_request_dma); | ||
287 | EXPORT_SYMBOL(cris_free_dma); | ||
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 1bc44f481c34..c0163bf94a50 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: entry.S,v 1.23 2004/10/19 13:07:37 starvik Exp $ | 1 | /* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $ |
2 | * | 2 | * |
3 | * linux/arch/cris/entry.S | 3 | * linux/arch/cris/entry.S |
4 | * | 4 | * |
@@ -7,6 +7,22 @@ | |||
7 | * Authors: Bjorn Wesen (bjornw@axis.com) | 7 | * Authors: Bjorn Wesen (bjornw@axis.com) |
8 | * | 8 | * |
9 | * $Log: entry.S,v $ | 9 | * $Log: entry.S,v $ |
10 | * Revision 1.28 2005/06/20 05:06:30 starvik | ||
11 | * Remove unnecessary diff to kernel.org tree | ||
12 | * | ||
13 | * Revision 1.27 2005/03/04 08:16:16 starvik | ||
14 | * Merge of Linux 2.6.11. | ||
15 | * | ||
16 | * Revision 1.26 2005/01/11 13:49:47 starvik | ||
17 | * Added NMI handler. | ||
18 | * | ||
19 | * Revision 1.25 2004/12/27 11:18:32 starvik | ||
20 | * Merge of Linux 2.6.10 (not functional yet). | ||
21 | * | ||
22 | * Revision 1.24 2004/12/22 10:41:23 starvik | ||
23 | * Updates to make v10 compile with the latest SMP aware generic code (even | ||
24 | * though v10 will never have SMP). | ||
25 | * | ||
10 | * Revision 1.23 2004/10/19 13:07:37 starvik | 26 | * Revision 1.23 2004/10/19 13:07:37 starvik |
11 | * Merge of Linux 2.6.9 | 27 | * Merge of Linux 2.6.9 |
12 | * | 28 | * |
@@ -279,6 +295,7 @@ | |||
279 | #ifdef CONFIG_PREEMPT | 295 | #ifdef CONFIG_PREEMPT |
280 | ; Check if preemptive kernel scheduling should be done | 296 | ; Check if preemptive kernel scheduling should be done |
281 | _resume_kernel: | 297 | _resume_kernel: |
298 | di | ||
282 | ; Load current task struct | 299 | ; Load current task struct |
283 | movs.w -8192, $r0 ; THREAD_SIZE = 8192 | 300 | movs.w -8192, $r0 ; THREAD_SIZE = 8192 |
284 | and.d $sp, $r0 | 301 | and.d $sp, $r0 |
@@ -291,12 +308,7 @@ _need_resched: | |||
291 | bpl _Rexit | 308 | bpl _Rexit |
292 | nop | 309 | nop |
293 | ; Ok, lets's do some preemptive kernel scheduling | 310 | ; Ok, lets's do some preemptive kernel scheduling |
294 | move.d PREEMPT_ACTIVE, $r10 | 311 | jsr preempt_schedule_irq |
295 | move.d $r10, [$r0+TI_preempt_count] ; Mark as active | ||
296 | ei | ||
297 | jsr schedule | ||
298 | clear.d [$r0+TI_preempt_count] ; Mark as inactive | ||
299 | di | ||
300 | ; Load new task struct | 312 | ; Load new task struct |
301 | movs.w -8192, $r0 ; THREAD_SIZE = 8192 | 313 | movs.w -8192, $r0 ; THREAD_SIZE = 8192 |
302 | and.d $sp, $r0 | 314 | and.d $sp, $r0 |
@@ -590,15 +602,15 @@ mmu_bus_fault: | |||
590 | move.d $r0, [$sp+16] | 602 | move.d $r0, [$sp+16] |
591 | 1: btstq 12, $r1 ; Refill? | 603 | 1: btstq 12, $r1 ; Refill? |
592 | bpl 2f | 604 | bpl 2f |
593 | lsrq PMD_SHIFT, $r1 ; Get PMD index into PGD (bit 24-31) | 605 | lsrq 24, $r1 ; Get PGD index (bit 24-31) |
594 | move.d [current_pgd], $r0 ; PGD for the current process | 606 | move.d [per_cpu__current_pgd], $r0 ; PGD for the current process |
595 | move.d [$r0+$r1.d], $r0 ; Get PMD | 607 | move.d [$r0+$r1.d], $r0 ; Get PMD |
596 | beq 2f | 608 | beq 2f |
597 | nop | 609 | nop |
598 | and.w PAGE_MASK, $r0 ; Remove PMD flags | 610 | and.w PAGE_MASK, $r0 ; Remove PMD flags |
599 | move.d [R_MMU_CAUSE], $r1 | 611 | move.d [R_MMU_CAUSE], $r1 |
600 | lsrq PAGE_SHIFT, $r1 | 612 | lsrq PAGE_SHIFT, $r1 |
601 | and.d 0x7ff, $r1 ; Get PTE index into PMD (bit 13-24) | 613 | and.d 0x7ff, $r1 ; Get PTE index into PGD (bit 13-23) |
602 | move.d [$r0+$r1.d], $r1 ; Get PTE | 614 | move.d [$r0+$r1.d], $r1 ; Get PTE |
603 | beq 2f | 615 | beq 2f |
604 | nop | 616 | nop |
@@ -656,11 +668,6 @@ hwbreakpoint: | |||
656 | nop | 668 | nop |
657 | 669 | ||
658 | IRQ1_interrupt: | 670 | IRQ1_interrupt: |
659 | |||
660 | #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) | ||
661 | ;; If we receive a watchdog interrupt while it is not expected, then set | ||
662 | ;; up a canonical frame and dump register contents before dying. | ||
663 | |||
664 | ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!! | 671 | ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!! |
665 | move $brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame | 672 | move $brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame |
666 | push $srp | 673 | push $srp |
@@ -672,9 +679,16 @@ IRQ1_interrupt: | |||
672 | push $r10 ; push orig_r10 | 679 | push $r10 ; push orig_r10 |
673 | clear.d [$sp=$sp-4] ; frametype == 0, normal frame | 680 | clear.d [$sp=$sp-4] ; frametype == 0, normal frame |
674 | 681 | ||
675 | ;; We don't check that we actually were bit by the watchdog as opposed to | 682 | move.d [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog? |
676 | ;; an external NMI, since there is currently no handler for external NMI. | 683 | and.d 0x80000000, $r1 |
677 | 684 | beq wdog | |
685 | move.d $sp, $r10 | ||
686 | jsr handle_nmi | ||
687 | setf m ; Enable NMI again | ||
688 | retb ; Return from NMI | ||
689 | nop | ||
690 | wdog: | ||
691 | #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) | ||
678 | ;; Check if we're waiting for reset to happen, as signalled by | 692 | ;; Check if we're waiting for reset to happen, as signalled by |
679 | ;; hard_reset_now setting cause_of_death to a magic value. If so, just | 693 | ;; hard_reset_now setting cause_of_death to a magic value. If so, just |
680 | ;; get stuck until reset happens. | 694 | ;; get stuck until reset happens. |
@@ -1118,6 +1132,10 @@ sys_call_table: | |||
1118 | .long sys_mq_getsetattr | 1132 | .long sys_mq_getsetattr |
1119 | .long sys_ni_syscall /* reserved for kexec */ | 1133 | .long sys_ni_syscall /* reserved for kexec */ |
1120 | .long sys_waitid | 1134 | .long sys_waitid |
1135 | .long sys_ni_syscall /* 285 */ /* available */ | ||
1136 | .long sys_add_key | ||
1137 | .long sys_request_key | ||
1138 | .long sys_keyctl | ||
1121 | 1139 | ||
1122 | /* | 1140 | /* |
1123 | * NOTE!! This doesn't have to be exact - we just have | 1141 | * NOTE!! This doesn't have to be exact - we just have |
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index 4717f7ae8e51..094ff45ae85b 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c | |||
@@ -1,10 +1,20 @@ | |||
1 | /* $Id: fasttimer.c,v 1.6 2004/05/14 10:18:39 starvik Exp $ | 1 | /* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $ |
2 | * linux/arch/cris/kernel/fasttimer.c | 2 | * linux/arch/cris/kernel/fasttimer.c |
3 | * | 3 | * |
4 | * Fast timers for ETRAX100/ETRAX100LX | 4 | * Fast timers for ETRAX100/ETRAX100LX |
5 | * This may be useful in other OS than Linux so use 2 space indentation... | 5 | * This may be useful in other OS than Linux so use 2 space indentation... |
6 | * | 6 | * |
7 | * $Log: fasttimer.c,v $ | 7 | * $Log: fasttimer.c,v $ |
8 | * Revision 1.9 2005/03/04 08:16:16 starvik | ||
9 | * Merge of Linux 2.6.11. | ||
10 | * | ||
11 | * Revision 1.8 2005/01/05 06:09:29 starvik | ||
12 | * cli()/sti() will be obsolete in 2.6.11. | ||
13 | * | ||
14 | * Revision 1.7 2005/01/03 13:35:46 starvik | ||
15 | * Removed obsolete stuff. | ||
16 | * Mark fast timer IRQ as not shared. | ||
17 | * | ||
8 | * Revision 1.6 2004/05/14 10:18:39 starvik | 18 | * Revision 1.6 2004/05/14 10:18:39 starvik |
9 | * Export fast_timer_list | 19 | * Export fast_timer_list |
10 | * | 20 | * |
@@ -148,8 +158,7 @@ static int debug_log_cnt_wrapped = 0; | |||
148 | #define DEBUG_LOG(string, value) \ | 158 | #define DEBUG_LOG(string, value) \ |
149 | { \ | 159 | { \ |
150 | unsigned long log_flags; \ | 160 | unsigned long log_flags; \ |
151 | save_flags(log_flags); \ | 161 | local_irq_save(log_flags); \ |
152 | cli(); \ | ||
153 | debug_log_string[debug_log_cnt] = (string); \ | 162 | debug_log_string[debug_log_cnt] = (string); \ |
154 | debug_log_value[debug_log_cnt] = (unsigned long)(value); \ | 163 | debug_log_value[debug_log_cnt] = (unsigned long)(value); \ |
155 | if (++debug_log_cnt >= DEBUG_LOG_MAX) \ | 164 | if (++debug_log_cnt >= DEBUG_LOG_MAX) \ |
@@ -157,7 +166,7 @@ static int debug_log_cnt_wrapped = 0; | |||
157 | debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \ | 166 | debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \ |
158 | debug_log_cnt_wrapped = 1; \ | 167 | debug_log_cnt_wrapped = 1; \ |
159 | } \ | 168 | } \ |
160 | restore_flags(log_flags); \ | 169 | local_irq_restore(log_flags); \ |
161 | } | 170 | } |
162 | #else | 171 | #else |
163 | #define DEBUG_LOG(string, value) | 172 | #define DEBUG_LOG(string, value) |
@@ -320,8 +329,7 @@ void start_one_shot_timer(struct fast_timer *t, | |||
320 | 329 | ||
321 | D1(printk("sft %s %d us\n", name, delay_us)); | 330 | D1(printk("sft %s %d us\n", name, delay_us)); |
322 | 331 | ||
323 | save_flags(flags); | 332 | local_irq_save(flags); |
324 | cli(); | ||
325 | 333 | ||
326 | do_gettimeofday_fast(&t->tv_set); | 334 | do_gettimeofday_fast(&t->tv_set); |
327 | tmp = fast_timer_list; | 335 | tmp = fast_timer_list; |
@@ -395,7 +403,7 @@ void start_one_shot_timer(struct fast_timer *t, | |||
395 | 403 | ||
396 | D2(printk("start_one_shot_timer: %d us done\n", delay_us)); | 404 | D2(printk("start_one_shot_timer: %d us done\n", delay_us)); |
397 | 405 | ||
398 | restore_flags(flags); | 406 | local_irq_restore(flags); |
399 | } /* start_one_shot_timer */ | 407 | } /* start_one_shot_timer */ |
400 | 408 | ||
401 | static inline int fast_timer_pending (const struct fast_timer * t) | 409 | static inline int fast_timer_pending (const struct fast_timer * t) |
@@ -425,11 +433,10 @@ int del_fast_timer(struct fast_timer * t) | |||
425 | unsigned long flags; | 433 | unsigned long flags; |
426 | int ret; | 434 | int ret; |
427 | 435 | ||
428 | save_flags(flags); | 436 | local_irq_save(flags); |
429 | cli(); | ||
430 | ret = detach_fast_timer(t); | 437 | ret = detach_fast_timer(t); |
431 | t->next = t->prev = NULL; | 438 | t->next = t->prev = NULL; |
432 | restore_flags(flags); | 439 | local_irq_restore(flags); |
433 | return ret; | 440 | return ret; |
434 | } /* del_fast_timer */ | 441 | } /* del_fast_timer */ |
435 | 442 | ||
@@ -444,8 +451,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
444 | struct fast_timer *t; | 451 | struct fast_timer *t; |
445 | unsigned long flags; | 452 | unsigned long flags; |
446 | 453 | ||
447 | save_flags(flags); | 454 | local_irq_save(flags); |
448 | cli(); | ||
449 | 455 | ||
450 | /* Clear timer1 irq */ | 456 | /* Clear timer1 irq */ |
451 | *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); | 457 | *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); |
@@ -462,7 +468,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
462 | fast_timer_running = 0; | 468 | fast_timer_running = 0; |
463 | fast_timer_ints++; | 469 | fast_timer_ints++; |
464 | 470 | ||
465 | restore_flags(flags); | 471 | local_irq_restore(flags); |
466 | 472 | ||
467 | t = fast_timer_list; | 473 | t = fast_timer_list; |
468 | while (t) | 474 | while (t) |
@@ -482,8 +488,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
482 | fast_timers_expired++; | 488 | fast_timers_expired++; |
483 | 489 | ||
484 | /* Remove this timer before call, since it may reuse the timer */ | 490 | /* Remove this timer before call, since it may reuse the timer */ |
485 | save_flags(flags); | 491 | local_irq_save(flags); |
486 | cli(); | ||
487 | if (t->prev) | 492 | if (t->prev) |
488 | { | 493 | { |
489 | t->prev->next = t->next; | 494 | t->prev->next = t->next; |
@@ -498,7 +503,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
498 | } | 503 | } |
499 | t->prev = NULL; | 504 | t->prev = NULL; |
500 | t->next = NULL; | 505 | t->next = NULL; |
501 | restore_flags(flags); | 506 | local_irq_restore(flags); |
502 | 507 | ||
503 | if (t->function != NULL) | 508 | if (t->function != NULL) |
504 | { | 509 | { |
@@ -515,8 +520,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
515 | D1(printk(".\n")); | 520 | D1(printk(".\n")); |
516 | } | 521 | } |
517 | 522 | ||
518 | save_flags(flags); | 523 | local_irq_save(flags); |
519 | cli(); | ||
520 | if ((t = fast_timer_list) != NULL) | 524 | if ((t = fast_timer_list) != NULL) |
521 | { | 525 | { |
522 | /* Start next timer.. */ | 526 | /* Start next timer.. */ |
@@ -535,7 +539,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
535 | #endif | 539 | #endif |
536 | start_timer1(us); | 540 | start_timer1(us); |
537 | } | 541 | } |
538 | restore_flags(flags); | 542 | local_irq_restore(flags); |
539 | break; | 543 | break; |
540 | } | 544 | } |
541 | else | 545 | else |
@@ -546,7 +550,7 @@ timer1_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
546 | D1(printk("e! %d\n", us)); | 550 | D1(printk("e! %d\n", us)); |
547 | } | 551 | } |
548 | } | 552 | } |
549 | restore_flags(flags); | 553 | local_irq_restore(flags); |
550 | } | 554 | } |
551 | 555 | ||
552 | if (!t) | 556 | if (!t) |
@@ -748,13 +752,12 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
748 | #endif | 752 | #endif |
749 | 753 | ||
750 | used += sprintf(bigbuf + used, "Active timers:\n"); | 754 | used += sprintf(bigbuf + used, "Active timers:\n"); |
751 | save_flags(flags); | 755 | local_irq_save(flags); |
752 | cli(); | ||
753 | t = fast_timer_list; | 756 | t = fast_timer_list; |
754 | while (t != NULL && (used+100 < BIG_BUF_SIZE)) | 757 | while (t != NULL && (used+100 < BIG_BUF_SIZE)) |
755 | { | 758 | { |
756 | nextt = t->next; | 759 | nextt = t->next; |
757 | restore_flags(flags); | 760 | local_irq_restore(flags); |
758 | used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " | 761 | used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " |
759 | "d: %6li us data: 0x%08lX" | 762 | "d: %6li us data: 0x%08lX" |
760 | /* " func: 0x%08lX" */ | 763 | /* " func: 0x%08lX" */ |
@@ -768,14 +771,14 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
768 | t->data | 771 | t->data |
769 | /* , t->function */ | 772 | /* , t->function */ |
770 | ); | 773 | ); |
771 | cli(); | 774 | local_irq_disable(); |
772 | if (t->next != nextt) | 775 | if (t->next != nextt) |
773 | { | 776 | { |
774 | printk(KERN_WARNING "timer removed!\n"); | 777 | printk(KERN_WARNING "timer removed!\n"); |
775 | } | 778 | } |
776 | t = nextt; | 779 | t = nextt; |
777 | } | 780 | } |
778 | restore_flags(flags); | 781 | local_irq_restore(flags); |
779 | } | 782 | } |
780 | 783 | ||
781 | if (used - offset < len) | 784 | if (used - offset < len) |
@@ -963,7 +966,7 @@ void fast_timer_init(void) | |||
963 | if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) | 966 | if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) |
964 | fasttimer_proc_entry->read_proc = proc_fasttimer_read; | 967 | fasttimer_proc_entry->read_proc = proc_fasttimer_read; |
965 | #endif /* PROC_FS */ | 968 | #endif /* PROC_FS */ |
966 | if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ, | 969 | if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0, |
967 | "fast timer int", NULL)) | 970 | "fast timer int", NULL)) |
968 | { | 971 | { |
969 | printk("err: timer1 irq\n"); | 972 | printk("err: timer1 irq\n"); |
diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S index 2c1dd1184a8f..f00c145b43f1 100644 --- a/arch/cris/arch-v10/kernel/head.S +++ b/arch/cris/arch-v10/kernel/head.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: head.S,v 1.7 2004/05/14 07:58:01 starvik Exp $ | 1 | /* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $ |
2 | * | 2 | * |
3 | * Head of the kernel - alter with care | 3 | * Head of the kernel - alter with care |
4 | * | 4 | * |
@@ -7,6 +7,16 @@ | |||
7 | * Authors: Bjorn Wesen (bjornw@axis.com) | 7 | * Authors: Bjorn Wesen (bjornw@axis.com) |
8 | * | 8 | * |
9 | * $Log: head.S,v $ | 9 | * $Log: head.S,v $ |
10 | * Revision 1.10 2005/06/20 05:12:54 starvik | ||
11 | * Remove unnecessary diff to kernel.org tree | ||
12 | * | ||
13 | * Revision 1.9 2004/12/13 12:21:51 starvik | ||
14 | * Added I/O and DMA allocators from Linux 2.4 | ||
15 | * | ||
16 | * Revision 1.8 2004/11/22 11:41:14 starvik | ||
17 | * Kernel command line may be supplied to kernel. Not used by Axis but may | ||
18 | * be used by customers. | ||
19 | * | ||
10 | * Revision 1.7 2004/05/14 07:58:01 starvik | 20 | * Revision 1.7 2004/05/14 07:58:01 starvik |
11 | * Merge of changes from 2.4 | 21 | * Merge of changes from 2.4 |
12 | * | 22 | * |
@@ -181,6 +191,7 @@ | |||
181 | 191 | ||
182 | #define CRAMFS_MAGIC 0x28cd3d45 | 192 | #define CRAMFS_MAGIC 0x28cd3d45 |
183 | #define RAM_INIT_MAGIC 0x56902387 | 193 | #define RAM_INIT_MAGIC 0x56902387 |
194 | #define COMMAND_LINE_MAGIC 0x87109563 | ||
184 | 195 | ||
185 | #define START_ETHERNET_CLOCK IO_STATE(R_NETWORK_GEN_CONFIG, enable, on) |\ | 196 | #define START_ETHERNET_CLOCK IO_STATE(R_NETWORK_GEN_CONFIG, enable, on) |\ |
186 | IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | 197 | IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) |
@@ -490,6 +501,23 @@ _no_romfs_in_flash: | |||
490 | 501 | ||
491 | _start_it: | 502 | _start_it: |
492 | 503 | ||
504 | ;; Check if kernel command line is supplied | ||
505 | cmp.d COMMAND_LINE_MAGIC, $r10 | ||
506 | bne no_command_line | ||
507 | nop | ||
508 | |||
509 | move.d 256, $r13 | ||
510 | move.d cris_command_line, $r10 | ||
511 | or.d 0x80000000, $r11 ; Make it virtual | ||
512 | 1: | ||
513 | move.b [$r11+], $r12 | ||
514 | move.b $r12, [$r10+] | ||
515 | subq 1, $r13 | ||
516 | bne 1b | ||
517 | nop | ||
518 | |||
519 | no_command_line: | ||
520 | |||
493 | ;; the kernel stack is overlayed with the task structure for each | 521 | ;; the kernel stack is overlayed with the task structure for each |
494 | ;; task. thus the initial kernel stack is in the same page as the | 522 | ;; task. thus the initial kernel stack is in the same page as the |
495 | ;; init_task (but starts in the top of the page, size 8192) | 523 | ;; init_task (but starts in the top of the page, size 8192) |
@@ -567,76 +595,32 @@ _start_it: | |||
567 | ;; Etrax product HW genconfig setup | 595 | ;; Etrax product HW genconfig setup |
568 | 596 | ||
569 | moveq 0,$r0 | 597 | moveq 0,$r0 |
570 | #if (!defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT0)) \ | 598 | |
571 | && !defined(CONFIG_DMA_MEMCPY) | 599 | ;; Init interfaces (disable them). |
572 | ; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA | 600 | or.d IO_STATE (R_GEN_CONFIG, scsi0, disable) \ |
573 | or.d IO_STATE (R_GEN_CONFIG, dma7, serial0) \ | 601 | | IO_STATE (R_GEN_CONFIG, ata, disable) \ |
574 | | IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0 | 602 | | IO_STATE (R_GEN_CONFIG, par0, disable) \ |
575 | #endif | 603 | | IO_STATE (R_GEN_CONFIG, ser2, disable) \ |
576 | #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1) | 604 | | IO_STATE (R_GEN_CONFIG, mio, disable) \ |
577 | ; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA | 605 | | IO_STATE (R_GEN_CONFIG, scsi1, disable) \ |
578 | or.d IO_STATE (R_GEN_CONFIG, dma9, serial1) \ | 606 | | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \ |
579 | | IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0 | 607 | | IO_STATE (R_GEN_CONFIG, par1, disable) \ |
580 | #endif | 608 | | IO_STATE (R_GEN_CONFIG, ser3, disable) \ |
581 | #ifdef CONFIG_DMA_MEMCPY | 609 | | IO_STATE (R_GEN_CONFIG, mio_w, disable) \ |
582 | ; 6/7 memory-memory DMA | 610 | | IO_STATE (R_GEN_CONFIG, usb1, disable) \ |
583 | or.d IO_STATE (R_GEN_CONFIG, dma7, intdma6) \ | 611 | | IO_STATE (R_GEN_CONFIG, usb2, disable) \ |
584 | | IO_STATE (R_GEN_CONFIG, dma6, intdma7),$r0 | 612 | | IO_STATE (R_GEN_CONFIG, par_w, disable),$r0 |
585 | #endif | 613 | |
586 | #ifdef CONFIG_ETRAX_SERIAL_PORT2 | 614 | ;; Init DMA channel muxing (set to unused clients). |
587 | ; Enable serial port 2 | 615 | or.d IO_STATE (R_GEN_CONFIG, dma2, ata) \ |
588 | or.w IO_STATE (R_GEN_CONFIG, ser2, select),$r0 | 616 | | IO_STATE (R_GEN_CONFIG, dma3, ata) \ |
589 | #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT2) | 617 | | IO_STATE (R_GEN_CONFIG, dma4, scsi1) \ |
590 | ; DMA channels 2 and 3 to ser2, kgdb doesnt want DMA | 618 | | IO_STATE (R_GEN_CONFIG, dma5, scsi1) \ |
591 | or.d IO_STATE (R_GEN_CONFIG, dma3, serial2) \ | 619 | | IO_STATE (R_GEN_CONFIG, dma6, unused) \ |
592 | | IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0 | 620 | | IO_STATE (R_GEN_CONFIG, dma7, unused) \ |
593 | #endif | 621 | | IO_STATE (R_GEN_CONFIG, dma8, usb) \ |
594 | #endif | 622 | | IO_STATE (R_GEN_CONFIG, dma9, usb),$r0 |
595 | #if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) | 623 | |
596 | ; Enable serial port 3 | ||
597 | or.w IO_STATE (R_GEN_CONFIG, ser3, select),$r0 | ||
598 | #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT3) | ||
599 | ; DMA channels 4 and 5 to ser3, kgdb doesnt want DMA | ||
600 | or.d IO_STATE (R_GEN_CONFIG, dma5, serial3) \ | ||
601 | | IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0 | ||
602 | #endif | ||
603 | #endif | ||
604 | #if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE) | ||
605 | ; parport 0 enabled using DMA 2/3 | ||
606 | or.w IO_STATE (R_GEN_CONFIG, par0, select),$r0 | ||
607 | #endif | ||
608 | #if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE) | ||
609 | ; parport 1 enabled using DMA 4/5 | ||
610 | or.w IO_STATE (R_GEN_CONFIG, par1, select),$r0 | ||
611 | #endif | ||
612 | #ifdef CONFIG_ETRAX_IDE | ||
613 | ; DMA channels 2 and 3 to ATA, ATA enabled | ||
614 | or.d IO_STATE (R_GEN_CONFIG, dma3, ata) \ | ||
615 | | IO_STATE (R_GEN_CONFIG, dma2, ata) \ | ||
616 | | IO_STATE (R_GEN_CONFIG, ata, select),$r0 | ||
617 | #endif | ||
618 | |||
619 | #ifdef CONFIG_ETRAX_USB_HOST_PORT1 | ||
620 | ; Set the USB port 1 enable bit | ||
621 | or.d IO_STATE (R_GEN_CONFIG, usb1, select),$r0 | ||
622 | #endif | ||
623 | #ifdef CONFIG_ETRAX_USB_HOST_PORT2 | ||
624 | ; Set the USB port 2 enable bit | ||
625 | or.d IO_STATE (R_GEN_CONFIG, usb2, select),$r0 | ||
626 | #endif | ||
627 | #ifdef CONFIG_ETRAX_USB_HOST | ||
628 | ; Connect DMA channels 8 and 9 to USB | ||
629 | and.d (~(IO_MASK (R_GEN_CONFIG, dma9) \ | ||
630 | | IO_MASK (R_GEN_CONFIG, dma8))) \ | ||
631 | | IO_STATE (R_GEN_CONFIG, dma9, usb) \ | ||
632 | | IO_STATE (R_GEN_CONFIG, dma8, usb),$r0 | ||
633 | #endif | ||
634 | |||
635 | #ifdef CONFIG_JULIETTE | ||
636 | ; DMA channels 4 and 5 to EXTDMA0, for Juliette | ||
637 | or.d IO_STATE (R_GEN_CONFIG, dma5, extdma0) \ | ||
638 | | IO_STATE (R_GEN_CONFIG, dma4, extdma0),$r0 | ||
639 | #endif | ||
640 | 624 | ||
641 | #if defined(CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT) | 625 | #if defined(CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT) |
642 | or.d IO_STATE (R_GEN_CONFIG, g0dir, out),$r0 | 626 | or.d IO_STATE (R_GEN_CONFIG, g0dir, out),$r0 |
diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c new file mode 100644 index 000000000000..29d48ad00df9 --- /dev/null +++ b/arch/cris/arch-v10/kernel/io_interface_mux.c | |||
@@ -0,0 +1,879 @@ | |||
1 | /* IO interface mux allocator for ETRAX100LX. | ||
2 | * Copyright 2004, Axis Communications AB | ||
3 | * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $ | ||
4 | */ | ||
5 | |||
6 | |||
7 | /* C.f. ETRAX100LX Designer's Reference 20.9 */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/arch/svinto.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/arch/io_interface_mux.h> | ||
18 | |||
19 | |||
20 | #define DBG(s) | ||
21 | |||
22 | /* Macro to access ETRAX 100 registers */ | ||
23 | #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ | ||
24 | IO_STATE_(reg##_, field##_, _##val) | ||
25 | |||
26 | enum io_if_group { | ||
27 | group_a = (1<<0), | ||
28 | group_b = (1<<1), | ||
29 | group_c = (1<<2), | ||
30 | group_d = (1<<3), | ||
31 | group_e = (1<<4), | ||
32 | group_f = (1<<5) | ||
33 | }; | ||
34 | |||
35 | struct watcher | ||
36 | { | ||
37 | void (*notify)(const unsigned int gpio_in_available, | ||
38 | const unsigned int gpio_out_available, | ||
39 | const unsigned char pa_available, | ||
40 | const unsigned char pb_available); | ||
41 | struct watcher *next; | ||
42 | }; | ||
43 | |||
44 | |||
45 | struct if_group | ||
46 | { | ||
47 | enum io_if_group group; | ||
48 | unsigned char used; | ||
49 | enum cris_io_interface owner; | ||
50 | }; | ||
51 | |||
52 | |||
53 | struct interface | ||
54 | { | ||
55 | enum cris_io_interface ioif; | ||
56 | unsigned char groups; | ||
57 | unsigned char used; | ||
58 | char *owner; | ||
59 | unsigned int gpio_g_in; | ||
60 | unsigned int gpio_g_out; | ||
61 | unsigned char gpio_b; | ||
62 | }; | ||
63 | |||
64 | static struct if_group if_groups[6] = { | ||
65 | { | ||
66 | .group = group_a, | ||
67 | .used = 0, | ||
68 | }, | ||
69 | { | ||
70 | .group = group_b, | ||
71 | .used = 0, | ||
72 | }, | ||
73 | { | ||
74 | .group = group_c, | ||
75 | .used = 0, | ||
76 | }, | ||
77 | { | ||
78 | .group = group_d, | ||
79 | .used = 0, | ||
80 | }, | ||
81 | { | ||
82 | .group = group_e, | ||
83 | .used = 0, | ||
84 | }, | ||
85 | { | ||
86 | .group = group_f, | ||
87 | .used = 0, | ||
88 | } | ||
89 | }; | ||
90 | |||
91 | /* The order in the array must match the order of enum | ||
92 | * cris_io_interface in io_interface_mux.h */ | ||
93 | static struct interface interfaces[] = { | ||
94 | /* Begin Non-multiplexed interfaces */ | ||
95 | { | ||
96 | .ioif = if_eth, | ||
97 | .groups = 0, | ||
98 | .gpio_g_in = 0, | ||
99 | .gpio_g_out = 0, | ||
100 | .gpio_b = 0 | ||
101 | }, | ||
102 | { | ||
103 | .ioif = if_serial_0, | ||
104 | .groups = 0, | ||
105 | .gpio_g_in = 0, | ||
106 | .gpio_g_out = 0, | ||
107 | .gpio_b = 0 | ||
108 | }, | ||
109 | /* End Non-multiplexed interfaces */ | ||
110 | { | ||
111 | .ioif = if_serial_1, | ||
112 | .groups = group_e, | ||
113 | .gpio_g_in = 0x00000000, | ||
114 | .gpio_g_out = 0x00000000, | ||
115 | .gpio_b = 0x00 | ||
116 | }, | ||
117 | { | ||
118 | .ioif = if_serial_2, | ||
119 | .groups = group_b, | ||
120 | .gpio_g_in = 0x000000c0, | ||
121 | .gpio_g_out = 0x000000c0, | ||
122 | .gpio_b = 0x00 | ||
123 | }, | ||
124 | { | ||
125 | .ioif = if_serial_3, | ||
126 | .groups = group_c, | ||
127 | .gpio_g_in = 0xc0000000, | ||
128 | .gpio_g_out = 0xc0000000, | ||
129 | .gpio_b = 0x00 | ||
130 | }, | ||
131 | { | ||
132 | .ioif = if_sync_serial_1, | ||
133 | .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3 | ||
134 | can be used simultaneously */ | ||
135 | .gpio_g_in = 0x00000000, | ||
136 | .gpio_g_out = 0x00000000, | ||
137 | .gpio_b = 0x10 | ||
138 | }, | ||
139 | { | ||
140 | .ioif = if_sync_serial_3, | ||
141 | .groups = group_c | group_f, | ||
142 | .gpio_g_in = 0xc0000000, | ||
143 | .gpio_g_out = 0xc0000000, | ||
144 | .gpio_b = 0x80 | ||
145 | }, | ||
146 | { | ||
147 | .ioif = if_shared_ram, | ||
148 | .groups = group_a, | ||
149 | .gpio_g_in = 0x0000ff3e, | ||
150 | .gpio_g_out = 0x0000ff38, | ||
151 | .gpio_b = 0x00 | ||
152 | }, | ||
153 | { | ||
154 | .ioif = if_shared_ram_w, | ||
155 | .groups = group_a | group_d, | ||
156 | .gpio_g_in = 0x00ffff3e, | ||
157 | .gpio_g_out = 0x00ffff38, | ||
158 | .gpio_b = 0x00 | ||
159 | }, | ||
160 | { | ||
161 | .ioif = if_par_0, | ||
162 | .groups = group_a, | ||
163 | .gpio_g_in = 0x0000ff3e, | ||
164 | .gpio_g_out = 0x0000ff3e, | ||
165 | .gpio_b = 0x00 | ||
166 | }, | ||
167 | { | ||
168 | .ioif = if_par_1, | ||
169 | .groups = group_d, | ||
170 | .gpio_g_in = 0x3eff0000, | ||
171 | .gpio_g_out = 0x3eff0000, | ||
172 | .gpio_b = 0x00 | ||
173 | }, | ||
174 | { | ||
175 | .ioif = if_par_w, | ||
176 | .groups = group_a | group_d, | ||
177 | .gpio_g_in = 0x00ffff3e, | ||
178 | .gpio_g_out = 0x00ffff3e, | ||
179 | .gpio_b = 0x00 | ||
180 | }, | ||
181 | { | ||
182 | .ioif = if_scsi8_0, | ||
183 | .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1 | ||
184 | can be used simultaneously */ | ||
185 | .gpio_g_in = 0x0000ffff, | ||
186 | .gpio_g_out = 0x0000ffff, | ||
187 | .gpio_b = 0x10 | ||
188 | }, | ||
189 | { | ||
190 | .ioif = if_scsi8_1, | ||
191 | .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1 | ||
192 | can be used simultaneously */ | ||
193 | .gpio_g_in = 0xffff0000, | ||
194 | .gpio_g_out = 0xffff0000, | ||
195 | .gpio_b = 0x80 | ||
196 | }, | ||
197 | { | ||
198 | .ioif = if_scsi_w, | ||
199 | .groups = group_a | group_b | group_d | group_f, | ||
200 | .gpio_g_in = 0x01ffffff, | ||
201 | .gpio_g_out = 0x07ffffff, | ||
202 | .gpio_b = 0x80 | ||
203 | }, | ||
204 | { | ||
205 | .ioif = if_ata, | ||
206 | .groups = group_a | group_b | group_c | group_d, | ||
207 | .gpio_g_in = 0xf9ffffff, | ||
208 | .gpio_g_out = 0xffffffff, | ||
209 | .gpio_b = 0x80 | ||
210 | }, | ||
211 | { | ||
212 | .ioif = if_csp, | ||
213 | .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ | ||
214 | .gpio_g_in = 0x00000000, | ||
215 | .gpio_g_out = 0x00000000, | ||
216 | .gpio_b = 0xfc | ||
217 | }, | ||
218 | { | ||
219 | .ioif = if_i2c, | ||
220 | .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ | ||
221 | .gpio_g_in = 0x00000000, | ||
222 | .gpio_g_out = 0x00000000, | ||
223 | .gpio_b = 0x03 | ||
224 | }, | ||
225 | { | ||
226 | .ioif = if_usb_1, | ||
227 | .groups = group_e | group_f, | ||
228 | .gpio_g_in = 0x00000000, | ||
229 | .gpio_g_out = 0x00000000, | ||
230 | .gpio_b = 0x2c | ||
231 | }, | ||
232 | { | ||
233 | .ioif = if_usb_2, | ||
234 | .groups = group_d, | ||
235 | .gpio_g_in = 0x0e000000, | ||
236 | .gpio_g_out = 0x3c000000, | ||
237 | .gpio_b = 0x00 | ||
238 | }, | ||
239 | /* GPIO pins */ | ||
240 | { | ||
241 | .ioif = if_gpio_grp_a, | ||
242 | .groups = group_a, | ||
243 | .gpio_g_in = 0x0000ff3f, | ||
244 | .gpio_g_out = 0x0000ff3f, | ||
245 | .gpio_b = 0x00 | ||
246 | }, | ||
247 | { | ||
248 | .ioif = if_gpio_grp_b, | ||
249 | .groups = group_b, | ||
250 | .gpio_g_in = 0x000000c0, | ||
251 | .gpio_g_out = 0x000000c0, | ||
252 | .gpio_b = 0x00 | ||
253 | }, | ||
254 | { | ||
255 | .ioif = if_gpio_grp_c, | ||
256 | .groups = group_c, | ||
257 | .gpio_g_in = 0xc0000000, | ||
258 | .gpio_g_out = 0xc0000000, | ||
259 | .gpio_b = 0x00 | ||
260 | }, | ||
261 | { | ||
262 | .ioif = if_gpio_grp_d, | ||
263 | .groups = group_d, | ||
264 | .gpio_g_in = 0x3fff0000, | ||
265 | .gpio_g_out = 0x3fff0000, | ||
266 | .gpio_b = 0x00 | ||
267 | }, | ||
268 | { | ||
269 | .ioif = if_gpio_grp_e, | ||
270 | .groups = group_e, | ||
271 | .gpio_g_in = 0x00000000, | ||
272 | .gpio_g_out = 0x00000000, | ||
273 | .gpio_b = 0x00 | ||
274 | }, | ||
275 | { | ||
276 | .ioif = if_gpio_grp_f, | ||
277 | .groups = group_f, | ||
278 | .gpio_g_in = 0x00000000, | ||
279 | .gpio_g_out = 0x00000000, | ||
280 | .gpio_b = 0xff | ||
281 | } | ||
282 | /* Array end */ | ||
283 | }; | ||
284 | |||
285 | static struct watcher *watchers = NULL; | ||
286 | |||
287 | static unsigned int gpio_in_pins = 0xffffffff; | ||
288 | static unsigned int gpio_out_pins = 0xffffffff; | ||
289 | static unsigned char gpio_pb_pins = 0xff; | ||
290 | static unsigned char gpio_pa_pins = 0xff; | ||
291 | |||
292 | static enum cris_io_interface gpio_pa_owners[8]; | ||
293 | static enum cris_io_interface gpio_pb_owners[8]; | ||
294 | static enum cris_io_interface gpio_pg_owners[32]; | ||
295 | |||
296 | static int cris_io_interface_init(void); | ||
297 | |||
298 | static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group) | ||
299 | { | ||
300 | return (groups & ~group->group); | ||
301 | } | ||
302 | |||
303 | |||
304 | static struct if_group *get_group(const unsigned char groups) | ||
305 | { | ||
306 | int i; | ||
307 | for (i = 0; i < sizeof(if_groups)/sizeof(struct if_group); i++) { | ||
308 | if (groups & if_groups[i].group) { | ||
309 | return &if_groups[i]; | ||
310 | } | ||
311 | } | ||
312 | return NULL; | ||
313 | } | ||
314 | |||
315 | |||
316 | static void notify_watchers(void) | ||
317 | { | ||
318 | struct watcher *w = watchers; | ||
319 | |||
320 | DBG(printk("io_interface_mux: notifying watchers\n")); | ||
321 | |||
322 | while (NULL != w) { | ||
323 | w->notify((const unsigned int)gpio_in_pins, | ||
324 | (const unsigned int)gpio_out_pins, | ||
325 | (const unsigned char)gpio_pa_pins, | ||
326 | (const unsigned char)gpio_pb_pins); | ||
327 | w = w->next; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | |||
332 | int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id) | ||
333 | { | ||
334 | int set_gen_config = 0; | ||
335 | int set_gen_config_ii = 0; | ||
336 | unsigned long int gens; | ||
337 | unsigned long int gens_ii; | ||
338 | struct if_group *grp; | ||
339 | unsigned char group_set; | ||
340 | unsigned long flags; | ||
341 | |||
342 | (void)cris_io_interface_init(); | ||
343 | |||
344 | DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id)); | ||
345 | |||
346 | if ((ioif >= if_max_interfaces) || (ioif < 0)) { | ||
347 | printk(KERN_CRIT "cris_request_io_interface: Bad interface %u submitted for %s\n", | ||
348 | ioif, | ||
349 | device_id); | ||
350 | return -EINVAL; | ||
351 | } | ||
352 | |||
353 | local_irq_save(flags); | ||
354 | |||
355 | if (interfaces[ioif].used) { | ||
356 | local_irq_restore(flags); | ||
357 | printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n", | ||
358 | device_id, | ||
359 | interfaces[ioif].owner); | ||
360 | return -EBUSY; | ||
361 | } | ||
362 | |||
363 | /* Check that all required groups are free before allocating, */ | ||
364 | group_set = interfaces[ioif].groups; | ||
365 | while (NULL != (grp = get_group(group_set))) { | ||
366 | if (grp->used) { | ||
367 | if (grp->group == group_f) { | ||
368 | if ((if_sync_serial_1 == ioif) || | ||
369 | (if_sync_serial_3 == ioif)) { | ||
370 | if ((grp->owner != if_sync_serial_1) && | ||
371 | (grp->owner != if_sync_serial_3)) { | ||
372 | local_irq_restore(flags); | ||
373 | return -EBUSY; | ||
374 | } | ||
375 | } else if ((if_scsi8_0 == ioif) || | ||
376 | (if_scsi8_1 == ioif)) { | ||
377 | if ((grp->owner != if_scsi8_0) && | ||
378 | (grp->owner != if_scsi8_1)) { | ||
379 | local_irq_restore(flags); | ||
380 | return -EBUSY; | ||
381 | } | ||
382 | } | ||
383 | } else { | ||
384 | local_irq_restore(flags); | ||
385 | return -EBUSY; | ||
386 | } | ||
387 | } | ||
388 | group_set = clear_group_from_set(group_set, grp); | ||
389 | } | ||
390 | |||
391 | /* Are the required GPIO pins available too? */ | ||
392 | if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) || | ||
393 | ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) || | ||
394 | ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) { | ||
395 | printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n", | ||
396 | ioif); | ||
397 | return -EBUSY; | ||
398 | } | ||
399 | |||
400 | /* All needed I/O pins and pin groups are free, allocate. */ | ||
401 | group_set = interfaces[ioif].groups; | ||
402 | while (NULL != (grp = get_group(group_set))) { | ||
403 | grp->used = 1; | ||
404 | grp->owner = ioif; | ||
405 | group_set = clear_group_from_set(group_set, grp); | ||
406 | } | ||
407 | |||
408 | gens = genconfig_shadow; | ||
409 | gens_ii = gen_config_ii_shadow; | ||
410 | |||
411 | set_gen_config = 1; | ||
412 | switch (ioif) | ||
413 | { | ||
414 | /* Begin Non-multiplexed interfaces */ | ||
415 | case if_eth: | ||
416 | /* fall through */ | ||
417 | case if_serial_0: | ||
418 | set_gen_config = 0; | ||
419 | break; | ||
420 | /* End Non-multiplexed interfaces */ | ||
421 | case if_serial_1: | ||
422 | set_gen_config_ii = 1; | ||
423 | SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async); | ||
424 | break; | ||
425 | case if_serial_2: | ||
426 | SETS(gens, R_GEN_CONFIG, ser2, select); | ||
427 | break; | ||
428 | case if_serial_3: | ||
429 | SETS(gens, R_GEN_CONFIG, ser3, select); | ||
430 | set_gen_config_ii = 1; | ||
431 | SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async); | ||
432 | break; | ||
433 | case if_sync_serial_1: | ||
434 | set_gen_config_ii = 1; | ||
435 | SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync); | ||
436 | break; | ||
437 | case if_sync_serial_3: | ||
438 | SETS(gens, R_GEN_CONFIG, ser3, select); | ||
439 | set_gen_config_ii = 1; | ||
440 | SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync); | ||
441 | break; | ||
442 | case if_shared_ram: | ||
443 | SETS(gens, R_GEN_CONFIG, mio, select); | ||
444 | break; | ||
445 | case if_shared_ram_w: | ||
446 | SETS(gens, R_GEN_CONFIG, mio_w, select); | ||
447 | break; | ||
448 | case if_par_0: | ||
449 | SETS(gens, R_GEN_CONFIG, par0, select); | ||
450 | break; | ||
451 | case if_par_1: | ||
452 | SETS(gens, R_GEN_CONFIG, par1, select); | ||
453 | break; | ||
454 | case if_par_w: | ||
455 | SETS(gens, R_GEN_CONFIG, par0, select); | ||
456 | SETS(gens, R_GEN_CONFIG, par_w, select); | ||
457 | break; | ||
458 | case if_scsi8_0: | ||
459 | SETS(gens, R_GEN_CONFIG, scsi0, select); | ||
460 | break; | ||
461 | case if_scsi8_1: | ||
462 | SETS(gens, R_GEN_CONFIG, scsi1, select); | ||
463 | break; | ||
464 | case if_scsi_w: | ||
465 | SETS(gens, R_GEN_CONFIG, scsi0, select); | ||
466 | SETS(gens, R_GEN_CONFIG, scsi0w, select); | ||
467 | break; | ||
468 | case if_ata: | ||
469 | SETS(gens, R_GEN_CONFIG, ata, select); | ||
470 | break; | ||
471 | case if_csp: | ||
472 | /* fall through */ | ||
473 | case if_i2c: | ||
474 | set_gen_config = 0; | ||
475 | break; | ||
476 | case if_usb_1: | ||
477 | SETS(gens, R_GEN_CONFIG, usb1, select); | ||
478 | break; | ||
479 | case if_usb_2: | ||
480 | SETS(gens, R_GEN_CONFIG, usb2, select); | ||
481 | break; | ||
482 | case if_gpio_grp_a: | ||
483 | /* GPIO groups are only accounted, don't do configuration changes. */ | ||
484 | /* fall through */ | ||
485 | case if_gpio_grp_b: | ||
486 | /* fall through */ | ||
487 | case if_gpio_grp_c: | ||
488 | /* fall through */ | ||
489 | case if_gpio_grp_d: | ||
490 | /* fall through */ | ||
491 | case if_gpio_grp_e: | ||
492 | /* fall through */ | ||
493 | case if_gpio_grp_f: | ||
494 | set_gen_config = 0; | ||
495 | break; | ||
496 | default: | ||
497 | panic("cris_request_io_interface: Bad interface %u submitted for %s\n", | ||
498 | ioif, | ||
499 | device_id); | ||
500 | } | ||
501 | |||
502 | interfaces[ioif].used = 1; | ||
503 | interfaces[ioif].owner = (char*)device_id; | ||
504 | |||
505 | if (set_gen_config) { | ||
506 | volatile int i; | ||
507 | genconfig_shadow = gens; | ||
508 | *R_GEN_CONFIG = genconfig_shadow; | ||
509 | /* Wait 12 cycles before doing any DMA command */ | ||
510 | for(i = 6; i > 0; i--) | ||
511 | nop(); | ||
512 | } | ||
513 | if (set_gen_config_ii) { | ||
514 | gen_config_ii_shadow = gens_ii; | ||
515 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | ||
516 | } | ||
517 | |||
518 | DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
519 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | ||
520 | DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
521 | interfaces[ioif].gpio_g_in, | ||
522 | interfaces[ioif].gpio_g_out, | ||
523 | interfaces[ioif].gpio_b)); | ||
524 | |||
525 | gpio_in_pins &= ~interfaces[ioif].gpio_g_in; | ||
526 | gpio_out_pins &= ~interfaces[ioif].gpio_g_out; | ||
527 | gpio_pb_pins &= ~interfaces[ioif].gpio_b; | ||
528 | |||
529 | DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
530 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | ||
531 | |||
532 | local_irq_restore(flags); | ||
533 | |||
534 | notify_watchers(); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | |||
540 | void cris_free_io_interface(enum cris_io_interface ioif) | ||
541 | { | ||
542 | struct if_group *grp; | ||
543 | unsigned char group_set; | ||
544 | unsigned long flags; | ||
545 | |||
546 | (void)cris_io_interface_init(); | ||
547 | |||
548 | if ((ioif >= if_max_interfaces) || (ioif < 0)) { | ||
549 | printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n", | ||
550 | ioif); | ||
551 | return; | ||
552 | } | ||
553 | local_irq_save(flags); | ||
554 | if (!interfaces[ioif].used) { | ||
555 | printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n", | ||
556 | ioif); | ||
557 | local_irq_restore(flags); | ||
558 | return; | ||
559 | } | ||
560 | group_set = interfaces[ioif].groups; | ||
561 | while (NULL != (grp = get_group(group_set))) { | ||
562 | if (grp->group == group_f) { | ||
563 | switch (ioif) | ||
564 | { | ||
565 | case if_sync_serial_1: | ||
566 | if ((grp->owner == if_sync_serial_1) && | ||
567 | interfaces[if_sync_serial_3].used) { | ||
568 | grp->owner = if_sync_serial_3; | ||
569 | } else | ||
570 | grp->used = 0; | ||
571 | break; | ||
572 | case if_sync_serial_3: | ||
573 | if ((grp->owner == if_sync_serial_3) && | ||
574 | interfaces[if_sync_serial_1].used) { | ||
575 | grp->owner = if_sync_serial_1; | ||
576 | } else | ||
577 | grp->used = 0; | ||
578 | break; | ||
579 | case if_scsi8_0: | ||
580 | if ((grp->owner == if_scsi8_0) && | ||
581 | interfaces[if_scsi8_1].used) { | ||
582 | grp->owner = if_scsi8_1; | ||
583 | } else | ||
584 | grp->used = 0; | ||
585 | break; | ||
586 | case if_scsi8_1: | ||
587 | if ((grp->owner == if_scsi8_1) && | ||
588 | interfaces[if_scsi8_0].used) { | ||
589 | grp->owner = if_scsi8_0; | ||
590 | } else | ||
591 | grp->used = 0; | ||
592 | break; | ||
593 | default: | ||
594 | grp->used = 0; | ||
595 | } | ||
596 | } else { | ||
597 | grp->used = 0; | ||
598 | } | ||
599 | group_set = clear_group_from_set(group_set, grp); | ||
600 | } | ||
601 | interfaces[ioif].used = 0; | ||
602 | interfaces[ioif].owner = NULL; | ||
603 | |||
604 | DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
605 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | ||
606 | DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
607 | interfaces[ioif].gpio_g_in, | ||
608 | interfaces[ioif].gpio_g_out, | ||
609 | interfaces[ioif].gpio_b)); | ||
610 | |||
611 | gpio_in_pins |= interfaces[ioif].gpio_g_in; | ||
612 | gpio_out_pins |= interfaces[ioif].gpio_g_out; | ||
613 | gpio_pb_pins |= interfaces[ioif].gpio_b; | ||
614 | |||
615 | DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | ||
616 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | ||
617 | |||
618 | local_irq_restore(flags); | ||
619 | |||
620 | notify_watchers(); | ||
621 | } | ||
622 | |||
623 | /* Create a bitmask from bit 0 (inclusive) to bit stop_bit | ||
624 | (non-inclusive). stop_bit == 0 returns 0x0 */ | ||
625 | static inline unsigned int create_mask(const unsigned stop_bit) | ||
626 | { | ||
627 | /* Avoid overflow */ | ||
628 | if (stop_bit >= 32) { | ||
629 | return 0xffffffff; | ||
630 | } | ||
631 | return (1<<stop_bit)-1; | ||
632 | } | ||
633 | |||
634 | |||
635 | /* port can be 'a', 'b' or 'g' */ | ||
636 | int cris_io_interface_allocate_pins(const enum cris_io_interface ioif, | ||
637 | const char port, | ||
638 | const unsigned start_bit, | ||
639 | const unsigned stop_bit) | ||
640 | { | ||
641 | unsigned int i; | ||
642 | unsigned int mask = 0; | ||
643 | unsigned int tmp_mask; | ||
644 | unsigned long int flags; | ||
645 | enum cris_io_interface *owners; | ||
646 | |||
647 | (void)cris_io_interface_init(); | ||
648 | |||
649 | DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n", | ||
650 | ioif, port, start_bit, stop_bit)); | ||
651 | |||
652 | if (!((start_bit <= stop_bit) && | ||
653 | ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) || | ||
654 | ((port == 'g') && (stop_bit < 32))))) { | ||
655 | return -EINVAL; | ||
656 | } | ||
657 | |||
658 | mask = create_mask(stop_bit + 1); | ||
659 | tmp_mask = create_mask(start_bit); | ||
660 | mask &= ~tmp_mask; | ||
661 | |||
662 | DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n", | ||
663 | port, start_bit, stop_bit, mask)); | ||
664 | |||
665 | local_irq_save(flags); | ||
666 | |||
667 | switch (port) { | ||
668 | case 'a': | ||
669 | if ((gpio_pa_pins & mask) != mask) { | ||
670 | local_irq_restore(flags); | ||
671 | return -EBUSY; | ||
672 | } | ||
673 | owners = gpio_pa_owners; | ||
674 | gpio_pa_pins &= ~mask; | ||
675 | break; | ||
676 | case 'b': | ||
677 | if ((gpio_pb_pins & mask) != mask) { | ||
678 | local_irq_restore(flags); | ||
679 | return -EBUSY; | ||
680 | } | ||
681 | owners = gpio_pb_owners; | ||
682 | gpio_pb_pins &= ~mask; | ||
683 | break; | ||
684 | case 'g': | ||
685 | if (((gpio_in_pins & mask) != mask) || | ||
686 | ((gpio_out_pins & mask) != mask)) { | ||
687 | local_irq_restore(flags); | ||
688 | return -EBUSY; | ||
689 | } | ||
690 | owners = gpio_pg_owners; | ||
691 | gpio_in_pins &= ~mask; | ||
692 | gpio_out_pins &= ~mask; | ||
693 | break; | ||
694 | default: | ||
695 | local_irq_restore(flags); | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | |||
699 | for (i = start_bit; i <= stop_bit; i++) { | ||
700 | owners[i] = ioif; | ||
701 | } | ||
702 | local_irq_restore(flags); | ||
703 | |||
704 | notify_watchers(); | ||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | |||
709 | /* port can be 'a', 'b' or 'g' */ | ||
710 | int cris_io_interface_free_pins(const enum cris_io_interface ioif, | ||
711 | const char port, | ||
712 | const unsigned start_bit, | ||
713 | const unsigned stop_bit) | ||
714 | { | ||
715 | unsigned int i; | ||
716 | unsigned int mask = 0; | ||
717 | unsigned int tmp_mask; | ||
718 | unsigned long int flags; | ||
719 | enum cris_io_interface *owners; | ||
720 | |||
721 | (void)cris_io_interface_init(); | ||
722 | |||
723 | if (!((start_bit <= stop_bit) && | ||
724 | ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) || | ||
725 | ((port == 'g') && (stop_bit < 32))))) { | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | mask = create_mask(stop_bit + 1); | ||
730 | tmp_mask = create_mask(start_bit); | ||
731 | mask &= ~tmp_mask; | ||
732 | |||
733 | DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n", | ||
734 | port, start_bit, stop_bit, mask)); | ||
735 | |||
736 | local_irq_save(flags); | ||
737 | |||
738 | switch (port) { | ||
739 | case 'a': | ||
740 | if ((~gpio_pa_pins & mask) != mask) { | ||
741 | local_irq_restore(flags); | ||
742 | printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); | ||
743 | } | ||
744 | owners = gpio_pa_owners; | ||
745 | break; | ||
746 | case 'b': | ||
747 | if ((~gpio_pb_pins & mask) != mask) { | ||
748 | local_irq_restore(flags); | ||
749 | printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); | ||
750 | } | ||
751 | owners = gpio_pb_owners; | ||
752 | break; | ||
753 | case 'g': | ||
754 | if (((~gpio_in_pins & mask) != mask) || | ||
755 | ((~gpio_out_pins & mask) != mask)) { | ||
756 | local_irq_restore(flags); | ||
757 | printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); | ||
758 | } | ||
759 | owners = gpio_pg_owners; | ||
760 | break; | ||
761 | default: | ||
762 | owners = NULL; /* Cannot happen. Shut up, gcc! */ | ||
763 | } | ||
764 | |||
765 | for (i = start_bit; i <= stop_bit; i++) { | ||
766 | if (owners[i] != ioif) { | ||
767 | printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins"); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | /* All was ok, change data. */ | ||
772 | switch (port) { | ||
773 | case 'a': | ||
774 | gpio_pa_pins |= mask; | ||
775 | break; | ||
776 | case 'b': | ||
777 | gpio_pb_pins |= mask; | ||
778 | break; | ||
779 | case 'g': | ||
780 | gpio_in_pins |= mask; | ||
781 | gpio_out_pins |= mask; | ||
782 | break; | ||
783 | } | ||
784 | |||
785 | for (i = start_bit; i <= stop_bit; i++) { | ||
786 | owners[i] = if_unclaimed; | ||
787 | } | ||
788 | local_irq_restore(flags); | ||
789 | notify_watchers(); | ||
790 | |||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | |||
795 | int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available, | ||
796 | const unsigned int gpio_out_available, | ||
797 | const unsigned char pa_available, | ||
798 | const unsigned char pb_available)) | ||
799 | { | ||
800 | struct watcher *w; | ||
801 | |||
802 | (void)cris_io_interface_init(); | ||
803 | |||
804 | if (NULL == notify) { | ||
805 | return -EINVAL; | ||
806 | } | ||
807 | w = kmalloc(sizeof(*w), GFP_KERNEL); | ||
808 | if (!w) { | ||
809 | return -ENOMEM; | ||
810 | } | ||
811 | w->notify = notify; | ||
812 | w->next = watchers; | ||
813 | watchers = w; | ||
814 | |||
815 | w->notify((const unsigned int)gpio_in_pins, | ||
816 | (const unsigned int)gpio_out_pins, | ||
817 | (const unsigned char)gpio_pa_pins, | ||
818 | (const unsigned char)gpio_pb_pins); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available, | ||
824 | const unsigned int gpio_out_available, | ||
825 | const unsigned char pa_available, | ||
826 | const unsigned char pb_available)) | ||
827 | { | ||
828 | struct watcher *w = watchers, *prev = NULL; | ||
829 | |||
830 | (void)cris_io_interface_init(); | ||
831 | |||
832 | while ((NULL != w) && (w->notify != notify)){ | ||
833 | prev = w; | ||
834 | w = w->next; | ||
835 | } | ||
836 | if (NULL != w) { | ||
837 | if (NULL != prev) { | ||
838 | prev->next = w->next; | ||
839 | } else { | ||
840 | watchers = w->next; | ||
841 | } | ||
842 | kfree(w); | ||
843 | return; | ||
844 | } | ||
845 | printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify); | ||
846 | } | ||
847 | |||
848 | |||
849 | static int cris_io_interface_init(void) | ||
850 | { | ||
851 | static int first = 1; | ||
852 | int i; | ||
853 | |||
854 | if (!first) { | ||
855 | return 0; | ||
856 | } | ||
857 | first = 0; | ||
858 | |||
859 | for (i = 0; i<8; i++) { | ||
860 | gpio_pa_owners[i] = if_unclaimed; | ||
861 | gpio_pb_owners[i] = if_unclaimed; | ||
862 | gpio_pg_owners[i] = if_unclaimed; | ||
863 | } | ||
864 | for (; i<32; i++) { | ||
865 | gpio_pg_owners[i] = if_unclaimed; | ||
866 | } | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | |||
871 | module_init(cris_io_interface_init); | ||
872 | |||
873 | |||
874 | EXPORT_SYMBOL(cris_request_io_interface); | ||
875 | EXPORT_SYMBOL(cris_free_io_interface); | ||
876 | EXPORT_SYMBOL(cris_io_interface_allocate_pins); | ||
877 | EXPORT_SYMBOL(cris_io_interface_free_pins); | ||
878 | EXPORT_SYMBOL(cris_io_interface_register_watcher); | ||
879 | EXPORT_SYMBOL(cris_io_interface_delete_watcher); | ||
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index b2f16d6fc871..4b368a122015 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: irq.c,v 1.2 2004/06/09 05:30:27 starvik Exp $ | 1 | /* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $ |
2 | * | 2 | * |
3 | * linux/arch/cris/kernel/irq.c | 3 | * linux/arch/cris/kernel/irq.c |
4 | * | 4 | * |
@@ -12,11 +12,13 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
15 | #include <linux/irq.h> | ||
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/config.h> | 18 | #include <linux/config.h> |
18 | 19 | ||
19 | irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */ | 20 | #define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); |
21 | #define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); | ||
20 | 22 | ||
21 | /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is | 23 | /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is |
22 | * global just so that the kernel gdb can use it. | 24 | * global just so that the kernel gdb can use it. |
@@ -102,41 +104,52 @@ static void (*interrupt[NR_IRQS])(void) = { | |||
102 | IRQ31_interrupt | 104 | IRQ31_interrupt |
103 | }; | 105 | }; |
104 | 106 | ||
105 | static void (*bad_interrupt[NR_IRQS])(void) = { | 107 | static void enable_crisv10_irq(unsigned int irq); |
106 | NULL, NULL, | 108 | |
107 | NULL, bad_IRQ3_interrupt, | 109 | static unsigned int startup_crisv10_irq(unsigned int irq) |
108 | bad_IRQ4_interrupt, bad_IRQ5_interrupt, | 110 | { |
109 | bad_IRQ6_interrupt, bad_IRQ7_interrupt, | 111 | enable_crisv10_irq(irq); |
110 | bad_IRQ8_interrupt, bad_IRQ9_interrupt, | 112 | return 0; |
111 | bad_IRQ10_interrupt, bad_IRQ11_interrupt, | 113 | } |
112 | bad_IRQ12_interrupt, bad_IRQ13_interrupt, | 114 | |
113 | NULL, NULL, | 115 | #define shutdown_crisv10_irq disable_crisv10_irq |
114 | bad_IRQ16_interrupt, bad_IRQ17_interrupt, | ||
115 | bad_IRQ18_interrupt, bad_IRQ19_interrupt, | ||
116 | bad_IRQ20_interrupt, bad_IRQ21_interrupt, | ||
117 | bad_IRQ22_interrupt, bad_IRQ23_interrupt, | ||
118 | bad_IRQ24_interrupt, bad_IRQ25_interrupt, | ||
119 | NULL, NULL, NULL, NULL, NULL, | ||
120 | bad_IRQ31_interrupt | ||
121 | }; | ||
122 | 116 | ||
123 | void arch_setup_irq(int irq) | 117 | static void enable_crisv10_irq(unsigned int irq) |
124 | { | 118 | { |
125 | set_int_vector(irq, interrupt[irq]); | 119 | unmask_irq(irq); |
126 | } | 120 | } |
127 | 121 | ||
128 | void arch_free_irq(int irq) | 122 | static void disable_crisv10_irq(unsigned int irq) |
129 | { | 123 | { |
130 | set_int_vector(irq, bad_interrupt[irq]); | 124 | mask_irq(irq); |
131 | } | 125 | } |
132 | 126 | ||
127 | static void ack_crisv10_irq(unsigned int irq) | ||
128 | { | ||
129 | } | ||
130 | |||
131 | static void end_crisv10_irq(unsigned int irq) | ||
132 | { | ||
133 | } | ||
134 | |||
135 | static struct hw_interrupt_type crisv10_irq_type = { | ||
136 | .typename = "CRISv10", | ||
137 | .startup = startup_crisv10_irq, | ||
138 | .shutdown = shutdown_crisv10_irq, | ||
139 | .enable = enable_crisv10_irq, | ||
140 | .disable = disable_crisv10_irq, | ||
141 | .ack = ack_crisv10_irq, | ||
142 | .end = end_crisv10_irq, | ||
143 | .set_affinity = NULL | ||
144 | }; | ||
145 | |||
133 | void weird_irq(void); | 146 | void weird_irq(void); |
134 | void system_call(void); /* from entry.S */ | 147 | void system_call(void); /* from entry.S */ |
135 | void do_sigtrap(void); /* from entry.S */ | 148 | void do_sigtrap(void); /* from entry.S */ |
136 | void gdb_handle_breakpoint(void); /* from entry.S */ | 149 | void gdb_handle_breakpoint(void); /* from entry.S */ |
137 | 150 | ||
138 | /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and | 151 | /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and |
139 | setting the irq vector table to point to bad_interrupt ptrs. | 152 | setting the irq vector table. |
140 | */ | 153 | */ |
141 | 154 | ||
142 | void __init | 155 | void __init |
@@ -154,14 +167,15 @@ init_IRQ(void) | |||
154 | 167 | ||
155 | *R_VECT_MASK_CLR = 0xffffffff; | 168 | *R_VECT_MASK_CLR = 0xffffffff; |
156 | 169 | ||
157 | /* clear the shortcut entry points */ | ||
158 | |||
159 | for(i = 0; i < NR_IRQS; i++) | ||
160 | irq_shortcuts[i] = NULL; | ||
161 | |||
162 | for (i = 0; i < 256; i++) | 170 | for (i = 0; i < 256; i++) |
163 | etrax_irv->v[i] = weird_irq; | 171 | etrax_irv->v[i] = weird_irq; |
164 | 172 | ||
173 | /* Initialize IRQ handler descriptiors. */ | ||
174 | for(i = 2; i < NR_IRQS; i++) { | ||
175 | irq_desc[i].handler = &crisv10_irq_type; | ||
176 | set_int_vector(i, interrupt[i]); | ||
177 | } | ||
178 | |||
165 | /* the entries in the break vector contain actual code to be | 179 | /* the entries in the break vector contain actual code to be |
166 | executed by the associated break handler, rather than just a jump | 180 | executed by the associated break handler, rather than just a jump |
167 | address. therefore we need to setup a default breakpoint handler | 181 | address. therefore we need to setup a default breakpoint handler |
@@ -170,10 +184,6 @@ init_IRQ(void) | |||
170 | for (i = 0; i < 16; i++) | 184 | for (i = 0; i < 16; i++) |
171 | set_break_vector(i, do_sigtrap); | 185 | set_break_vector(i, do_sigtrap); |
172 | 186 | ||
173 | /* set all etrax irq's to the bad handlers */ | ||
174 | for (i = 2; i < NR_IRQS; i++) | ||
175 | set_int_vector(i, bad_interrupt[i]); | ||
176 | |||
177 | /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */ | 187 | /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */ |
178 | 188 | ||
179 | set_int_vector(15, multiple_interrupt); | 189 | set_int_vector(15, multiple_interrupt); |
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index 7d368c877ee9..b72e6a91a639 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c | |||
@@ -18,6 +18,10 @@ | |||
18 | *! Jul 21 1999 Bjorn Wesen eLinux port | 18 | *! Jul 21 1999 Bjorn Wesen eLinux port |
19 | *! | 19 | *! |
20 | *! $Log: kgdb.c,v $ | 20 | *! $Log: kgdb.c,v $ |
21 | *! Revision 1.6 2005/01/14 10:12:17 starvik | ||
22 | *! KGDB on separate port. | ||
23 | *! Console fixes from 2.4. | ||
24 | *! | ||
21 | *! Revision 1.5 2004/10/07 13:59:08 starvik | 25 | *! Revision 1.5 2004/10/07 13:59:08 starvik |
22 | *! Corrected call to set_int_vector | 26 | *! Corrected call to set_int_vector |
23 | *! | 27 | *! |
@@ -71,7 +75,7 @@ | |||
71 | *! | 75 | *! |
72 | *!--------------------------------------------------------------------------- | 76 | *!--------------------------------------------------------------------------- |
73 | *! | 77 | *! |
74 | *! $Id: kgdb.c,v 1.5 2004/10/07 13:59:08 starvik Exp $ | 78 | *! $Id: kgdb.c,v 1.6 2005/01/14 10:12:17 starvik Exp $ |
75 | *! | 79 | *! |
76 | *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN | 80 | *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN |
77 | *! | 81 | *! |
@@ -225,6 +229,7 @@ | |||
225 | #include <linux/kernel.h> | 229 | #include <linux/kernel.h> |
226 | #include <linux/delay.h> | 230 | #include <linux/delay.h> |
227 | #include <linux/linkage.h> | 231 | #include <linux/linkage.h> |
232 | #include <linux/reboot.h> | ||
228 | 233 | ||
229 | #include <asm/setup.h> | 234 | #include <asm/setup.h> |
230 | #include <asm/ptrace.h> | 235 | #include <asm/ptrace.h> |
@@ -1344,12 +1349,11 @@ handle_exception (int sigval) | |||
1344 | } | 1349 | } |
1345 | } | 1350 | } |
1346 | 1351 | ||
1347 | /* The jump is to the address 0x00000002. Performs a complete re-start | 1352 | /* Performs a complete re-start from scratch. */ |
1348 | from scratch. */ | ||
1349 | static void | 1353 | static void |
1350 | kill_restart () | 1354 | kill_restart () |
1351 | { | 1355 | { |
1352 | __asm__ volatile ("jump 2"); | 1356 | machine_restart(""); |
1353 | } | 1357 | } |
1354 | 1358 | ||
1355 | /********************************** Breakpoint *******************************/ | 1359 | /********************************** Breakpoint *******************************/ |
@@ -1506,6 +1510,11 @@ kgdb_handle_serial: | |||
1506 | bne goback | 1510 | bne goback |
1507 | nop | 1511 | nop |
1508 | 1512 | ||
1513 | move.d [reg+0x5E], $r10 ; Get DCCR | ||
1514 | btstq 8, $r10 ; Test the U-flag. | ||
1515 | bmi goback | ||
1516 | nop | ||
1517 | |||
1509 | ;; | 1518 | ;; |
1510 | ;; Handle the communication | 1519 | ;; Handle the communication |
1511 | ;; | 1520 | ;; |
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 87ff37790827..69e28b4057e8 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: process.c,v 1.9 2004/10/19 13:07:37 starvik Exp $ | 1 | /* $Id: process.c,v 1.12 2004/12/27 11:18:32 starvik Exp $ |
2 | * | 2 | * |
3 | * linux/arch/cris/kernel/process.c | 3 | * linux/arch/cris/kernel/process.c |
4 | * | 4 | * |
@@ -101,6 +101,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
101 | regs.r11 = (unsigned long)fn; | 101 | regs.r11 = (unsigned long)fn; |
102 | regs.r12 = (unsigned long)arg; | 102 | regs.r12 = (unsigned long)arg; |
103 | regs.irp = (unsigned long)kernel_thread_helper; | 103 | regs.irp = (unsigned long)kernel_thread_helper; |
104 | regs.dccr = 1 << I_DCCR_BITNR; | ||
104 | 105 | ||
105 | /* Ok, create the new process.. */ | 106 | /* Ok, create the new process.. */ |
106 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | 107 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); |
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index 581ecabaae53..130dd214e41d 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/ptrace.h> | 11 | #include <linux/ptrace.h> |
12 | #include <linux/user.h> | 12 | #include <linux/user.h> |
13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
14 | #include <linux/security.h> | ||
14 | 15 | ||
15 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
16 | #include <asm/page.h> | 17 | #include <asm/page.h> |
@@ -86,9 +87,13 @@ sys_ptrace(long request, long pid, long addr, long data) | |||
86 | ret = -EPERM; | 87 | ret = -EPERM; |
87 | 88 | ||
88 | if (request == PTRACE_TRACEME) { | 89 | if (request == PTRACE_TRACEME) { |
90 | /* are we already being traced? */ | ||
89 | if (current->ptrace & PT_PTRACED) | 91 | if (current->ptrace & PT_PTRACED) |
90 | goto out; | 92 | goto out; |
91 | 93 | ret = security_ptrace(current->parent, current); | |
94 | if (ret) | ||
95 | goto out; | ||
96 | /* set the ptrace bit in the process flags. */ | ||
92 | current->ptrace |= PT_PTRACED; | 97 | current->ptrace |= PT_PTRACED; |
93 | ret = 0; | 98 | ret = 0; |
94 | goto out; | 99 | goto out; |
@@ -207,7 +212,7 @@ sys_ptrace(long request, long pid, long addr, long data) | |||
207 | case PTRACE_KILL: | 212 | case PTRACE_KILL: |
208 | ret = 0; | 213 | ret = 0; |
209 | 214 | ||
210 | if (child->state == TASK_ZOMBIE) | 215 | if (child->exit_state == EXIT_ZOMBIE) |
211 | break; | 216 | break; |
212 | 217 | ||
213 | child->exit_code = SIGKILL; | 218 | child->exit_code = SIGKILL; |
diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c index 561a890a8e4c..38fd44dfbc5b 100644 --- a/arch/cris/arch-v10/kernel/shadows.c +++ b/arch/cris/arch-v10/kernel/shadows.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: shadows.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | 1 | /* $Id: shadows.c,v 1.2 2004/12/13 12:21:51 starvik Exp $ |
2 | * | 2 | * |
3 | * Various shadow registers. Defines for these are in include/asm-etrax100/io.h | 3 | * Various shadow registers. Defines for these are in include/asm-etrax100/io.h |
4 | */ | 4 | */ |
@@ -6,6 +6,7 @@ | |||
6 | /* Shadows for internal Etrax-registers */ | 6 | /* Shadows for internal Etrax-registers */ |
7 | 7 | ||
8 | unsigned long genconfig_shadow; | 8 | unsigned long genconfig_shadow; |
9 | unsigned long gen_config_ii_shadow; | ||
9 | unsigned long port_g_data_shadow; | 10 | unsigned long port_g_data_shadow; |
10 | unsigned char port_pa_dir_shadow; | 11 | unsigned char port_pa_dir_shadow; |
11 | unsigned char port_pa_data_shadow; | 12 | unsigned char port_pa_data_shadow; |
diff --git a/arch/cris/arch-v10/kernel/traps.c b/arch/cris/arch-v10/kernel/traps.c index da491f438a6e..34a27ea2052d 100644 --- a/arch/cris/arch-v10/kernel/traps.c +++ b/arch/cris/arch-v10/kernel/traps.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: traps.c,v 1.2 2003/07/04 08:27:41 starvik Exp $ | 1 | /* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $ |
2 | * | 2 | * |
3 | * linux/arch/cris/arch-v10/traps.c | 3 | * linux/arch/cris/arch-v10/traps.c |
4 | * | 4 | * |
@@ -16,6 +16,8 @@ | |||
16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
17 | #include <asm/arch/sv_addr_ag.h> | 17 | #include <asm/arch/sv_addr_ag.h> |
18 | 18 | ||
19 | extern int raw_printk(const char *fmt, ...); | ||
20 | |||
19 | void | 21 | void |
20 | show_registers(struct pt_regs * regs) | 22 | show_registers(struct pt_regs * regs) |
21 | { | 23 | { |
@@ -26,18 +28,18 @@ show_registers(struct pt_regs * regs) | |||
26 | register. */ | 28 | register. */ |
27 | unsigned long usp = rdusp(); | 29 | unsigned long usp = rdusp(); |
28 | 30 | ||
29 | printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", | 31 | raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", |
30 | regs->irp, regs->srp, regs->dccr, usp, regs->mof ); | 32 | regs->irp, regs->srp, regs->dccr, usp, regs->mof ); |
31 | printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | 33 | raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", |
32 | regs->r0, regs->r1, regs->r2, regs->r3); | 34 | regs->r0, regs->r1, regs->r2, regs->r3); |
33 | printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | 35 | raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", |
34 | regs->r4, regs->r5, regs->r6, regs->r7); | 36 | regs->r4, regs->r5, regs->r6, regs->r7); |
35 | printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | 37 | raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", |
36 | regs->r8, regs->r9, regs->r10, regs->r11); | 38 | regs->r8, regs->r9, regs->r10, regs->r11); |
37 | printk("r12: %08lx r13: %08lx oR10: %08lx\n", | 39 | raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", |
38 | regs->r12, regs->r13, regs->orig_r10); | 40 | regs->r12, regs->r13, regs->orig_r10, regs); |
39 | printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); | 41 | raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); |
40 | printk("Process %s (pid: %d, stackpage=%08lx)\n", | 42 | raw_printk("Process %s (pid: %d, stackpage=%08lx)\n", |
41 | current->comm, current->pid, (unsigned long)current); | 43 | current->comm, current->pid, (unsigned long)current); |
42 | 44 | ||
43 | /* | 45 | /* |
@@ -53,7 +55,7 @@ show_registers(struct pt_regs * regs) | |||
53 | if (usp != 0) | 55 | if (usp != 0) |
54 | show_stack (NULL, NULL); | 56 | show_stack (NULL, NULL); |
55 | 57 | ||
56 | printk("\nCode: "); | 58 | raw_printk("\nCode: "); |
57 | if(regs->irp < PAGE_OFFSET) | 59 | if(regs->irp < PAGE_OFFSET) |
58 | goto bad; | 60 | goto bad; |
59 | 61 | ||
@@ -70,16 +72,16 @@ show_registers(struct pt_regs * regs) | |||
70 | unsigned char c; | 72 | unsigned char c; |
71 | if(__get_user(c, &((unsigned char*)regs->irp)[i])) { | 73 | if(__get_user(c, &((unsigned char*)regs->irp)[i])) { |
72 | bad: | 74 | bad: |
73 | printk(" Bad IP value."); | 75 | raw_printk(" Bad IP value."); |
74 | break; | 76 | break; |
75 | } | 77 | } |
76 | 78 | ||
77 | if (i == 0) | 79 | if (i == 0) |
78 | printk("(%02x) ", c); | 80 | raw_printk("(%02x) ", c); |
79 | else | 81 | else |
80 | printk("%02x ", c); | 82 | raw_printk("%02x ", c); |
81 | } | 83 | } |
82 | printk("\n"); | 84 | raw_printk("\n"); |
83 | } | 85 | } |
84 | } | 86 | } |
85 | 87 | ||
@@ -121,7 +123,7 @@ die_if_kernel(const char * str, struct pt_regs * regs, long err) | |||
121 | stop_watchdog(); | 123 | stop_watchdog(); |
122 | #endif | 124 | #endif |
123 | 125 | ||
124 | printk("%s: %04lx\n", str, err & 0xffff); | 126 | raw_printk("%s: %04lx\n", str, err & 0xffff); |
125 | 127 | ||
126 | show_registers(regs); | 128 | show_registers(regs); |
127 | 129 | ||
@@ -130,3 +132,8 @@ die_if_kernel(const char * str, struct pt_regs * regs, long err) | |||
130 | #endif | 132 | #endif |
131 | do_exit(SIGSEGV); | 133 | do_exit(SIGSEGV); |
132 | } | 134 | } |
135 | |||
136 | void arch_enable_nmi(void) | ||
137 | { | ||
138 | asm volatile("setf m"); | ||
139 | } | ||
diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c index 6805cdb25a53..fe2615022b97 100644 --- a/arch/cris/arch-v10/mm/fault.c +++ b/arch/cris/arch-v10/mm/fault.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/arch/svinto.h> | 16 | #include <asm/arch/svinto.h> |
17 | #include <asm/mmu_context.h> | ||
17 | 18 | ||
18 | /* debug of low-level TLB reload */ | 19 | /* debug of low-level TLB reload */ |
19 | #undef DEBUG | 20 | #undef DEBUG |
@@ -24,8 +25,6 @@ | |||
24 | #define D(x) | 25 | #define D(x) |
25 | #endif | 26 | #endif |
26 | 27 | ||
27 | extern volatile pgd_t *current_pgd; | ||
28 | |||
29 | extern const struct exception_table_entry | 28 | extern const struct exception_table_entry |
30 | *search_exception_tables(unsigned long addr); | 29 | *search_exception_tables(unsigned long addr); |
31 | 30 | ||
@@ -46,7 +45,7 @@ handle_mmu_bus_fault(struct pt_regs *regs) | |||
46 | int page_id; | 45 | int page_id; |
47 | int acc, inv; | 46 | int acc, inv; |
48 | #endif | 47 | #endif |
49 | pgd_t* pgd = (pgd_t*)current_pgd; | 48 | pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id()); |
50 | pmd_t *pmd; | 49 | pmd_t *pmd; |
51 | pte_t pte; | 50 | pte_t pte; |
52 | int miss, we, writeac; | 51 | int miss, we, writeac; |
@@ -94,24 +93,3 @@ handle_mmu_bus_fault(struct pt_regs *regs) | |||
94 | *R_TLB_LO = pte_val(pte); | 93 | *R_TLB_LO = pte_val(pte); |
95 | local_irq_restore(flags); | 94 | local_irq_restore(flags); |
96 | } | 95 | } |
97 | |||
98 | /* Called from arch/cris/mm/fault.c to find fixup code. */ | ||
99 | int | ||
100 | find_fixup_code(struct pt_regs *regs) | ||
101 | { | ||
102 | const struct exception_table_entry *fixup; | ||
103 | |||
104 | if ((fixup = search_exception_tables(regs->irp)) != 0) { | ||
105 | /* Adjust the instruction pointer in the stackframe. */ | ||
106 | regs->irp = fixup->fixup; | ||
107 | |||
108 | /* | ||
109 | * Don't return by restoring the CPU state, so switch | ||
110 | * frame-type. | ||
111 | */ | ||
112 | regs->frametype = CRIS_FRAME_NORMAL; | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c index a9f975a9cfb5..ff3481e76dd4 100644 --- a/arch/cris/arch-v10/mm/init.c +++ b/arch/cris/arch-v10/mm/init.c | |||
@@ -42,7 +42,7 @@ paging_init(void) | |||
42 | * switch_mm) | 42 | * switch_mm) |
43 | */ | 43 | */ |
44 | 44 | ||
45 | current_pgd = init_mm.pgd; | 45 | per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd; |
46 | 46 | ||
47 | /* initialise the TLB (tlb.c) */ | 47 | /* initialise the TLB (tlb.c) */ |
48 | 48 | ||
diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c index 9d06125ff5a2..70a5523eff78 100644 --- a/arch/cris/arch-v10/mm/tlb.c +++ b/arch/cris/arch-v10/mm/tlb.c | |||
@@ -139,53 +139,6 @@ flush_tlb_page(struct vm_area_struct *vma, | |||
139 | local_irq_restore(flags); | 139 | local_irq_restore(flags); |
140 | } | 140 | } |
141 | 141 | ||
142 | /* invalidate a page range */ | ||
143 | |||
144 | void | ||
145 | flush_tlb_range(struct vm_area_struct *vma, | ||
146 | unsigned long start, | ||
147 | unsigned long end) | ||
148 | { | ||
149 | struct mm_struct *mm = vma->vm_mm; | ||
150 | int page_id = mm->context.page_id; | ||
151 | int i; | ||
152 | unsigned long flags; | ||
153 | |||
154 | D(printk("tlb: flush range %p<->%p in context %d (%p)\n", | ||
155 | start, end, page_id, mm)); | ||
156 | |||
157 | if(page_id == NO_CONTEXT) | ||
158 | return; | ||
159 | |||
160 | start &= PAGE_MASK; /* probably not necessary */ | ||
161 | end &= PAGE_MASK; /* dito */ | ||
162 | |||
163 | /* invalidate those TLB entries that match both the mm context | ||
164 | * and the virtual address range | ||
165 | */ | ||
166 | |||
167 | local_save_flags(flags); | ||
168 | local_irq_disable(); | ||
169 | for(i = 0; i < NUM_TLB_ENTRIES; i++) { | ||
170 | unsigned long tlb_hi, vpn; | ||
171 | *R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i); | ||
172 | tlb_hi = *R_TLB_HI; | ||
173 | vpn = tlb_hi & PAGE_MASK; | ||
174 | if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id && | ||
175 | vpn >= start && vpn < end) { | ||
176 | *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | | ||
177 | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); | ||
178 | |||
179 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | | ||
180 | IO_STATE(R_TLB_LO, valid, no ) | | ||
181 | IO_STATE(R_TLB_LO, kernel,no ) | | ||
182 | IO_STATE(R_TLB_LO, we, no ) | | ||
183 | IO_FIELD(R_TLB_LO, pfn, 0 ) ); | ||
184 | } | ||
185 | } | ||
186 | local_irq_restore(flags); | ||
187 | } | ||
188 | |||
189 | /* dump the entire TLB for debug purposes */ | 142 | /* dump the entire TLB for debug purposes */ |
190 | 143 | ||
191 | #if 0 | 144 | #if 0 |
@@ -237,7 +190,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
237 | * the pgd. | 190 | * the pgd. |
238 | */ | 191 | */ |
239 | 192 | ||
240 | current_pgd = next->pgd; | 193 | per_cpu(current_pgd, smp_processor_id()) = next->pgd; |
241 | 194 | ||
242 | /* switch context in the MMU */ | 195 | /* switch context in the MMU */ |
243 | 196 | ||