aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32')
-rw-r--r--arch/cris/arch-v32/Kconfig127
-rw-r--r--arch/cris/arch-v32/boot/Makefile23
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile45
-rw-r--r--arch/cris/arch-v32/boot/compressed/README1
-rw-r--r--arch/cris/arch-v32/boot/compressed/head.S137
-rw-r--r--arch/cris/arch-v32/boot/compressed/misc.c72
-rw-r--r--arch/cris/arch-v32/boot/rescue/Makefile41
-rw-r--r--arch/cris/arch-v32/boot/rescue/head.S42
-rw-r--r--arch/cris/arch-v32/boot/rescue/rescue.ld37
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig711
-rw-r--r--arch/cris/arch-v32/drivers/Makefile5
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c488
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c104
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c206
-rw-r--r--arch/cris/arch-v32/drivers/i2c.h2
-rw-r--r--arch/cris/arch-v32/drivers/iop_fw_load.c16
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/Makefile6
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/gpio.c984
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/nandflash.c180
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/Makefile6
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c (renamed from arch/cris/arch-v32/drivers/gpio.c)612
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/nandflash.c (renamed from arch/cris/arch-v32/drivers/nandflash.c)122
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c296
-rw-r--r--arch/cris/arch-v32/drivers/sync_serial.c938
-rw-r--r--arch/cris/arch-v32/kernel/Makefile5
-rw-r--r--arch/cris/arch-v32/kernel/arbiter.c296
-rw-r--r--arch/cris/arch-v32/kernel/crisksyms.c7
-rw-r--r--arch/cris/arch-v32/kernel/debugport.c342
-rw-r--r--arch/cris/arch-v32/kernel/entry.S83
-rw-r--r--arch/cris/arch-v32/kernel/fasttimer.c535
-rw-r--r--arch/cris/arch-v32/kernel/head.S204
-rw-r--r--arch/cris/arch-v32/kernel/io.c153
-rw-r--r--arch/cris/arch-v32/kernel/irq.c274
-rw-r--r--arch/cris/arch-v32/kernel/kgdb.c12
-rw-r--r--arch/cris/arch-v32/kernel/process.c14
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c10
-rw-r--r--arch/cris/arch-v32/kernel/signal.c144
-rw-r--r--arch/cris/arch-v32/kernel/smp.c31
-rw-r--r--arch/cris/arch-v32/kernel/time.c237
-rw-r--r--arch/cris/arch-v32/kernel/traps.c192
-rw-r--r--arch/cris/arch-v32/kernel/vcs_hook.c96
-rw-r--r--arch/cris/arch-v32/lib/Makefile3
-rw-r--r--arch/cris/arch-v32/lib/checksum.S72
-rw-r--r--arch/cris/arch-v32/lib/checksumcopy.S69
-rw-r--r--arch/cris/arch-v32/lib/delay.c28
-rw-r--r--arch/cris/arch-v32/lib/spinlock.S10
-rw-r--r--arch/cris/arch-v32/mach-a3/Kconfig110
-rw-r--r--arch/cris/arch-v32/mach-a3/Makefile11
-rw-r--r--arch/cris/arch-v32/mach-a3/arbiter.c634
-rw-r--r--arch/cris/arch-v32/mach-a3/cpufreq.c153
-rw-r--r--arch/cris/arch-v32/mach-a3/dma.c185
-rw-r--r--arch/cris/arch-v32/mach-a3/dram_init.S104
-rw-r--r--arch/cris/arch-v32/mach-a3/hw_settings.S51
-rw-r--r--arch/cris/arch-v32/mach-a3/io.c149
-rw-r--r--arch/cris/arch-v32/mach-a3/pinmux.c386
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.c103
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.h58
-rw-r--r--arch/cris/arch-v32/mach-fs/Kconfig216
-rw-r--r--arch/cris/arch-v32/mach-fs/Makefile11
-rw-r--r--arch/cris/arch-v32/mach-fs/arbiter.c404
-rw-r--r--arch/cris/arch-v32/mach-fs/cpufreq.c146
-rw-r--r--arch/cris/arch-v32/mach-fs/dma.c (renamed from arch/cris/arch-v32/kernel/dma.c)46
-rw-r--r--arch/cris/arch-v32/mach-fs/dram_init.S (renamed from arch/cris/arch-v32/lib/dram_init.S)23
-rw-r--r--arch/cris/arch-v32/mach-fs/hw_settings.S (renamed from arch/cris/arch-v32/lib/hw_settings.S)12
-rw-r--r--arch/cris/arch-v32/mach-fs/io.c191
-rw-r--r--arch/cris/arch-v32/mach-fs/pinmux.c309
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.c100
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.h (renamed from arch/cris/arch-v32/kernel/vcs_hook.h)8
-rw-r--r--arch/cris/arch-v32/mm/Makefile3
-rw-r--r--arch/cris/arch-v32/mm/init.c8
-rw-r--r--arch/cris/arch-v32/mm/intmem.c48
-rw-r--r--arch/cris/arch-v32/mm/l2cache.c29
-rw-r--r--arch/cris/arch-v32/mm/mmu.S93
-rw-r--r--arch/cris/arch-v32/mm/tlb.c56
-rw-r--r--arch/cris/arch-v32/vmlinux.lds.S74
75 files changed, 8348 insertions, 3391 deletions
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index d8acaa920e1c..005ed2b3f7f4 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -1,27 +1,73 @@
1if ETRAX_ARCH_V32 1if ETRAX_ARCH_V32
2 2
3source arch/cris/arch-v32/mach-fs/Kconfig
4source arch/cris/arch-v32/mach-a3/Kconfig
5
6source drivers/cpufreq/Kconfig
7
3config ETRAX_DRAM_VIRTUAL_BASE 8config ETRAX_DRAM_VIRTUAL_BASE
4 hex 9 hex
5 depends on ETRAX_ARCH_V32 10 depends on ETRAX_ARCH_V32
6 default "c0000000" 11 default "c0000000"
7 12
8config ETRAX_LED1G 13choice
9 string "First green LED bit" 14 prompt "Nbr of Ethernet LED groups"
10 depends on ETRAX_ARCH_V32 15 depends on ETRAX_ARCH_V32
16 default ETRAX_NBR_LED_GRP_ONE
17 help
18 Select how many Ethernet LED groups that can be used. Usually one per Ethernet
19 interface is a good choice.
20
21config ETRAX_NBR_LED_GRP_ZERO
22 bool "Use zero LED groups"
23 help
24 Select this if you do not want any Ethernet LEDs.
25
26config ETRAX_NBR_LED_GRP_ONE
27 bool "Use one LED group"
28 help
29 Select this if you want one Ethernet LED group. This LED group
30 can be used for one or more Ethernet interfaces. However, it is
31 recomended that each Ethernet interface use a dedicated LED group.
32
33config ETRAX_NBR_LED_GRP_TWO
34 bool "Use two LED groups"
35 help
36 Select this if you want two Ethernet LED groups. This is the
37 best choice if you have more than one Ethernet interface and
38 would like to have separate LEDs for the interfaces.
39
40endchoice
41
42config ETRAX_LED_G_NET0
43 string "Ethernet LED group 0 green LED bit"
44 depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
11 default "PA3" 45 default "PA3"
12 help 46 help
13 Bit to use for the first green LED (network LED). 47 Bit to use for the green LED in Ethernet LED group 0.
14 Most Axis products use bit A3 here.
15 48
16config ETRAX_LED1R 49config ETRAX_LED_R_NET0
17 string "First red LED bit" 50 string "Ethernet LED group 0 red LED bit"
18 depends on ETRAX_ARCH_V32 51 depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
19 default "PA4" 52 default "PA4"
20 help 53 help
21 Bit to use for the first red LED (network LED). 54 Bit to use for the red LED in Ethernet LED group 0.
22 Most Axis products use bit A4 here.
23 55
24config ETRAX_LED2G 56config ETRAX_LED_G_NET1
57 string "Ethernet group 1 green LED bit"
58 depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
59 default ""
60 help
61 Bit to use for the green LED in Ethernet LED group 1.
62
63config ETRAX_LED_R_NET1
64 string "Ethernet group 1 red LED bit"
65 depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
66 default ""
67 help
68 Bit to use for the red LED in Ethernet LED group 1.
69
70config ETRAX_V32_LED2G
25 string "Second green LED bit" 71 string "Second green LED bit"
26 depends on ETRAX_ARCH_V32 72 depends on ETRAX_ARCH_V32
27 default "PA5" 73 default "PA5"
@@ -29,7 +75,7 @@ config ETRAX_LED2G
29 Bit to use for the first green LED (status LED). 75 Bit to use for the first green LED (status LED).
30 Most Axis products use bit A5 here. 76 Most Axis products use bit A5 here.
31 77
32config ETRAX_LED2R 78config ETRAX_V32_LED2R
33 string "Second red LED bit" 79 string "Second red LED bit"
34 depends on ETRAX_ARCH_V32 80 depends on ETRAX_ARCH_V32
35 default "PA6" 81 default "PA6"
@@ -37,7 +83,7 @@ config ETRAX_LED2R
37 Bit to use for the first red LED (network LED). 83 Bit to use for the first red LED (network LED).
38 Most Axis products use bit A6 here. 84 Most Axis products use bit A6 here.
39 85
40config ETRAX_LED3G 86config ETRAX_V32_LED3G
41 string "Third green LED bit" 87 string "Third green LED bit"
42 depends on ETRAX_ARCH_V32 88 depends on ETRAX_ARCH_V32
43 default "PA7" 89 default "PA7"
@@ -45,7 +91,7 @@ config ETRAX_LED3G
45 Bit to use for the first green LED (drive/power LED). 91 Bit to use for the first green LED (drive/power LED).
46 Most Axis products use bit A7 here. 92 Most Axis products use bit A7 here.
47 93
48config ETRAX_LED3R 94config ETRAX_V32_LED3R
49 string "Third red LED bit" 95 string "Third red LED bit"
50 depends on ETRAX_ARCH_V32 96 depends on ETRAX_ARCH_V32
51 default "PA7" 97 default "PA7"
@@ -54,39 +100,6 @@ config ETRAX_LED3R
54 Most Axis products use bit A7 here. 100 Most Axis products use bit A7 here.
55 101
56choice 102choice
57 prompt "Product debug-port"
58 depends on ETRAX_ARCH_V32
59 default ETRAX_DEBUG_PORT0
60
61config ETRAX_DEBUG_PORT0
62 bool "Serial-0"
63 help
64 Choose a serial port for the ETRAX debug console. Default to
65 port 0.
66
67config ETRAX_DEBUG_PORT1
68 bool "Serial-1"
69 help
70 Use serial port 1 for the console.
71
72config ETRAX_DEBUG_PORT2
73 bool "Serial-2"
74 help
75 Use serial port 2 for the console.
76
77config ETRAX_DEBUG_PORT3
78 bool "Serial-3"
79 help
80 Use serial port 3 for the console.
81
82config ETRAX_DEBUG_PORT_NULL
83 bool "disabled"
84 help
85 Disable serial-port debugging.
86
87endchoice
88
89choice
90 prompt "Kernel GDB port" 103 prompt "Kernel GDB port"
91 depends on ETRAX_KGDB 104 depends on ETRAX_KGDB
92 default ETRAX_KGDB_PORT0 105 default ETRAX_KGDB_PORT0
@@ -95,25 +108,11 @@ choice
95 not be enabled under Drivers for built-in interfaces (as it has its 108 not be enabled under Drivers for built-in interfaces (as it has its
96 own initialization code) and should not be the same as the debug port. 109 own initialization code) and should not be the same as the debug port.
97 110
98config ETRAX_KGDB_PORT0 111config ETRAX_KGDB_PORT4
99 bool "Serial-0" 112 bool "Serial-4"
100 help 113 depends on ETRAX_SERIAL_PORTS = 5
101 Use serial port 0 for kernel debugging.
102
103config ETRAX_KGDB_PORT1
104 bool "Serial-1"
105 help
106 Use serial port 1 for kernel debugging.
107
108config ETRAX_KGDB_PORT2
109 bool "Serial-2"
110 help
111 Use serial port 2 for kernel debugging.
112
113config ETRAX_KGDB_PORT3
114 bool "Serial-3"
115 help 114 help
116 Use serial port 3 for kernel debugging. 115 Use serial port 4 for kernel debugging.
117 116
118endchoice 117endchoice
119 118
diff --git a/arch/cris/arch-v32/boot/Makefile b/arch/cris/arch-v32/boot/Makefile
index 26f293ab9617..3f91349c5f12 100644
--- a/arch/cris/arch-v32/boot/Makefile
+++ b/arch/cris/arch-v32/boot/Makefile
@@ -1,14 +1,21 @@
1# 1#
2# arch/cris/arch-v32/boot/Makefile 2# arch/cris/arch-v32/boot/Makefile
3# 3#
4target = $(target_boot_dir)
5src = $(src_boot_dir)
6 4
7zImage: compressed/vmlinuz 5OBJCOPY = objcopy-cris
6OBJCOPYFLAGS = -O binary -R .note -R .comment
8 7
9compressed/vmlinuz: $(objtree)/vmlinux 8subdir- := compressed rescue
10 @$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz 9targets := Image
11 10
12clean: 11$(obj)/Image: vmlinux FORCE
13 rm -f zImage tools/build compressed/vmlinux.out 12 $(call if_changed,objcopy)
14 @$(MAKE) -f $(src)/compressed/Makefile clean 13 @echo ' Kernel: $@ is ready'
14
15$(obj)/compressed/vmlinux: $(obj)/Image FORCE
16 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
17 $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
18
19$(obj)/zImage: $(obj)/compressed/vmlinux
20 @cp $< $@
21 @echo ' Kernel: $@ is ready'
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 609692f9d5eb..2c8c2c3039c5 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -1,41 +1,30 @@
1# 1#
2# lx25/arch/cris/arch-v32/boot/compressed/Makefile 2# arch/cris/arch-v32/boot/compressed/Makefile
3# 3#
4# create a compressed vmlinux image from the original vmlinux files and romfs
5#
6
7target = $(target_compressed_dir)
8src = $(src_compressed_dir)
9 4
10CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) 5CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
11CFLAGS = -O2 6asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
7ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
12LD = gcc-cris -mlinux -march=v32 -nostdlib 8LD = gcc-cris -mlinux -march=v32 -nostdlib
9ldflags-y += -T $(obj)/decompress.ld
10obj-y = head.o misc.o
11OBJECTS = $(obj)/head.o $(obj)/misc.o
13OBJCOPY = objcopy-cris 12OBJCOPY = objcopy-cris
14OBJCOPYFLAGS = -O binary --remove-section=.bss 13OBJCOPYFLAGS = -O binary --remove-section=.bss
15OBJECTS = $(target)/head.o $(target)/misc.o
16
17# files to compress
18SYSTEM = $(objtree)/vmlinux.bin
19
20all: vmlinuz
21
22$(target)/decompress.bin: $(OBJECTS)
23 $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
24 $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
25 14
26$(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin 15quiet_cmd_image = BUILD $@
27 cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz 16cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
28 rm -f piggy.img
29 cp $(objtree)/vmlinuz $(src)
30 17
31$(target)/head.o: $(src)/head.S 18targets := vmlinux piggy.gz decompress.o decompress.bin
32 $(CC) -D__ASSEMBLY__ -c $< -o $@
33 19
34# gzip the kernel image 20$(obj)/decompress.o: $(OBJECTS) FORCE
21 $(call if_changed,ld)
35 22
36piggy.img: $(SYSTEM) 23$(obj)/decompress.bin: $(obj)/decompress.o FORCE
37 cat $(SYSTEM) | gzip -f -9 > piggy.img 24 $(call if_changed,objcopy)
38 25
39clean: 26$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
40 rm -f piggy.img $(objtree)/vmlinuz vmlinuz.o decompress.o decompress.bin $(OBJECTS) 27 $(call if_changed,image)
41 28
29$(obj)/piggy.gz: $(obj)/../Image FORCE
30 $(call if_changed,gzip)
diff --git a/arch/cris/arch-v32/boot/compressed/README b/arch/cris/arch-v32/boot/compressed/README
index e33691d15c57..182c5d75784b 100644
--- a/arch/cris/arch-v32/boot/compressed/README
+++ b/arch/cris/arch-v32/boot/compressed/README
@@ -1,6 +1,5 @@
1Creation of the self-extracting compressed kernel image (vmlinuz) 1Creation of the self-extracting compressed kernel image (vmlinuz)
2----------------------------------------------------------------- 2-----------------------------------------------------------------
3$Id: README,v 1.1 2003/08/21 09:37:03 johana Exp $
4 3
5This can be slightly confusing because it's a process with many steps. 4This can be slightly confusing because it's a process with many steps.
6 5
diff --git a/arch/cris/arch-v32/boot/compressed/head.S b/arch/cris/arch-v32/boot/compressed/head.S
index 34cea10a8998..f86208caf32d 100644
--- a/arch/cris/arch-v32/boot/compressed/head.S
+++ b/arch/cris/arch-v32/boot/compressed/head.S
@@ -2,13 +2,12 @@
2 * Code that sets up the DRAM registers, calls the 2 * Code that sets up the DRAM registers, calls the
3 * decompressor to unpack the piggybacked kernel, and jumps. 3 * decompressor to unpack the piggybacked kernel, and jumps.
4 * 4 *
5 * Copyright (C) 1999 - 2003, Axis Communications AB 5 * Copyright (C) 1999 - 2006, Axis Communications AB
6 */ 6 */
7 7
8#define ASSEMBLER_MACROS_ONLY 8#define ASSEMBLER_MACROS_ONLY
9#include <asm/arch/hwregs/asm/reg_map_asm.h> 9#include <hwregs/asm/reg_map_asm.h>
10#include <asm/arch/hwregs/asm/gio_defs_asm.h> 10#include <asm/arch/mach/startup.inc>
11#include <asm/arch/hwregs/asm/config_defs_asm.h>
12 11
13#define RAM_INIT_MAGIC 0x56902387 12#define RAM_INIT_MAGIC 0x56902387
14#define COMMAND_LINE_MAGIC 0x87109563 13#define COMMAND_LINE_MAGIC 0x87109563
@@ -22,114 +21,49 @@ start:
22 di 21 di
23 22
24 ;; Start clocks for used blocks. 23 ;; Start clocks for used blocks.
25 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 24 START_CLOCKS
26 move.d [$r1], $r0 25
27 or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ 26 ;; Initialize the DRAM registers.
28 REG_STATE(config, rw_clk_ctrl, bif, yes) | \
29 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
30 move.d $r0, [$r1]
31
32 ;; If booting from NAND flash we first have to copy some
33 ;; data from NAND flash to internal RAM to get the code
34 ;; that initializes the SDRAM. Lets copy 20 KB. This
35 ;; code executes at 0x38010000 if booting from NAND and
36 ;; we are guaranted that at least 0x200 bytes are good so
37 ;; lets start from there. The first 8192 bytes in the nand
38 ;; flash is spliced with zeroes and is thus 16384 bytes.
39 move.d 0x38010200, $r10
40 move.d 0x14200, $r11 ; Start offset in NAND flash 0x10200 + 16384
41 move.d 0x5000, $r12 ; Length of copy
42
43 ;; Before this code the tools add a partitiontable so the PC
44 ;; has an offset from the linked address.
45offset1:
46 lapcq ., $r13 ; get PC
47 add.d first_copy_complete-offset1, $r13
48
49#include "../../lib/nand_init.S"
50
51first_copy_complete:
52 ;; Initialze the DRAM registers.
53 cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? 27 cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
54 beq dram_init_finished 28 beq dram_init_finished
55 nop 29 nop
56 30
57#include "../../lib/dram_init.S" 31#include "../../mach/dram_init.S"
58 32
59dram_init_finished: 33dram_init_finished:
60 lapcq ., $r13 ; get PC
61 add.d second_copy_complete-dram_init_finished, $r13
62
63 move.d REG_ADDR(config, regi_config, r_bootsel), $r0
64 move.d [$r0], $r0
65 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
66 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
67 bne second_copy_complete ; No NAND boot
68 nop
69
70 ;; Copy 2MB from NAND flash to SDRAM (at 2-4MB into the SDRAM)
71 move.d 0x40204000, $r10
72 move.d 0x8000, $r11
73 move.d 0x200000, $r12
74 ba copy_nand_to_ram
75 nop
76second_copy_complete:
77
78 ;; Initiate the PA port.
79 move.d CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
80 move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
81 move.d $r0, [$r1]
82
83 move.d CONFIG_ETRAX_DEF_GIO_PA_OE, $r0
84 move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r1
85 move.d $r0, [$r1]
86 34
35 GIO_INIT
87 ;; Setup the stack to a suitably high address. 36 ;; Setup the stack to a suitably high address.
88 ;; We assume 8 MB is the minimum DRAM and put 37 ;; We assume 8 MB is the minimum DRAM and put
89 ;; the SP at the top for now. 38 ;; the SP at the top for now.
90 39
91 move.d 0x40800000, $sp 40 move.d 0x40800000, $sp
92 41
93 ;; Figure out where the compressed piggyback image is 42 ;; Figure out where the compressed piggyback image is.
94 ;; in the flash (since we wont try to copy it to DRAM 43 ;; It is either in [NOR] flash (we don't want to copy it
95 ;; before unpacking). It is at _edata, but in flash. 44 ;; to DRAM before unpacking), or copied to DRAM
45 ;; by the [NAND] flash boot loader.
46 ;; The piggyback image is at _edata, but relative to where the
47 ;; image is actually located in memory, not where it is linked
48 ;; (the decompressor is linked at 0x40700000+ and runs there).
96 ;; Use (_edata - herami) as offset to the current PC. 49 ;; Use (_edata - herami) as offset to the current PC.
97 50
98 move.d REG_ADDR(config, regi_config, r_bootsel), $r0
99 move.d [$r0], $r0
100 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
101 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
102 beq hereami2
103 nop
104hereami: 51hereami:
105 lapcq ., $r5 ; get PC 52 lapcq ., $r5 ; get PC
106 and.d 0x7fffffff, $r5 ; strip any non-cache bit 53 and.d 0x7fffffff, $r5 ; strip any non-cache bit
107 move.d $r5, $r0 ; save for later - flash address of 'herami' 54 move.d $r5, $r0 ; source address of 'herami'
108 add.d _edata, $r5 55 add.d _edata, $r5
109 sub.d hereami, $r5 ; r5 = flash address of '_edata' 56 sub.d hereami, $r5 ; r5 = flash address of '_edata'
110 move.d hereami, $r1 ; destination 57 move.d hereami, $r1 ; destination
111 ba 2f 58
112 nop
113hereami2:
114 lapcq ., $r5 ; get PC
115 and.d 0x00ffffff, $r5 ; strip any non-cache bit
116 move.d $r5, $r6
117 or.d 0x40200000, $r6
118 move.d $r6, $r0 ; save for later - flash address of 'herami'
119 add.d _edata, $r5
120 sub.d hereami2, $r5 ; r5 = flash address of '_edata'
121 add.d 0x40200000, $r5
122 move.d hereami2, $r1 ; destination
1232:
124 ;; Copy text+data to DRAM 59 ;; Copy text+data to DRAM
125 60
126 move.d _edata, $r2 ; end destination 61 move.d _edata, $r2 ; end destination
1271: move.w [$r0+], $r3 621: move.w [$r0+], $r3 ; from herami+ source
128 move.w $r3, [$r1+] 63 move.w $r3, [$r1+] ; to hereami+ destination (linked address)
129 cmp.d $r2, $r1 64 cmp.d $r2, $r1 ; finish when destination == _edata
130 bcs 1b 65 bcs 1b
131 nop 66 nop
132
133 move.d input_data, $r0 ; for the decompressor 67 move.d input_data, $r0 ; for the decompressor
134 move.d $r5, [$r0] ; for the decompressor 68 move.d $r5, [$r0] ; for the decompressor
135 69
@@ -144,16 +78,24 @@ hereami2:
144 nop 78 nop
145 79
146 ;; Save command line magic and address. 80 ;; Save command line magic and address.
147 move.d _cmd_line_magic, $r12 81 move.d _cmd_line_magic, $r0
148 move.d $r10, [$r12] 82 move.d $r10, [$r0]
149 move.d _cmd_line_addr, $r12 83 move.d _cmd_line_addr, $r0
150 move.d $r11, [$r12] 84 move.d $r11, [$r0]
85
86 ;; Save boot source indicator
87 move.d _boot_source, $r0
88 move.d $r12, [$r0]
151 89
152 ;; Do the decompression and save compressed size in _inptr 90 ;; Do the decompression and save compressed size in _inptr
153 91
154 jsr decompress_kernel 92 jsr decompress_kernel
155 nop 93 nop
156 94
95 ;; Restore boot source indicator
96 move.d _boot_source, $r12
97 move.d [$r12], $r12
98
157 ;; Restore command line magic and address. 99 ;; Restore command line magic and address.
158 move.d _cmd_line_magic, $r10 100 move.d _cmd_line_magic, $r10
159 move.d [$r10], $r10 101 move.d [$r10], $r10
@@ -166,11 +108,10 @@ hereami2:
166 move.d [$r0], $r9 ; flash address of compressed kernel 108 move.d [$r0], $r9 ; flash address of compressed kernel
167 move.d inptr, $r0 109 move.d inptr, $r0
168 add.d [$r0], $r9 ; size of compressed kernel 110 add.d [$r0], $r9 ; size of compressed kernel
169 cmp.d 0x40200000, $r9 111 cmp.d 0x40000000, $r9 ; image in DRAM ?
170 blo enter_kernel 112 blo enter_kernel ; no, must be [NOR] flash, jump
171 nop 113 nop ; delay slot
172 sub.d 0x40200000, $r9 114 and.d 0x001fffff, $r9 ; assume compressed kernel was < 2M
173 add.d 0x4000, $r9
174 115
175enter_kernel: 116enter_kernel:
176 ;; Enter the decompressed kernel 117 ;; Enter the decompressed kernel
@@ -186,7 +127,7 @@ _cmd_line_magic:
186 .dword 0 127 .dword 0
187_cmd_line_addr: 128_cmd_line_addr:
188 .dword 0 129 .dword 0
189is_nand_boot: 130_boot_source:
190 .dword 0 131 .dword 0
191 132
192#include "../../lib/hw_settings.S" 133#include "../../mach/hw_settings.S"
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/arch-v32/boot/compressed/misc.c
index 0169ba1ca9c9..55b2695c5d70 100644
--- a/arch/cris/arch-v32/boot/compressed/misc.c
+++ b/arch/cris/arch-v32/boot/compressed/misc.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * misc.c 2 * misc.c
3 * 3 *
4 * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $
5 *
6 * This is a collection of several routines from gzip-1.0.3 4 * This is a collection of several routines from gzip-1.0.3
7 * adapted for Linux. 5 * adapted for Linux.
8 * 6 *
@@ -22,9 +20,13 @@
22 20
23 21
24#include <linux/types.h> 22#include <linux/types.h>
25#include <asm/arch/hwregs/reg_rdwr.h> 23#include <hwregs/reg_rdwr.h>
26#include <asm/arch/hwregs/reg_map.h> 24#include <hwregs/reg_map.h>
27#include <asm/arch/hwregs/ser_defs.h> 25#include <hwregs/ser_defs.h>
26#include <hwregs/pinmux_defs.h>
27#ifdef CONFIG_CRIS_MACH_ARTPEC3
28#include <hwregs/clkgen_defs.h>
29#endif
28 30
29/* 31/*
30 * gzip declarations 32 * gzip declarations
@@ -85,7 +87,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */
85# define Tracecv(c,x) 87# define Tracecv(c,x)
86#endif 88#endif
87 89
88static int fill_inbuf(void);
89static void flush_window(void); 90static void flush_window(void);
90static void error(char *m); 91static void error(char *m);
91static void gzip_mark(void **); 92static void gzip_mark(void **);
@@ -186,6 +187,8 @@ memset(void* s, int c, size_t n)
186 char *ss = (char*)s; 187 char *ss = (char*)s;
187 188
188 for (i=0;i<n;i++) ss[i] = c; 189 for (i=0;i<n;i++) ss[i] = c;
190
191 return s;
189} 192}
190 193
191void* 194void*
@@ -196,6 +199,8 @@ memcpy(void* __dest, __const void* __src,
196 char *d = (char *)__dest, *s = (char *)__src; 199 char *d = (char *)__dest, *s = (char *)__src;
197 200
198 for (i=0;i<__n;i++) d[i] = s[i]; 201 for (i=0;i<__n;i++) d[i] = s[i];
202
203 return __dest;
199} 204}
200 205
201/* =========================================================================== 206/* ===========================================================================
@@ -225,15 +230,15 @@ flush_window()
225static void 230static void
226error(char *x) 231error(char *x)
227{ 232{
228 puts("\n\n"); 233 puts("\r\n\n");
229 puts(x); 234 puts(x);
230 puts("\n\n -- System halted\n"); 235 puts("\r\n\n -- System halted\n");
231 236
232 while(1); /* Halt */ 237 while(1); /* Halt */
233} 238}
234 239
235void 240void
236setup_normal_output_buffer() 241setup_normal_output_buffer(void)
237{ 242{
238 output_data = (char *)KERNEL_LOAD_ADR; 243 output_data = (char *)KERNEL_LOAD_ADR;
239} 244}
@@ -262,15 +267,17 @@ serial_setup(reg_scope_instances regi_ser)
262 rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div); 267 rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
263 268
264 tr_ctrl.stop_bits = 1; /* 2 stop bits. */ 269 tr_ctrl.stop_bits = 1; /* 2 stop bits. */
270 tr_ctrl.en = 1; /* enable transmitter */
271 rec_ctrl.en = 1; /* enabler receiver */
265 272
266 /* 273 /*
267 * The baudrate setup is a bit fishy, but in the end the transceiver is 274 * The baudrate setup used to be a bit fishy, but now transmitter and
268 * set to 4800 and the receiver to 115200. The magic value is 275 * receiver are both set to the intended baud rate, 115200.
269 * 29.493 MHz. 276 * The magic value is 29.493 MHz.
270 */ 277 */
271 tr_ctrl.base_freq = regk_ser_f29_493; 278 tr_ctrl.base_freq = regk_ser_f29_493;
272 rec_ctrl.base_freq = regk_ser_f29_493; 279 rec_ctrl.base_freq = regk_ser_f29_493;
273 tr_baud.div = (29493000 / 8) / 4800; 280 tr_baud.div = (29493000 / 8) / 115200;
274 rec_baud.div = (29493000 / 8) / 115200; 281 rec_baud.div = (29493000 / 8) / 115200;
275 282
276 REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); 283 REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
@@ -280,25 +287,52 @@ serial_setup(reg_scope_instances regi_ser)
280} 287}
281 288
282void 289void
283decompress_kernel() 290decompress_kernel(void)
284{ 291{
285 char revision; 292 char revision;
286 293
287 /* input_data is set in head.S */ 294#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
288 inbuf = input_data; 295 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
296 defined(CONFIG_ETRAX_DEBUG_PORT3)
297 reg_pinmux_rw_hwprot hwprot;
298
299#ifdef CONFIG_CRIS_MACH_ARTPEC3
300 reg_clkgen_rw_clk_ctrl clk_ctrl;
301
302 /* Enable corresponding clock region when serial 1..3 selected */
303
304 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
305 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
306 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
307#endif
308
309 /* pinmux setup for ports 1..3 */
310 hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
311#endif
289 312
290#ifdef CONFIG_ETRAX_DEBUG_PORT0 313#ifdef CONFIG_ETRAX_DEBUG_PORT0
291 serial_setup(regi_ser0); 314 serial_setup(regi_ser0);
292#endif 315#endif
293#ifdef CONFIG_ETRAX_DEBUG_PORT1 316#ifdef CONFIG_ETRAX_DEBUG_PORT1
317 hwprot.ser1 = regk_pinmux_yes;
294 serial_setup(regi_ser1); 318 serial_setup(regi_ser1);
295#endif 319#endif
296#ifdef CONFIG_ETRAX_DEBUG_PORT2 320#ifdef CONFIG_ETRAX_DEBUG_PORT2
321 hwprot.ser2 = regk_pinmux_yes;
297 serial_setup(regi_ser2); 322 serial_setup(regi_ser2);
298#endif 323#endif
299#ifdef CONFIG_ETRAX_DEBUG_PORT3 324#ifdef CONFIG_ETRAX_DEBUG_PORT3
325 hwprot.ser3 = regk_pinmux_yes;
300 serial_setup(regi_ser3); 326 serial_setup(regi_ser3);
301#endif 327#endif
328#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
329 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
330 defined(CONFIG_ETRAX_DEBUG_PORT3)
331 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
332#endif
333
334 /* input_data is set in head.S */
335 inbuf = input_data;
302 336
303 setup_normal_output_buffer(); 337 setup_normal_output_buffer();
304 338
@@ -307,11 +341,11 @@ decompress_kernel()
307 __asm__ volatile ("move $vr,%0" : "=rm" (revision)); 341 __asm__ volatile ("move $vr,%0" : "=rm" (revision));
308 if (revision < 32) 342 if (revision < 32)
309 { 343 {
310 puts("You need an ETRAX FS to run Linux 2.6/crisv32.\n"); 344 puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
311 while(1); 345 while(1);
312 } 346 }
313 347
314 puts("Uncompressing Linux...\n"); 348 puts("Uncompressing Linux...\r\n");
315 gunzip(); 349 gunzip();
316 puts("Done. Now booting the kernel.\n"); 350 puts("Done. Now booting the kernel.\r\n");
317} 351}
diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile
index f668a8198724..c0987795dcb7 100644
--- a/arch/cris/arch-v32/boot/rescue/Makefile
+++ b/arch/cris/arch-v32/boot/rescue/Makefile
@@ -1,36 +1,27 @@
1# 1#
2# Makefile for rescue code 2# Makefile for rescue (bootstrap) code
3# 3#
4target = $(target_rescue_dir)
5src = $(src_rescue_dir)
6 4
7CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) 5CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
8CFLAGS = -O2 6ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
7 -I $(srctree)/include/asm/arch
8asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
9LD = gcc-cris -mlinux -march=v32 -nostdlib 9LD = gcc-cris -mlinux -march=v32 -nostdlib
10ldflags-y += -T $(obj)/rescue.ld
11LDPOSTFLAGS = -lgcc
10OBJCOPY = objcopy-cris 12OBJCOPY = objcopy-cris
11OBJCOPYFLAGS = -O binary --remove-section=.bss 13OBJCOPYFLAGS = -O binary --remove-section=.bss
14obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
15OBJECT := $(obj)/head.o
12 16
13all: $(target)/rescue.bin 17targets := rescue.o rescue.bin
14 18
15rescue: rescue.bin 19quiet_cmd_ldlibgcc = LD $@
16 # do nothing 20cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
17 21
18$(target)/rescue.bin: $(target) $(target)/head.o 22$(obj)/rescue.o: $(OBJECTS) FORCE
19 $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o 23 $(call if_changed,ldlibgcc)
20 $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
21 cp -p $(target)/rescue.bin $(objtree)
22 24
23$(target): 25$(obj)/rescue.bin: $(obj)/rescue.o FORCE
24 mkdir -p $(target) 26 $(call if_changed,objcopy)
25 27 cp -p $(obj)/rescue.bin $(objtree)
26$(target)/head.o: $(src)/head.S
27 $(CC) -D__ASSEMBLY__ -c $< -o $*.o
28
29clean:
30 rm -f $(target)/*.o $(target)/*.bin
31
32fastdep:
33
34modules:
35
36modules-install:
diff --git a/arch/cris/arch-v32/boot/rescue/head.S b/arch/cris/arch-v32/boot/rescue/head.S
index 8cdb4011bc16..5f846b7700a3 100644
--- a/arch/cris/arch-v32/boot/rescue/head.S
+++ b/arch/cris/arch-v32/boot/rescue/head.S
@@ -1,38 +1,26 @@
1/* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $ 1/*
2 * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start
3 * kernel decompressor.
4 *
5 * In practice, this only works for NOR flash (or some convoluted RAM boot)
6 * and hence is not really useful for Artpec-3, so it's Etrax FS / NOR only.
2 * 7 *
3 * This used to be the rescue code but now that is handled by the
4 * RedBoot based RFL instead. Nothing to see here, move along.
5 */ 8 */
6 9
7#include <asm/arch/hwregs/reg_map_asm.h> 10#include <mach/startup.inc>
8#include <asm/arch/hwregs/config_defs_asm.h>
9 11
10 .text 12#ifdef CONFIG_ETRAX_AXISFLASHMAP
11 13
12 ;; Start clocks for used blocks. 14;; Code
13 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
14 move.d [$r1], $r0
15 or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \
16 REG_STATE(config, rw_clk_ctrl, bif, yes) | \
17 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
18 move.d $r0, [$r1]
19 15
20 ;; Copy 68KB NAND flash to Internal RAM (if NAND boot) 16 .text
21 move.d 0x38004000, $r10 17start:
22 move.d 0x8000, $r11
23 move.d 0x11000, $r12
24 move.d copy_complete, $r13
25 and.d 0x000fffff, $r13
26 or.d 0x38000000, $r13
27 18
28#include "../../lib/nand_init.S" 19 ;; Start clocks for used blocks.
20 START_CLOCKS
29 21
30 ;; No NAND found
31 move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10 22 move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10
32 jump $r10 ; Jump to decompresser 23 jump $r10 ; Jump to decompressor
33 nop 24 nop
34 25
35copy_complete: 26#endif
36 move.d 0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10
37 jump $r10 ; Jump to decompresser
38 nop
diff --git a/arch/cris/arch-v32/boot/rescue/rescue.ld b/arch/cris/arch-v32/boot/rescue/rescue.ld
index 42b11aa122b2..8ac646bc1a2b 100644
--- a/arch/cris/arch-v32/boot/rescue/rescue.ld
+++ b/arch/cris/arch-v32/boot/rescue/rescue.ld
@@ -1,20 +1,43 @@
1/*#OUTPUT_FORMAT(elf32-us-cris) */
2OUTPUT_ARCH (crisv32)
3/* Now that NAND support has been stripped, this file could be simplified,
4 * but it doesn't do any harm on the other hand so why bother. */
5
1MEMORY 6MEMORY
2 { 7 {
3 flash : ORIGIN = 0x00000000, 8 bootblk : ORIGIN = 0x38000000,
4 LENGTH = 0x00100000 9 LENGTH = 0x00004000
10 intmem : ORIGIN = 0x38004000,
11 LENGTH = 0x00005000
5 } 12 }
6 13
7SECTIONS 14SECTIONS
8{ 15{
9 .text : 16 .text :
10 { 17 {
11 stext = . ; 18 _stext = . ;
12 *(.text) 19 *(.text)
13 etext = . ; 20 *(.init.text)
14 } > flash 21 *(.rodata)
22 *(.rodata.*)
23 _etext = . ;
24 } > bootblk
15 .data : 25 .data :
16 { 26 {
17 *(.data) 27 *(.data)
18 edata = . ; 28 _edata = . ;
19 } > flash 29 } > bootblk
30 .bss :
31 {
32 _bss = . ;
33 *(.bss)
34 _end = ALIGN( 0x10 ) ;
35 } > intmem
36
37 /* Get rid of stuff from EXPORT_SYMBOL(foo). */
38 /DISCARD/ :
39 {
40 *(__ksymtab_strings)
41 *(__ksymtab)
42 }
20} 43}
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index c329cce2a0c3..2a92cb1886ca 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -4,64 +4,102 @@ config ETRAX_ETHERNET
4 bool "Ethernet support" 4 bool "Ethernet support"
5 depends on ETRAX_ARCH_V32 5 depends on ETRAX_ARCH_V32
6 select NET_ETHERNET 6 select NET_ETHERNET
7 select MII
7 help 8 help
8 This option enables the ETRAX FS built-in 10/100Mbit Ethernet 9 This option enables the ETRAX FS built-in 10/100Mbit Ethernet
9 controller. 10 controller.
10 11
11config ETRAX_ETHERNET_HW_CSUM 12config ETRAX_NO_PHY
12 bool "Hardware accelerated ethernet checksum and scatter/gather" 13 bool "PHY not present"
13 depends on ETRAX_ETHERNET 14 depends on ETRAX_ETHERNET
14 depends on ETRAX_STREAMCOPROC 15 default N
15 default y
16 help 16 help
17 Hardware acceleration of checksumming and scatter/gather 17 This option disables all MDIO communication with an ethernet
18 transceiver connected to the MII interface. This option shall
19 typically be enabled if the MII interface is connected to a
20 switch. This option should normally be disabled. If enabled,
21 speed and duplex will be locked to 100 Mbit and full duplex.
18 22
19config ETRAX_ETHERNET_IFACE0 23config ETRAX_ETHERNET_IFACE0
20 depends on ETRAX_ETHERNET 24 depends on ETRAX_ETHERNET
21 bool "Enable network interface 0" 25 bool "Enable network interface 0"
22 26
23config ETRAX_ETHERNET_IFACE1 27config ETRAX_ETHERNET_IFACE1
24 depends on ETRAX_ETHERNET 28 depends on (ETRAX_ETHERNET && ETRAXFS)
25 bool "Enable network interface 1 (uses DMA6 and DMA7)" 29 bool "Enable network interface 1 (uses DMA6 and DMA7)"
26 30
31config ETRAX_ETHERNET_GBIT
32 depends on (ETRAX_ETHERNET && CRIS_MACH_ARTPEC3)
33 bool "Enable gigabit Ethernet support"
34
27choice 35choice
28 prompt "Network LED behavior" 36 prompt "Eth0 led group"
29 depends on ETRAX_ETHERNET 37 depends on ETRAX_ETHERNET_IFACE0
30 default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY 38 default ETRAX_ETH0_USE_LEDGRP0
31 39
32config ETRAX_NETWORK_LED_ON_WHEN_LINK 40config ETRAX_ETH0_USE_LEDGRP0
33 bool "LED_on_when_link" 41 bool "Use LED grp 0"
42 depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
34 help 43 help
35 Selecting LED_on_when_link will light the LED when there is a 44 Use LED grp 0 for eth0
36 connection and will flash off when there is activity.
37 45
38 Selecting LED_on_when_activity will light the LED only when 46config ETRAX_ETH0_USE_LEDGRP1
39 there is activity. 47 bool "Use LED grp 1"
40 48 depends on ETRAX_NBR_LED_GRP_TWO
41 This setting will also affect the behaviour of other activity LEDs 49 help
42 e.g. Bluetooth. 50 Use LED grp 1 for eth0
43 51
44config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY 52config ETRAX_ETH0_USE_LEDGRPNULL
45 bool "LED_on_when_activity" 53 bool "Use no LEDs for eth0"
46 help 54 help
47 Selecting LED_on_when_link will light the LED when there is a 55 Use no LEDs for eth0
48 connection and will flash off when there is activity. 56endchoice
49 57
50 Selecting LED_on_when_activity will light the LED only when 58choice
51 there is activity. 59 prompt "Eth1 led group"
60 depends on ETRAX_ETHERNET_IFACE1
61 default ETRAX_ETH1_USE_LEDGRP1
62
63config ETRAX_ETH1_USE_LEDGRP0
64 bool "Use LED grp 0"
65 depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
66 help
67 Use LED grp 0 for eth1
52 68
53 This setting will also affect the behaviour of other activity LEDs 69config ETRAX_ETH1_USE_LEDGRP1
54 e.g. Bluetooth. 70 bool "Use LED grp 1"
71 depends on ETRAX_NBR_LED_GRP_TWO
72 help
73 Use LED grp 1 for eth1
55 74
75config ETRAX_ETH1_USE_LEDGRPNULL
76 bool "Use no LEDs for eth1"
77 help
78 Use no LEDs for eth1
56endchoice 79endchoice
57 80
58config ETRAXFS_SERIAL 81config ETRAXFS_SERIAL
59 bool "Serial-port support" 82 bool "Serial-port support"
60 depends on ETRAX_ARCH_V32 83 depends on ETRAX_ARCH_V32
84 select SERIAL_CORE
85 select SERIAL_CORE_CONSOLE
61 help 86 help
62 Enables the ETRAX FS serial driver for ser0 (ttyS0) 87 Enables the ETRAX FS serial driver for ser0 (ttyS0)
63 You probably want this enabled. 88 You probably want this enabled.
64 89
90config ETRAX_RS485
91 bool "RS-485 support"
92 depends on ETRAXFS_SERIAL
93 help
94 Enables support for RS-485 serial communication.
95
96config ETRAX_RS485_DISABLE_RECEIVER
97 bool "Disable serial receiver"
98 depends on ETRAX_RS485
99 help
100 It is necessary to disable the serial receiver to avoid serial
101 loopback. Not all products are able to do this in software only.
102
65config ETRAX_SERIAL_PORT0 103config ETRAX_SERIAL_PORT0
66 bool "Serial port 0 enabled" 104 bool "Serial port 0 enabled"
67 depends on ETRAXFS_SERIAL 105 depends on ETRAXFS_SERIAL
@@ -72,50 +110,28 @@ config ETRAX_SERIAL_PORT0
72 ser0 can use dma4 or dma6 for output and dma5 or dma7 for input. 110 ser0 can use dma4 or dma6 for output and dma5 or dma7 for input.
73 111
74choice 112choice
75 prompt "Ser0 DMA in channel " 113 prompt "Ser0 default port type "
76 depends on ETRAX_SERIAL_PORT0 114 depends on ETRAX_SERIAL_PORT0
77 default ETRAX_SERIAL_PORT0_NO_DMA_IN 115 default ETRAX_SERIAL_PORT0_TYPE_232
78 help 116 help
79 What DMA channel to use for ser0. 117 Type of serial port.
80
81 118
82config ETRAX_SERIAL_PORT0_NO_DMA_IN 119config ETRAX_SERIAL_PORT0_TYPE_232
83 bool "Ser0 uses no DMA for input" 120 bool "Ser0 is a RS-232 port"
84 help 121 help
85 Do not use DMA for ser0 input. 122 Configure serial port 0 to be a RS-232 port.
86 123
87config ETRAX_SERIAL_PORT0_DMA7_IN 124config ETRAX_SERIAL_PORT0_TYPE_485HD
88 bool "Ser0 uses DMA7 for input" 125 bool "Ser0 is a half duplex RS-485 port"
89 depends on ETRAX_SERIAL_PORT0 126 depends on ETRAX_RS485
90 help
91 Enables the DMA7 input channel for ser0 (ttyS0).
92 If you do not enable DMA, an interrupt for each character will be
93 used when receiving data.
94 Normally you want to use DMA, unless you use the DMA channel for
95 something else.
96
97endchoice
98
99choice
100 prompt "Ser0 DMA out channel"
101 depends on ETRAX_SERIAL_PORT0
102 default ETRAX_SERIAL_PORT0_NO_DMA_OUT
103
104config ETRAX_SERIAL_PORT0_NO_DMA_OUT
105 bool "Ser0 uses no DMA for output"
106 help 127 help
107 Do not use DMA for ser0 output. 128 Configure serial port 0 to be a half duplex (two wires) RS-485 port.
108 129
109config ETRAX_SERIAL_PORT0_DMA6_OUT 130config ETRAX_SERIAL_PORT0_TYPE_485FD
110 bool "Ser0 uses DMA6 for output" 131 bool "Ser0 is a full duplex RS-485 port"
111 depends on ETRAX_SERIAL_PORT0 132 depends on ETRAX_RS485
112 help 133 help
113 Enables the DMA6 output channel for ser0 (ttyS0). 134 Configure serial port 0 to be a full duplex (four wires) RS-485 port.
114 If you do not enable DMA, an interrupt for each character will be
115 used when transmitting data.
116 Normally you want to use DMA, unless you use the DMA channel for
117 something else.
118
119endchoice 135endchoice
120 136
121config ETRAX_SER0_DTR_BIT 137config ETRAX_SER0_DTR_BIT
@@ -141,52 +157,28 @@ config ETRAX_SERIAL_PORT1
141 Enables the ETRAX FS serial driver for ser1 (ttyS1). 157 Enables the ETRAX FS serial driver for ser1 (ttyS1).
142 158
143choice 159choice
144 prompt "Ser1 DMA in channel " 160 prompt "Ser1 default port type"
145 depends on ETRAX_SERIAL_PORT1 161 depends on ETRAX_SERIAL_PORT1
146 default ETRAX_SERIAL_PORT1_NO_DMA_IN 162 default ETRAX_SERIAL_PORT1_TYPE_232
147 help
148 What DMA channel to use for ser1.
149
150
151config ETRAX_SERIAL_PORT1_NO_DMA_IN
152 bool "Ser1 uses no DMA for input"
153 help 163 help
154 Do not use DMA for ser1 input. 164 Type of serial port.
155 165
156config ETRAX_SERIAL_PORT1_DMA5_IN 166config ETRAX_SERIAL_PORT1_TYPE_232
157 bool "Ser1 uses DMA5 for input" 167 bool "Ser1 is a RS-232 port"
158 depends on ETRAX_SERIAL_PORT1
159 help 168 help
160 Enables the DMA5 input channel for ser1 (ttyS1). 169 Configure serial port 1 to be a RS-232 port.
161 If you do not enable DMA, an interrupt for each character will be
162 used when receiving data.
163 Normally you want this on, unless you use the DMA channel for
164 something else.
165
166endchoice
167 170
168choice 171config ETRAX_SERIAL_PORT1_TYPE_485HD
169 prompt "Ser1 DMA out channel " 172 bool "Ser1 is a half duplex RS-485 port"
170 depends on ETRAX_SERIAL_PORT1 173 depends on ETRAX_RS485
171 default ETRAX_SERIAL_PORT1_NO_DMA_OUT
172 help
173 What DMA channel to use for ser1.
174
175config ETRAX_SERIAL_PORT1_NO_DMA_OUT
176 bool "Ser1 uses no DMA for output"
177 help 174 help
178 Do not use DMA for ser1 output. 175 Configure serial port 1 to be a half duplex (two wires) RS-485 port.
179 176
180config ETRAX_SERIAL_PORT1_DMA4_OUT 177config ETRAX_SERIAL_PORT1_TYPE_485FD
181 bool "Ser1 uses DMA4 for output" 178 bool "Ser1 is a full duplex RS-485 port"
182 depends on ETRAX_SERIAL_PORT1 179 depends on ETRAX_RS485
183 help 180 help
184 Enables the DMA4 output channel for ser1 (ttyS1). 181 Configure serial port 1 to be a full duplex (four wires) RS-485 port.
185 If you do not enable DMA, an interrupt for each character will be
186 used when transmitting data.
187 Normally you want this on, unless you use the DMA channel for
188 something else.
189
190endchoice 182endchoice
191 183
192config ETRAX_SER1_DTR_BIT 184config ETRAX_SER1_DTR_BIT
@@ -212,52 +204,31 @@ config ETRAX_SERIAL_PORT2
212 Enables the ETRAX FS serial driver for ser2 (ttyS2). 204 Enables the ETRAX FS serial driver for ser2 (ttyS2).
213 205
214choice 206choice
215 prompt "Ser2 DMA in channel " 207 prompt "Ser2 default port type"
216 depends on ETRAX_SERIAL_PORT2 208 depends on ETRAX_SERIAL_PORT2
217 default ETRAX_SERIAL_PORT2_NO_DMA_IN 209 default ETRAX_SERIAL_PORT2_TYPE_232
218 help 210 help
219 What DMA channel to use for ser2. 211 What DMA channel to use for ser2
220 212
221 213config ETRAX_SERIAL_PORT2_TYPE_232
222config ETRAX_SERIAL_PORT2_NO_DMA_IN 214 bool "Ser2 is a RS-232 port"
223 bool "Ser2 uses no DMA for input"
224 help 215 help
225 Do not use DMA for ser2 input. 216 Configure serial port 2 to be a RS-232 port.
226 217
227config ETRAX_SERIAL_PORT2_DMA3_IN 218config ETRAX_SERIAL_PORT2_TYPE_485HD
228 bool "Ser2 uses DMA3 for input" 219 bool "Ser2 is a half duplex RS-485 port"
229 depends on ETRAX_SERIAL_PORT2 220 depends on ETRAX_RS485
230 help
231 Enables the DMA3 input channel for ser2 (ttyS2).
232 If you do not enable DMA, an interrupt for each character will be
233 used when receiving data.
234 Normally you want to use DMA, unless you use the DMA channel for
235 something else.
236
237endchoice
238
239choice
240 prompt "Ser2 DMA out channel"
241 depends on ETRAX_SERIAL_PORT2
242 default ETRAX_SERIAL_PORT2_NO_DMA_OUT
243
244config ETRAX_SERIAL_PORT2_NO_DMA_OUT
245 bool "Ser2 uses no DMA for output"
246 help 221 help
247 Do not use DMA for ser2 output. 222 Configure serial port 2 to be a half duplex (two wires) RS-485 port.
248 223
249config ETRAX_SERIAL_PORT2_DMA2_OUT 224config ETRAX_SERIAL_PORT2_TYPE_485FD
250 bool "Ser2 uses DMA2 for output" 225 bool "Ser2 is a full duplex RS-485 port"
251 depends on ETRAX_SERIAL_PORT2 226 depends on ETRAX_RS485
252 help 227 help
253 Enables the DMA2 output channel for ser2 (ttyS2). 228 Configure serial port 2 to be a full duplex (four wires) RS-485 port.
254 If you do not enable DMA, an interrupt for each character will be
255 used when transmitting data.
256 Normally you want to use DMA, unless you use the DMA channel for
257 something else.
258
259endchoice 229endchoice
260 230
231
261config ETRAX_SER2_DTR_BIT 232config ETRAX_SER2_DTR_BIT
262 string "Ser 2 DTR bit (empty = not used)" 233 string "Ser 2 DTR bit (empty = not used)"
263 depends on ETRAX_SERIAL_PORT2 234 depends on ETRAX_SERIAL_PORT2
@@ -281,71 +252,121 @@ config ETRAX_SERIAL_PORT3
281 Enables the ETRAX FS serial driver for ser3 (ttyS3). 252 Enables the ETRAX FS serial driver for ser3 (ttyS3).
282 253
283choice 254choice
284 prompt "Ser3 DMA in channel " 255 prompt "Ser3 default port type"
285 depends on ETRAX_SERIAL_PORT3 256 depends on ETRAX_SERIAL_PORT3
286 default ETRAX_SERIAL_PORT3_NO_DMA_IN 257 default ETRAX_SERIAL_PORT3_TYPE_232
287 help 258 help
288 What DMA channel to use for ser3. 259 What DMA channel to use for ser3.
289 260
261config ETRAX_SERIAL_PORT3_TYPE_232
262 bool "Ser3 is a RS-232 port"
263 help
264 Configure serial port 3 to be a RS-232 port.
290 265
291config ETRAX_SERIAL_PORT3_NO_DMA_IN 266config ETRAX_SERIAL_PORT3_TYPE_485HD
292 bool "Ser3 uses no DMA for input" 267 bool "Ser3 is a half duplex RS-485 port"
268 depends on ETRAX_RS485
293 help 269 help
294 Do not use DMA for ser3 input. 270 Configure serial port 3 to be a half duplex (two wires) RS-485 port.
295 271
296config ETRAX_SERIAL_PORT3_DMA9_IN 272config ETRAX_SERIAL_PORT3_TYPE_485FD
297 bool "Ser3 uses DMA9 for input" 273 bool "Ser3 is a full duplex RS-485 port"
274 depends on ETRAX_RS485
275 help
276 Configure serial port 3 to be a full duplex (four wires) RS-485 port.
277endchoice
278
279config ETRAX_SER3_DTR_BIT
280 string "Ser 3 DTR bit (empty = not used)"
281 depends on ETRAX_SERIAL_PORT3
282
283config ETRAX_SER3_RI_BIT
284 string "Ser 3 RI bit (empty = not used)"
285 depends on ETRAX_SERIAL_PORT3
286
287config ETRAX_SER3_DSR_BIT
288 string "Ser 3 DSR bit (empty = not used)"
289 depends on ETRAX_SERIAL_PORT3
290
291config ETRAX_SER3_CD_BIT
292 string "Ser 3 CD bit (empty = not used)"
298 depends on ETRAX_SERIAL_PORT3 293 depends on ETRAX_SERIAL_PORT3
294
295config ETRAX_SERIAL_PORT4
296 bool "Serial port 4 enabled"
297 depends on ETRAXFS_SERIAL && CRIS_MACH_ARTPEC3
299 help 298 help
300 Enables the DMA9 input channel for ser3 (ttyS3). 299 Enables the ETRAX FS serial driver for ser4 (ttyS4).
301 If you do not enable DMA, an interrupt for each character will be 300
302 used when receiving data. 301choice
303 Normally you want to use DMA, unless you use the DMA channel for 302 prompt "Ser4 default port type"
304 something else. 303 depends on ETRAX_SERIAL_PORT4
304 default ETRAX_SERIAL_PORT4_TYPE_232
305 help
306 What DMA channel to use for ser4.
305 307
308config ETRAX_SERIAL_PORT4_TYPE_232
309 bool "Ser4 is a RS-232 port"
310 help
311 Configure serial port 4 to be a RS-232 port.
312
313config ETRAX_SERIAL_PORT4_TYPE_485HD
314 bool "Ser4 is a half duplex RS-485 port"
315 depends on ETRAX_RS485
316 help
317 Configure serial port 4 to be a half duplex (two wires) RS-485 port.
318
319config ETRAX_SERIAL_PORT4_TYPE_485FD
320 bool "Ser4 is a full duplex RS-485 port"
321 depends on ETRAX_RS485
322 help
323 Configure serial port 4 to be a full duplex (four wires) RS-485 port.
306endchoice 324endchoice
307 325
308choice 326choice
309 prompt "Ser3 DMA out channel" 327 prompt "Ser4 DMA in channel "
310 depends on ETRAX_SERIAL_PORT3 328 depends on ETRAX_SERIAL_PORT4
311 default ETRAX_SERIAL_PORT3_NO_DMA_OUT 329 default ETRAX_SERIAL_PORT4_NO_DMA_IN
330 help
331 What DMA channel to use for ser4.
332
312 333
313config ETRAX_SERIAL_PORT3_NO_DMA_OUT 334config ETRAX_SERIAL_PORT4_NO_DMA_IN
314 bool "Ser3 uses no DMA for output" 335 bool "Ser4 uses no DMA for input"
315 help 336 help
316 Do not use DMA for ser3 output. 337 Do not use DMA for ser4 input.
317 338
318config ETRAX_SERIAL_PORT3_DMA8_OUT 339config ETRAX_SERIAL_PORT4_DMA9_IN
319 bool "Ser3 uses DMA8 for output" 340 bool "Ser4 uses DMA9 for input"
320 depends on ETRAX_SERIAL_PORT3 341 depends on ETRAX_SERIAL_PORT4
321 help 342 help
322 Enables the DMA8 output channel for ser3 (ttyS3). 343 Enables the DMA9 input channel for ser4 (ttyS4).
323 If you do not enable DMA, an interrupt for each character will be 344 If you do not enable DMA, an interrupt for each character will be
324 used when transmitting data. 345 used when receiveing data.
325 Normally you want to use DMA, unless you use the DMA channel for 346 Normally you want to use DMA, unless you use the DMA channel for
326 something else. 347 something else.
327 348
328endchoice 349endchoice
329 350
330config ETRAX_SER3_DTR_BIT 351config ETRAX_SER4_DTR_BIT
331 string "Ser 3 DTR bit (empty = not used)" 352 string "Ser 4 DTR bit (empty = not used)"
332 depends on ETRAX_SERIAL_PORT3 353 depends on ETRAX_SERIAL_PORT4
333 354
334config ETRAX_SER3_RI_BIT 355config ETRAX_SER4_RI_BIT
335 string "Ser 3 RI bit (empty = not used)" 356 string "Ser 4 RI bit (empty = not used)"
336 depends on ETRAX_SERIAL_PORT3 357 depends on ETRAX_SERIAL_PORT4
337 358
338config ETRAX_SER3_DSR_BIT 359config ETRAX_SER4_DSR_BIT
339 string "Ser 3 DSR bit (empty = not used)" 360 string "Ser 4 DSR bit (empty = not used)"
340 depends on ETRAX_SERIAL_PORT3 361 depends on ETRAX_SERIAL_PORT4
341 362
342config ETRAX_SER3_CD_BIT 363config ETRAX_SER3_CD_BIT
343 string "Ser 3 CD bit (empty = not used)" 364 string "Ser 4 CD bit (empty = not used)"
344 depends on ETRAX_SERIAL_PORT3 365 depends on ETRAX_SERIAL_PORT4
345 366
346config ETRAX_RS485 367config ETRAX_RS485
347 bool "RS-485 support" 368 bool "RS-485 support"
348 depends on ETRAX_SERIAL 369 depends on ETRAXFS_SERIAL
349 help 370 help
350 Enables support for RS-485 serial communication. For a primer on 371 Enables support for RS-485 serial communication. For a primer on
351 RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. 372 RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
@@ -356,22 +377,6 @@ config ETRAX_RS485_DISABLE_RECEIVER
356 help 377 help
357 It is necessary to disable the serial receiver to avoid serial 378 It is necessary to disable the serial receiver to avoid serial
358 loopback. Not all products are able to do this in software only. 379 loopback. Not all products are able to do this in software only.
359 Axis 2400/2401 must disable receiver.
360
361config ETRAX_AXISFLASHMAP
362 bool "Axis flash-map support"
363 depends on ETRAX_ARCH_V32
364 select MTD
365 select MTD_CFI
366 select MTD_CFI_AMDSTD
367 select MTD_CHAR
368 select MTD_BLOCK
369 select MTD_PARTITIONS
370 select MTD_CONCAT
371 select MTD_COMPLEX_MAPPINGS
372 help
373 This option enables MTD mapping of flash devices. Needed to use
374 flash memories. If unsure, say Y.
375 380
376config ETRAX_SYNCHRONOUS_SERIAL 381config ETRAX_SYNCHRONOUS_SERIAL
377 bool "Synchronous serial-port support" 382 bool "Synchronous serial-port support"
@@ -394,7 +399,7 @@ config ETRAX_SYNCHRONOUS_SERIAL0_DMA
394 399
395config ETRAX_SYNCHRONOUS_SERIAL_PORT1 400config ETRAX_SYNCHRONOUS_SERIAL_PORT1
396 bool "Synchronous serial port 1 enabled" 401 bool "Synchronous serial port 1 enabled"
397 depends on ETRAX_SYNCHRONOUS_SERIAL 402 depends on ETRAX_SYNCHRONOUS_SERIAL && ETRAXFS
398 help 403 help
399 Enabled synchronous serial port 1. 404 Enabled synchronous serial port 1.
400 405
@@ -405,6 +410,31 @@ config ETRAX_SYNCHRONOUS_SERIAL1_DMA
405 A synchronous serial port can run in manual or DMA mode. 410 A synchronous serial port can run in manual or DMA mode.
406 Selecting this option will make it run in DMA mode. 411 Selecting this option will make it run in DMA mode.
407 412
413config ETRAX_AXISFLASHMAP
414 bool "Axis flash-map support"
415 depends on ETRAX_ARCH_V32
416 select MTD
417 select MTD_CFI
418 select MTD_CFI_AMDSTD
419 select MTD_JEDECPROBE
420 select MTD_CHAR
421 select MTD_BLOCK
422 select MTD_PARTITIONS
423 select MTD_CONCAT
424 select MTD_COMPLEX_MAPPINGS
425 help
426 This option enables MTD mapping of flash devices. Needed to use
427 flash memories. If unsure, say Y.
428
429config ETRAX_AXISFLASHMAP_MTD0WHOLE
430 bool "MTD0 is whole boot flash device"
431 depends on ETRAX_AXISFLASHMAP
432 default N
433 help
434 When this option is not set, mtd0 refers to the first partition
435 on the boot flash device. When set, mtd0 refers to the whole
436 device, with mtd1 referring to the first partition etc.
437
408config ETRAX_PTABLE_SECTOR 438config ETRAX_PTABLE_SECTOR
409 int "Byte-offset of partition table sector" 439 int "Byte-offset of partition table sector"
410 depends on ETRAX_AXISFLASHMAP 440 depends on ETRAX_AXISFLASHMAP
@@ -425,42 +455,32 @@ config ETRAX_NANDFLASH
425 This option enables MTD mapping of NAND flash devices. Needed to use 455 This option enables MTD mapping of NAND flash devices. Needed to use
426 NAND flash memories. If unsure, say Y. 456 NAND flash memories. If unsure, say Y.
427 457
458config ETRAX_NANDBOOT
459 bool "Boot from NAND flash"
460 depends on ETRAX_NANDFLASH
461 help
462 This options enables booting from NAND flash devices.
463 Say Y if your boot code, kernel and root file system is in
464 NAND flash. Say N if they are in NOR flash.
465
428config ETRAX_I2C 466config ETRAX_I2C
429 bool "I2C driver" 467 bool "I2C driver"
430 depends on ETRAX_ARCH_V32 468 depends on ETRAX_ARCH_V32
431 help 469 help
432 This option enabled the I2C driver used by e.g. the RTC driver. 470 This option enables the I2C driver used by e.g. the RTC driver.
433 471
434config ETRAX_I2C_DATA_PORT 472config ETRAX_V32_I2C_DATA_PORT
435 string "I2C data pin" 473 string "I2C data pin"
436 depends on ETRAX_I2C 474 depends on ETRAX_I2C
437 help 475 help
438 The pin to use for I2C data. 476 The pin to use for I2C data.
439 477
440config ETRAX_I2C_CLK_PORT 478config ETRAX_V32_I2C_CLK_PORT
441 string "I2C clock pin" 479 string "I2C clock pin"
442 depends on ETRAX_I2C 480 depends on ETRAX_I2C
443 help 481 help
444 The pin to use for I2C clock. 482 The pin to use for I2C clock.
445 483
446config ETRAX_RTC
447 bool "Real Time Clock support"
448 depends on ETRAX_ARCH_V32
449 help
450 Enabled RTC support.
451
452choice
453 prompt "RTC chip"
454 depends on ETRAX_RTC
455 default ETRAX_PCF8563
456
457config ETRAX_PCF8563
458 bool "PCF8563"
459 help
460 Philips PCF8563 RTC
461
462endchoice
463
464config ETRAX_GPIO 484config ETRAX_GPIO
465 bool "GPIO support" 485 bool "GPIO support"
466 depends on ETRAX_ARCH_V32 486 depends on ETRAX_ARCH_V32
@@ -476,33 +496,36 @@ config ETRAX_GPIO
476 Remember that you need to setup the port directions appropriately in 496 Remember that you need to setup the port directions appropriately in
477 the General configuration. 497 the General configuration.
478 498
479config ETRAX_PA_BUTTON_BITMASK 499config ETRAX_VIRTUAL_GPIO
480 hex "PA-buttons bitmask" 500 bool "Virtual GPIO support"
481 depends on ETRAX_GPIO 501 depends on ETRAX_GPIO
482 default "0x02"
483 help 502 help
484 This is a bitmask (8 bits) with information about what bits on PA 503 Enables the virtual Etrax general port device (major 120, minor 6).
485 that are used for buttons. 504 It uses an I/O expander for the I2C-bus.
486 Most products has a so called TEST button on PA1, if that is true 505
487 use 0x02 here. 506config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
488 Use 00 if there are no buttons on PA. 507 int "Virtual GPIO interrupt pin on PA pin"
489 If the bitmask is <> 00 a button driver will be included in the gpio 508 range 0 7
490 driver. ETRAX general I/O support must be enabled. 509 depends on ETRAX_VIRTUAL_GPIO
510 help
511 The pin to use on PA for virtual gpio interrupt.
491 512
492config ETRAX_PA_CHANGEABLE_DIR 513config ETRAX_PA_CHANGEABLE_DIR
493 hex "PA user changeable dir mask" 514 hex "PA user changeable dir mask"
494 depends on ETRAX_GPIO 515 depends on ETRAX_GPIO
495 default "0x00" 516 default "0x00" if ETRAXFS
517 default "0x00000000" if !ETRAXFS
496 help 518 help
497 This is a bitmask (8 bits) with information of what bits in PA that a 519 This is a bitmask (8 bits) with information of what bits in PA that a
498 user can change direction on using ioctl's. 520 user can change direction on using ioctl's.
499 Bit set = changeable. 521 Bit set = changeable.
500 You probably want 0x00 here, but it depends on your hardware. 522 You probably want 0 here, but it depends on your hardware.
501 523
502config ETRAX_PA_CHANGEABLE_BITS 524config ETRAX_PA_CHANGEABLE_BITS
503 hex "PA user changeable bits mask" 525 hex "PA user changeable bits mask"
504 depends on ETRAX_GPIO 526 depends on ETRAX_GPIO
505 default "0x00" 527 default "0x00" if ETRAXFS
528 default "0x00000000" if !ETRAXFS
506 help 529 help
507 This is a bitmask (8 bits) with information of what bits in PA 530 This is a bitmask (8 bits) with information of what bits in PA
508 that a user can change the value on using ioctl's. 531 that a user can change the value on using ioctl's.
@@ -511,17 +534,19 @@ config ETRAX_PA_CHANGEABLE_BITS
511config ETRAX_PB_CHANGEABLE_DIR 534config ETRAX_PB_CHANGEABLE_DIR
512 hex "PB user changeable dir mask" 535 hex "PB user changeable dir mask"
513 depends on ETRAX_GPIO 536 depends on ETRAX_GPIO
514 default "0x00000" 537 default "0x00000" if ETRAXFS
538 default "0x00000000" if !ETRAXFS
515 help 539 help
516 This is a bitmask (18 bits) with information of what bits in PB 540 This is a bitmask (18 bits) with information of what bits in PB
517 that a user can change direction on using ioctl's. 541 that a user can change direction on using ioctl's.
518 Bit set = changeable. 542 Bit set = changeable.
519 You probably want 0x00000 here, but it depends on your hardware. 543 You probably want 0 here, but it depends on your hardware.
520 544
521config ETRAX_PB_CHANGEABLE_BITS 545config ETRAX_PB_CHANGEABLE_BITS
522 hex "PB user changeable bits mask" 546 hex "PB user changeable bits mask"
523 depends on ETRAX_GPIO 547 depends on ETRAX_GPIO
524 default "0x00000" 548 default "0x00000" if ETRAXFS
549 default "0x00000000" if !ETRAXFS
525 help 550 help
526 This is a bitmask (18 bits) with information of what bits in PB 551 This is a bitmask (18 bits) with information of what bits in PB
527 that a user can change the value on using ioctl's. 552 that a user can change the value on using ioctl's.
@@ -530,17 +555,19 @@ config ETRAX_PB_CHANGEABLE_BITS
530config ETRAX_PC_CHANGEABLE_DIR 555config ETRAX_PC_CHANGEABLE_DIR
531 hex "PC user changeable dir mask" 556 hex "PC user changeable dir mask"
532 depends on ETRAX_GPIO 557 depends on ETRAX_GPIO
533 default "0x00000" 558 default "0x00000" if ETRAXFS
559 default "0x00000000" if !ETRAXFS
534 help 560 help
535 This is a bitmask (18 bits) with information of what bits in PC 561 This is a bitmask (18 bits) with information of what bits in PC
536 that a user can change direction on using ioctl's. 562 that a user can change direction on using ioctl's.
537 Bit set = changeable. 563 Bit set = changeable.
538 You probably want 0x00000 here, but it depends on your hardware. 564 You probably want 0 here, but it depends on your hardware.
539 565
540config ETRAX_PC_CHANGEABLE_BITS 566config ETRAX_PC_CHANGEABLE_BITS
541 hex "PC user changeable bits mask" 567 hex "PC user changeable bits mask"
542 depends on ETRAX_GPIO 568 depends on ETRAX_GPIO
543 default "0x00000" 569 default "0x00000" if ETRAXFS
570 default "0x00000000" if ETRAXFS
544 help 571 help
545 This is a bitmask (18 bits) with information of what bits in PC 572 This is a bitmask (18 bits) with information of what bits in PC
546 that a user can change the value on using ioctl's. 573 that a user can change the value on using ioctl's.
@@ -548,7 +575,7 @@ config ETRAX_PC_CHANGEABLE_BITS
548 575
549config ETRAX_PD_CHANGEABLE_DIR 576config ETRAX_PD_CHANGEABLE_DIR
550 hex "PD user changeable dir mask" 577 hex "PD user changeable dir mask"
551 depends on ETRAX_GPIO 578 depends on ETRAX_GPIO && ETRAXFS
552 default "0x00000" 579 default "0x00000"
553 help 580 help
554 This is a bitmask (18 bits) with information of what bits in PD 581 This is a bitmask (18 bits) with information of what bits in PD
@@ -558,7 +585,7 @@ config ETRAX_PD_CHANGEABLE_DIR
558 585
559config ETRAX_PD_CHANGEABLE_BITS 586config ETRAX_PD_CHANGEABLE_BITS
560 hex "PD user changeable bits mask" 587 hex "PD user changeable bits mask"
561 depends on ETRAX_GPIO 588 depends on ETRAX_GPIO && ETRAXFS
562 default "0x00000" 589 default "0x00000"
563 help 590 help
564 This is a bitmask (18 bits) with information of what bits in PD 591 This is a bitmask (18 bits) with information of what bits in PD
@@ -567,7 +594,7 @@ config ETRAX_PD_CHANGEABLE_BITS
567 594
568config ETRAX_PE_CHANGEABLE_DIR 595config ETRAX_PE_CHANGEABLE_DIR
569 hex "PE user changeable dir mask" 596 hex "PE user changeable dir mask"
570 depends on ETRAX_GPIO 597 depends on ETRAX_GPIO && ETRAXFS
571 default "0x00000" 598 default "0x00000"
572 help 599 help
573 This is a bitmask (18 bits) with information of what bits in PE 600 This is a bitmask (18 bits) with information of what bits in PE
@@ -577,20 +604,36 @@ config ETRAX_PE_CHANGEABLE_DIR
577 604
578config ETRAX_PE_CHANGEABLE_BITS 605config ETRAX_PE_CHANGEABLE_BITS
579 hex "PE user changeable bits mask" 606 hex "PE user changeable bits mask"
580 depends on ETRAX_GPIO 607 depends on ETRAX_GPIO && ETRAXFS
581 default "0x00000" 608 default "0x00000"
582 help 609 help
583 This is a bitmask (18 bits) with information of what bits in PE 610 This is a bitmask (18 bits) with information of what bits in PE
584 that a user can change the value on using ioctl's. 611 that a user can change the value on using ioctl's.
585 Bit set = changeable. 612 Bit set = changeable.
586 613
614config ETRAX_PV_CHANGEABLE_DIR
615 hex "PV user changeable dir mask"
616 depends on ETRAX_VIRTUAL_GPIO
617 default "0x0000"
618 help
619 This is a bitmask (16 bits) with information of what bits in PV
620 that a user can change direction on using ioctl's.
621 Bit set = changeable.
622 You probably want 0x0000 here, but it depends on your hardware.
623
624config ETRAX_PV_CHANGEABLE_BITS
625 hex "PV user changeable bits mask"
626 depends on ETRAX_VIRTUAL_GPIO
627 default "0x0000"
628 help
629 This is a bitmask (16 bits) with information of what bits in PV
630 that a user can change the value on using ioctl's.
631 Bit set = changeable.
632
587config ETRAX_CARDBUS 633config ETRAX_CARDBUS
588 bool "Cardbus support" 634 bool "Cardbus support"
589 depends on ETRAX_ARCH_V32 635 depends on ETRAX_ARCH_V32
590 select PCCARD
591 select CARDBUS
592 select HOTPLUG 636 select HOTPLUG
593 select PCCARD_NONSTATIC
594 help 637 help
595 Enabled the ETRAX Cardbus driver. 638 Enabled the ETRAX Cardbus driver.
596 639
@@ -613,4 +656,202 @@ config ETRAX_STREAMCOPROC
613 This option enables a driver for the stream co-processor 656 This option enables a driver for the stream co-processor
614 for cryptographic operations. 657 for cryptographic operations.
615 658
659source drivers/mmc/Kconfig
660
661config ETRAX_MMC_IOP
662 tristate "MMC/SD host driver using IO-processor"
663 depends on ETRAX_ARCH_V32 && MMC
664 help
665 This option enables the SD/MMC host controller interface.
666 The host controller is implemented using the built in
667 IO-Processor. Only the SPU is used in this implementation.
668
669config ETRAX_SPI_MMC
670# Make this one of several "choices" (possible simultaneously but
671# suggested uniquely) when an IOP driver emerges for "real" MMC/SD
672# protocol support.
673 tristate
674 depends on !ETRAX_MMC_IOP
675 default MMC
676 select SPI
677 select MMC_SPI
678 select ETRAX_SPI_MMC_BOARD
679
680# For the parts that can't be a module (due to restrictions in
681# framework elsewhere).
682config ETRAX_SPI_MMC_BOARD
683 boolean
684 default n
685
686# While the board info is MMC_SPI only, the drivers are written to be
687# independent of MMC_SPI, so we'll keep SPI non-dependent on the
688# MMC_SPI config choices (well, except for a single depends-on-line
689# for the board-info file until a separate non-MMC SPI board file
690# emerges).
691# FIXME: When that happens, we'll need to be able to ask for and
692# configure non-MMC SPI ports together with MMC_SPI ports (if multiple
693# SPI ports are enabled).
694
695config SPI_ETRAX_SSER
696 tristate
697 depends on SPI_MASTER && ETRAX_ARCH_V32 && EXPERIMENTAL
698 select SPI_BITBANG
699 help
700 This enables using an synchronous serial (sser) port as a
701 SPI master controller on Axis ETRAX FS and later. The
702 driver can be configured to use any sser port.
703
704config SPI_ETRAX_GPIO
705 tristate
706 depends on SPI_MASTER && ETRAX_ARCH_V32 && EXPERIMENTAL
707 select SPI_BITBANG
708 help
709 This enables using GPIO pins port as a SPI master controller
710 on Axis ETRAX FS and later. The driver can be configured to
711 use any GPIO pins.
712
713config ETRAX_SPI_SSER0
714 tristate "SPI using synchronous serial port 0 (sser0)"
715 depends on ETRAX_SPI_MMC
716 default m if MMC_SPI=m
717 default y if MMC_SPI=y
718 default y if MMC_SPI=n
719 select SPI_ETRAX_SSER
720 help
721 Say Y for an MMC/SD socket connected to synchronous serial port 0,
722 or for devices using the SPI protocol on that port. Say m if you
723 want to build it as a module, which will be named spi_crisv32_sser.
724 (You need to select MMC separately.)
725
726config ETRAX_SPI_SSER0_DMA
727 bool "DMA for SPI on sser0 enabled"
728 depends on ETRAX_SPI_SSER0
729 depends on !ETRAX_SERIAL_PORT1_DMA4_OUT && !ETRAX_SERIAL_PORT1_DMA5_IN
730 default y
731 help
732 Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0.
733
734config ETRAX_SPI_MMC_CD_SSER0_PIN
735 string "MMC/SD card detect pin for SPI on sser0"
736 depends on ETRAX_SPI_SSER0 && MMC_SPI
737 default "pd11"
738 help
739 The pin to use for SD/MMC card detect. This pin should be pulled up
740 and grounded when a card is present. If defined as " " (space), no
741 pin is selected. A card must then always be inserted for proper
742 action.
743
744config ETRAX_SPI_MMC_WP_SSER0_PIN
745 string "MMC/SD card write-protect pin for SPI on sser0"
746 depends on ETRAX_SPI_SSER0 && MMC_SPI
747 default "pd10"
748 help
749 The pin to use for the SD/MMC write-protect signal for a memory
750 card. If defined as " " (space), the card is considered writable.
751
752config ETRAX_SPI_SSER1
753 tristate "SPI using synchronous serial port 1 (sser1)"
754 depends on ETRAX_SPI_MMC
755 default m if MMC_SPI=m && ETRAX_SPI_SSER0=n
756 default y if MMC_SPI=y && ETRAX_SPI_SSER0=n
757 default y if MMC_SPI=n && ETRAX_SPI_SSER0=n
758 select SPI_ETRAX_SSER
759 help
760 Say Y for an MMC/SD socket connected to synchronous serial port 1,
761 or for devices using the SPI protocol on that port. Say m if you
762 want to build it as a module, which will be named spi_crisv32_sser.
763 (You need to select MMC separately.)
764
765config ETRAX_SPI_SSER1_DMA
766 bool "DMA for SPI on sser1 enabled"
767 depends on ETRAX_SPI_SSER1 && !ETRAX_ETHERNET_IFACE1
768 depends on !ETRAX_SERIAL_PORT0_DMA6_OUT && !ETRAX_SERIAL_PORT0_DMA7_IN
769 default y
770 help
771 Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1.
772
773config ETRAX_SPI_MMC_CD_SSER1_PIN
774 string "MMC/SD card detect pin for SPI on sser1"
775 depends on ETRAX_SPI_SSER1 && MMC_SPI
776 default "pd12"
777 help
778 The pin to use for SD/MMC card detect. This pin should be pulled up
779 and grounded when a card is present. If defined as " " (space), no
780 pin is selected. A card must then always be inserted for proper
781 action.
782
783config ETRAX_SPI_MMC_WP_SSER1_PIN
784 string "MMC/SD card write-protect pin for SPI on sser1"
785 depends on ETRAX_SPI_SSER1 && MMC_SPI
786 default "pd9"
787 help
788 The pin to use for the SD/MMC write-protect signal for a memory
789 card. If defined as " " (space), the card is considered writable.
790
791config ETRAX_SPI_GPIO
792 tristate "Bitbanged SPI using gpio pins"
793 depends on ETRAX_SPI_MMC
794 select SPI_ETRAX_GPIO
795 default m if MMC_SPI=m && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
796 default y if MMC_SPI=y && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
797 default y if MMC_SPI=n && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
798 help
799 Say Y for an MMC/SD socket connected to general I/O pins (but not
800 a complete synchronous serial ports), or for devices using the SPI
801 protocol on general I/O pins. Slow and slows down the system.
802 Say m to build it as a module, which will be called spi_crisv32_gpio.
803 (You need to select MMC separately.)
804
805# The default match that of sser0, only because that's how it was tested.
806config ETRAX_SPI_CS_PIN
807 string "SPI chip select pin"
808 depends on ETRAX_SPI_GPIO
809 default "pc3"
810 help
811 The pin to use for SPI chip select.
812
813config ETRAX_SPI_CLK_PIN
814 string "SPI clock pin"
815 depends on ETRAX_SPI_GPIO
816 default "pc1"
817 help
818 The pin to use for the SPI clock.
819
820config ETRAX_SPI_DATAIN_PIN
821 string "SPI MISO (data in) pin"
822 depends on ETRAX_SPI_GPIO
823 default "pc16"
824 help
825 The pin to use for SPI data in from the device.
826
827config ETRAX_SPI_DATAOUT_PIN
828 string "SPI MOSI (data out) pin"
829 depends on ETRAX_SPI_GPIO
830 default "pc0"
831 help
832 The pin to use for SPI data out to the device.
833
834config ETRAX_SPI_MMC_CD_GPIO_PIN
835 string "MMC/SD card detect pin for SPI using gpio (space for none)"
836 depends on ETRAX_SPI_GPIO && MMC_SPI
837 default "pd11"
838 help
839 The pin to use for SD/MMC card detect. This pin should be pulled up
840 and grounded when a card is present. If defined as " " (space), no
841 pin is selected. A card must then always be inserted for proper
842 action.
843
844config ETRAX_SPI_MMC_WP_GPIO_PIN
845 string "MMC/SD card write-protect pin for SPI using gpio (space for none)"
846 depends on ETRAX_SPI_GPIO && MMC_SPI
847 default "pd10"
848 help
849 The pin to use for the SD/MMC write-protect signal for a memory
850 card. If defined as " " (space), the card is considered writable.
851
852# Avoid choices causing non-working configs by conditionalizing the inclusion.
853if ETRAX_SPI_MMC
854source drivers/spi/Kconfig
855endif
856
616endif 857endif
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile
index a359cd20ae75..e8c02437edaf 100644
--- a/arch/cris/arch-v32/drivers/Makefile
+++ b/arch/cris/arch-v32/drivers/Makefile
@@ -4,10 +4,11 @@
4 4
5obj-$(CONFIG_ETRAX_STREAMCOPROC) += cryptocop.o 5obj-$(CONFIG_ETRAX_STREAMCOPROC) += cryptocop.o
6obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o 6obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
7obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o 7obj-$(CONFIG_ETRAXFS) += mach-fs/
8obj-$(CONFIG_ETRAX_GPIO) += gpio.o 8obj-$(CONFIG_CRIS_MACH_ARTPEC3) += mach-a3/
9obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o 9obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o
10obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o 10obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o
11obj-$(CONFIG_ETRAX_I2C) += i2c.o 11obj-$(CONFIG_ETRAX_I2C) += i2c.o
12obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o 12obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
13obj-$(CONFIG_PCI) += pci/ 13obj-$(CONFIG_PCI) += pci/
14obj-$(CONFIG_ETRAX_SPI_MMC_BOARD) += board_mmcspi.o
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index c5ff95e18269..51e1e85df96d 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Physical mapping layer for MTD using the Axis partitiontable format 2 * Physical mapping layer for MTD using the Axis partitiontable format
3 * 3 *
4 * Copyright (c) 2001, 2002, 2003 Axis Communications AB 4 * Copyright (c) 2001-2007 Axis Communications AB
5 * 5 *
6 * This file is under the GPL. 6 * This file is under the GPL.
7 * 7 *
@@ -10,9 +10,6 @@
10 * tells us what other partitions to define. If there isn't, we use a default 10 * tells us what other partitions to define. If there isn't, we use a default
11 * partition split defined below. 11 * partition split defined below.
12 * 12 *
13 * Copy of os/lx25/arch/cris/arch-v10/drivers/axisflashmap.c 1.5
14 * with minor changes.
15 *
16 */ 13 */
17 14
18#include <linux/module.h> 15#include <linux/module.h>
@@ -27,7 +24,8 @@
27#include <linux/mtd/mtdram.h> 24#include <linux/mtd/mtdram.h>
28#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
29 26
30#include <asm/arch/hwregs/config_defs.h> 27#include <linux/cramfs_fs.h>
28
31#include <asm/axisflashmap.h> 29#include <asm/axisflashmap.h>
32#include <asm/mmu.h> 30#include <asm/mmu.h>
33 31
@@ -37,16 +35,24 @@
37#define FLASH_UNCACHED_ADDR KSEG_E 35#define FLASH_UNCACHED_ADDR KSEG_E
38#define FLASH_CACHED_ADDR KSEG_F 36#define FLASH_CACHED_ADDR KSEG_F
39 37
38#define PAGESIZE (512)
39
40#if CONFIG_ETRAX_FLASH_BUSWIDTH==1 40#if CONFIG_ETRAX_FLASH_BUSWIDTH==1
41#define flash_data __u8 41#define flash_data __u8
42#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 42#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
43#define flash_data __u16 43#define flash_data __u16
44#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 44#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
45#define flash_data __u16 45#define flash_data __u32
46#endif 46#endif
47 47
48/* From head.S */ 48/* From head.S */
49extern unsigned long romfs_start, romfs_length, romfs_in_flash; 49extern unsigned long romfs_in_flash; /* 1 when romfs_start, _length in flash */
50extern unsigned long romfs_start, romfs_length;
51extern unsigned long nand_boot; /* 1 when booted from nand flash */
52
53struct partition_name {
54 char name[6];
55};
50 56
51/* The master mtd for the entire flash. */ 57/* The master mtd for the entire flash. */
52struct mtd_info* axisflash_mtd = NULL; 58struct mtd_info* axisflash_mtd = NULL;
@@ -112,32 +118,20 @@ static struct map_info map_cse1 = {
112 .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE 118 .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
113}; 119};
114 120
115/* If no partition-table was found, we use this default-set. */ 121#define MAX_PARTITIONS 7
116#define MAX_PARTITIONS 7 122#ifdef CONFIG_ETRAX_NANDBOOT
117#define NUM_DEFAULT_PARTITIONS 3 123#define NUM_DEFAULT_PARTITIONS 4
124#define DEFAULT_ROOTFS_PARTITION_NO 2
125#define DEFAULT_MEDIA_SIZE 0x2000000 /* 32 megs */
126#else
127#define NUM_DEFAULT_PARTITIONS 3
128#define DEFAULT_ROOTFS_PARTITION_NO (-1)
129#define DEFAULT_MEDIA_SIZE 0x800000 /* 8 megs */
130#endif
118 131
119/* 132#if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS)
120 * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the 133#error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS
121 * size of one flash block and "filesystem"-partition needs 5 blocks to be able 134#endif
122 * to use JFFS.
123 */
124static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
125 {
126 .name = "boot firmware",
127 .size = CONFIG_ETRAX_PTABLE_SECTOR,
128 .offset = 0
129 },
130 {
131 .name = "kernel",
132 .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
133 .offset = CONFIG_ETRAX_PTABLE_SECTOR
134 },
135 {
136 .name = "filesystem",
137 .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
138 .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
139 }
140};
141 135
142/* Initialize the ones normally used. */ 136/* Initialize the ones normally used. */
143static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { 137static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
@@ -178,6 +172,56 @@ static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
178 }, 172 },
179}; 173};
180 174
175
176/* If no partition-table was found, we use this default-set.
177 * Default flash size is 8MB (NOR). CONFIG_ETRAX_PTABLE_SECTOR is most
178 * likely the size of one flash block and "filesystem"-partition needs
179 * to be >=5 blocks to be able to use JFFS.
180 */
181static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
182 {
183 .name = "boot firmware",
184 .size = CONFIG_ETRAX_PTABLE_SECTOR,
185 .offset = 0
186 },
187 {
188 .name = "kernel",
189 .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
190 .offset = CONFIG_ETRAX_PTABLE_SECTOR
191 },
192#define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR)
193#ifdef CONFIG_ETRAX_NANDBOOT
194 {
195 .name = "rootfs",
196 .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
197 .offset = FILESYSTEM_SECTOR
198 },
199#undef FILESYSTEM_SECTOR
200#define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR)
201#endif
202 {
203 .name = "rwfs",
204 .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR,
205 .offset = FILESYSTEM_SECTOR
206 }
207};
208
209#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
210/* Main flash device */
211static struct mtd_partition main_partition = {
212 .name = "main",
213 .size = 0,
214 .offset = 0
215};
216#endif
217
218/* Auxilliary partition if we find another flash */
219static struct mtd_partition aux_partition = {
220 .name = "aux",
221 .size = 0,
222 .offset = 0
223};
224
181/* 225/*
182 * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash 226 * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
183 * chips in that order (because the amd_flash-driver is faster). 227 * chips in that order (because the amd_flash-driver is faster).
@@ -191,7 +235,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
191 map_cs->name, map_cs->size, map_cs->map_priv_1); 235 map_cs->name, map_cs->size, map_cs->map_priv_1);
192 236
193#ifdef CONFIG_MTD_CFI 237#ifdef CONFIG_MTD_CFI
194 mtd_cs = do_map_probe("cfi_probe", map_cs); 238 mtd_cs = do_map_probe("cfi_probe", map_cs);
195#endif 239#endif
196#ifdef CONFIG_MTD_JEDECPROBE 240#ifdef CONFIG_MTD_JEDECPROBE
197 if (!mtd_cs) 241 if (!mtd_cs)
@@ -204,7 +248,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
204/* 248/*
205 * Probe each chip select individually for flash chips. If there are chips on 249 * Probe each chip select individually for flash chips. If there are chips on
206 * both cse0 and cse1, the mtd_info structs will be concatenated to one struct 250 * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
207 * so that MTD partitions can cross chip boundaries. 251 * so that MTD partitions can cross chip boundries.
208 * 252 *
209 * The only known restriction to how you can mount your chips is that each 253 * The only known restriction to how you can mount your chips is that each
210 * chip select must hold similar flash chips. But you need external hardware 254 * chip select must hold similar flash chips. But you need external hardware
@@ -216,9 +260,8 @@ static struct mtd_info *flash_probe(void)
216{ 260{
217 struct mtd_info *mtd_cse0; 261 struct mtd_info *mtd_cse0;
218 struct mtd_info *mtd_cse1; 262 struct mtd_info *mtd_cse1;
219 struct mtd_info *mtd_nand = NULL;
220 struct mtd_info *mtd_total; 263 struct mtd_info *mtd_total;
221 struct mtd_info *mtds[3]; 264 struct mtd_info *mtds[2];
222 int count = 0; 265 int count = 0;
223 266
224 if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL) 267 if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL)
@@ -226,12 +269,7 @@ static struct mtd_info *flash_probe(void)
226 if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL) 269 if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL)
227 mtds[count++] = mtd_cse1; 270 mtds[count++] = mtd_cse1;
228 271
229#ifdef CONFIG_ETRAX_NANDFLASH 272 if (!mtd_cse0 && !mtd_cse1) {
230 if ((mtd_nand = crisv32_nand_flash_probe()) != NULL)
231 mtds[count++] = mtd_nand;
232#endif
233
234 if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) {
235 /* No chip found. */ 273 /* No chip found. */
236 return NULL; 274 return NULL;
237 } 275 }
@@ -245,9 +283,7 @@ static struct mtd_info *flash_probe(void)
245 * So we use the MTD concatenation layer instead of further 283 * So we use the MTD concatenation layer instead of further
246 * complicating the probing procedure. 284 * complicating the probing procedure.
247 */ 285 */
248 mtd_total = mtd_concat_create(mtds, 286 mtd_total = mtd_concat_create(mtds, count, "cse0+cse1");
249 count,
250 "cse0+cse1+nand");
251#else 287#else
252 printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " 288 printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "
253 "(mis)configuration!\n", map_cse0.name, map_cse1.name); 289 "(mis)configuration!\n", map_cse0.name, map_cse1.name);
@@ -255,61 +291,162 @@ static struct mtd_info *flash_probe(void)
255#endif 291#endif
256 if (!mtd_total) { 292 if (!mtd_total) {
257 printk(KERN_ERR "%s and %s: Concatenation failed!\n", 293 printk(KERN_ERR "%s and %s: Concatenation failed!\n",
258 map_cse0.name, map_cse1.name); 294 map_cse0.name, map_cse1.name);
259 295
260 /* The best we can do now is to only use what we found 296 /* The best we can do now is to only use what we found
261 * at cse0. 297 * at cse0. */
262 */
263 mtd_total = mtd_cse0; 298 mtd_total = mtd_cse0;
264 map_destroy(mtd_cse1); 299 map_destroy(mtd_cse1);
265 } 300 }
266 } else { 301 } else
267 mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand; 302 mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1;
268
269 }
270 303
271 return mtd_total; 304 return mtd_total;
272} 305}
273 306
274extern unsigned long crisv32_nand_boot;
275extern unsigned long crisv32_nand_cramfs_offset;
276
277/* 307/*
278 * Probe the flash chip(s) and, if it succeeds, read the partition-table 308 * Probe the flash chip(s) and, if it succeeds, read the partition-table
279 * and register the partitions with MTD. 309 * and register the partitions with MTD.
280 */ 310 */
281static int __init init_axis_flash(void) 311static int __init init_axis_flash(void)
282{ 312{
283 struct mtd_info *mymtd; 313 struct mtd_info *main_mtd;
314 struct mtd_info *aux_mtd = NULL;
284 int err = 0; 315 int err = 0;
285 int pidx = 0; 316 int pidx = 0;
286 struct partitiontable_head *ptable_head = NULL; 317 struct partitiontable_head *ptable_head = NULL;
287 struct partitiontable_entry *ptable; 318 struct partitiontable_entry *ptable;
288 int use_default_ptable = 1; /* Until proven otherwise. */ 319 int ptable_ok = 0;
289 const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; 320 static char page[PAGESIZE];
290 static char page[512];
291 size_t len; 321 size_t len;
322 int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */
323 int part;
324
325 /* We need a root fs. If it resides in RAM, we need to use an
326 * MTDRAM device, so it must be enabled in the kernel config,
327 * but its size must be configured as 0 so as not to conflict
328 * with our usage.
329 */
330#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
331 if (!romfs_in_flash && !nand_boot) {
332 printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
333 "device; configure CONFIG_MTD_MTDRAM with size = 0!\n");
334 panic("This kernel cannot boot from RAM!\n");
335 }
336#endif
337
338#ifndef CONFIG_ETRAX_VCS_SIM
339 main_mtd = flash_probe();
340 if (main_mtd)
341 printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n",
342 main_mtd->name, main_mtd->size);
343
344#ifdef CONFIG_ETRAX_NANDFLASH
345 aux_mtd = crisv32_nand_flash_probe();
346 if (aux_mtd)
347 printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n",
348 aux_mtd->name, aux_mtd->size);
349
350#ifdef CONFIG_ETRAX_NANDBOOT
351 {
352 struct mtd_info *tmp_mtd;
292 353
293#ifndef CONFIG_ETRAXFS_SIM 354 printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, "
294 mymtd = flash_probe(); 355 "making NAND flash primary device.\n");
295 mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page); 356 tmp_mtd = main_mtd;
296 ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET); 357 main_mtd = aux_mtd;
358 aux_mtd = tmp_mtd;
359 }
360#endif /* CONFIG_ETRAX_NANDBOOT */
361#endif /* CONFIG_ETRAX_NANDFLASH */
297 362
298 if (!mymtd) { 363 if (!main_mtd && !aux_mtd) {
299 /* There's no reason to use this module if no flash chip can 364 /* There's no reason to use this module if no flash chip can
300 * be identified. Make sure that's understood. 365 * be identified. Make sure that's understood.
301 */ 366 */
302 printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); 367 printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
303 } else {
304 printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
305 mymtd->name, mymtd->size);
306 axisflash_mtd = mymtd;
307 } 368 }
308 369
309 if (mymtd) { 370#if 0 /* Dump flash memory so we can see what is going on */
310 mymtd->owner = THIS_MODULE; 371 if (main_mtd) {
372 int sectoraddr, i;
373 for (sectoraddr = 0; sectoraddr < 2*65536+4096;
374 sectoraddr += PAGESIZE) {
375 main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len,
376 page);
377 printk(KERN_INFO
378 "Sector at %d (length %d):\n",
379 sectoraddr, len);
380 for (i = 0; i < PAGESIZE; i += 16) {
381 printk(KERN_INFO
382 "%02x %02x %02x %02x "
383 "%02x %02x %02x %02x "
384 "%02x %02x %02x %02x "
385 "%02x %02x %02x %02x\n",
386 page[i] & 255, page[i+1] & 255,
387 page[i+2] & 255, page[i+3] & 255,
388 page[i+4] & 255, page[i+5] & 255,
389 page[i+6] & 255, page[i+7] & 255,
390 page[i+8] & 255, page[i+9] & 255,
391 page[i+10] & 255, page[i+11] & 255,
392 page[i+12] & 255, page[i+13] & 255,
393 page[i+14] & 255, page[i+15] & 255);
394 }
395 }
396 }
397#endif
398
399 if (main_mtd) {
400 main_mtd->owner = THIS_MODULE;
401 axisflash_mtd = main_mtd;
402
403 loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR;
404
405 /* First partition (rescue) is always set to the default. */
406 pidx++;
407#ifdef CONFIG_ETRAX_NANDBOOT
408 /* We know where the partition table should be located,
409 * it will be in first good block after that.
410 */
411 int blockstat;
412 do {
413 blockstat = main_mtd->block_isbad(main_mtd,
414 ptable_sector);
415 if (blockstat < 0)
416 ptable_sector = 0; /* read error */
417 else if (blockstat)
418 ptable_sector += main_mtd->erasesize;
419 } while (blockstat && ptable_sector);
420#endif
421 if (ptable_sector) {
422 main_mtd->read(main_mtd, ptable_sector, PAGESIZE,
423 &len, page);
424 ptable_head = &((struct partitiontable *) page)->head;
425 }
426
427#if 0 /* Dump partition table so we can see what is going on */
428 printk(KERN_INFO
429 "axisflashmap: flash read %d bytes at 0x%08x, data: "
430 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
431 len, CONFIG_ETRAX_PTABLE_SECTOR,
432 page[0] & 255, page[1] & 255,
433 page[2] & 255, page[3] & 255,
434 page[4] & 255, page[5] & 255,
435 page[6] & 255, page[7] & 255);
436 printk(KERN_INFO
437 "axisflashmap: partition table offset %d, data: "
438 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
439 PARTITION_TABLE_OFFSET,
440 page[PARTITION_TABLE_OFFSET+0] & 255,
441 page[PARTITION_TABLE_OFFSET+1] & 255,
442 page[PARTITION_TABLE_OFFSET+2] & 255,
443 page[PARTITION_TABLE_OFFSET+3] & 255,
444 page[PARTITION_TABLE_OFFSET+4] & 255,
445 page[PARTITION_TABLE_OFFSET+5] & 255,
446 page[PARTITION_TABLE_OFFSET+6] & 255,
447 page[PARTITION_TABLE_OFFSET+7] & 255);
448#endif
311 } 449 }
312 pidx++; /* First partition is always set to the default. */
313 450
314 if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) 451 if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
315 && (ptable_head->size < 452 && (ptable_head->size <
@@ -322,7 +459,6 @@ static int __init init_axis_flash(void)
322 /* Looks like a start, sane length and end of a 459 /* Looks like a start, sane length and end of a
323 * partition table, lets check csum etc. 460 * partition table, lets check csum etc.
324 */ 461 */
325 int ptable_ok = 0;
326 struct partitiontable_entry *max_addr = 462 struct partitiontable_entry *max_addr =
327 (struct partitiontable_entry *) 463 (struct partitiontable_entry *)
328 ((unsigned long)ptable_head + sizeof(*ptable_head) + 464 ((unsigned long)ptable_head + sizeof(*ptable_head) +
@@ -346,104 +482,170 @@ static int __init init_axis_flash(void)
346 ptable_ok = (csum == ptable_head->checksum); 482 ptable_ok = (csum == ptable_head->checksum);
347 483
348 /* Read the entries and use/show the info. */ 484 /* Read the entries and use/show the info. */
349 printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", 485 printk(KERN_INFO "axisflashmap: "
486 "Found a%s partition table at 0x%p-0x%p.\n",
350 (ptable_ok ? " valid" : "n invalid"), ptable_head, 487 (ptable_ok ? " valid" : "n invalid"), ptable_head,
351 max_addr); 488 max_addr);
352 489
353 /* We have found a working bootblock. Now read the 490 /* We have found a working bootblock. Now read the
354 * partition table. Scan the table. It ends when 491 * partition table. Scan the table. It ends with 0xffffffff.
355 * there is 0xffffffff, that is, empty flash.
356 */ 492 */
357 while (ptable_ok 493 while (ptable_ok
358 && ptable->offset != 0xffffffff 494 && ptable->offset != PARTITIONTABLE_END_MARKER
359 && ptable < max_addr 495 && ptable < max_addr
360 && pidx < MAX_PARTITIONS) { 496 && pidx < MAX_PARTITIONS - 1) {
361 497
362 axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0); 498 axis_partitions[pidx].offset = offset + ptable->offset;
363 axis_partitions[pidx].size = ptable->size; 499#ifdef CONFIG_ETRAX_NANDFLASH
364 500 if (main_mtd->type == MTD_NANDFLASH) {
365 printk(pmsg, pidx, axis_partitions[pidx].offset, 501 axis_partitions[pidx].size =
366 axis_partitions[pidx].size); 502 (((ptable+1)->offset ==
503 PARTITIONTABLE_END_MARKER) ?
504 main_mtd->size :
505 ((ptable+1)->offset + offset)) -
506 (ptable->offset + offset);
507
508 } else
509#endif /* CONFIG_ETRAX_NANDFLASH */
510 axis_partitions[pidx].size = ptable->size;
511#ifdef CONFIG_ETRAX_NANDBOOT
512 /* Save partition number of jffs2 ro partition.
513 * Needed if RAM booting or root file system in RAM.
514 */
515 if (!nand_boot &&
516 ram_rootfs_partition < 0 && /* not already set */
517 ptable->type == PARTITION_TYPE_JFFS2 &&
518 (ptable->flags & PARTITION_FLAGS_READONLY_MASK) ==
519 PARTITION_FLAGS_READONLY)
520 ram_rootfs_partition = pidx;
521#endif /* CONFIG_ETRAX_NANDBOOT */
367 pidx++; 522 pidx++;
368 ptable++; 523 ptable++;
369 } 524 }
370 use_default_ptable = !ptable_ok;
371 } 525 }
372 526
373 if (romfs_in_flash) { 527 /* Decide whether to use default partition table. */
374 /* Add an overlapping device for the root partition (romfs). */ 528 /* Only use default table if we actually have a device (main_mtd) */
375 529
376 axis_partitions[pidx].name = "romfs"; 530 struct mtd_partition *partition = &axis_partitions[0];
377 if (crisv32_nand_boot) { 531 if (main_mtd && !ptable_ok) {
378 char* data = kmalloc(1024, GFP_KERNEL); 532 memcpy(axis_partitions, axis_default_partitions,
379 int len; 533 sizeof(axis_default_partitions));
380 int offset = crisv32_nand_cramfs_offset & ~(1024-1); 534 pidx = NUM_DEFAULT_PARTITIONS;
381 char* tmp; 535 ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO;
382 536 }
383 mymtd->read(mymtd, offset, 1024, &len, data);
384 tmp = &data[crisv32_nand_cramfs_offset % 512];
385 axis_partitions[pidx].size = *(unsigned*)(tmp + 4);
386 axis_partitions[pidx].offset = crisv32_nand_cramfs_offset;
387 kfree(data);
388 } else {
389 axis_partitions[pidx].size = romfs_length;
390 axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
391 }
392 537
538 /* Add artificial partitions for rootfs if necessary */
539 if (romfs_in_flash) {
540 /* rootfs is in directly accessible flash memory = NOR flash.
541 Add an overlapping device for the rootfs partition. */
542 printk(KERN_INFO "axisflashmap: Adding partition for "
543 "overlapping root file system image\n");
544 axis_partitions[pidx].size = romfs_length;
545 axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
546 axis_partitions[pidx].name = "romfs";
393 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; 547 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
394 548 ram_rootfs_partition = -1;
395 printk(KERN_INFO
396 " Adding readonly flash partition for romfs image:\n");
397 printk(pmsg, pidx, axis_partitions[pidx].offset,
398 axis_partitions[pidx].size);
399 pidx++; 549 pidx++;
400 } 550 } else if (romfs_length && !nand_boot) {
401 551 /* romfs exists in memory, but not in flash, so must be in RAM.
402 if (mymtd) { 552 * Configure an MTDRAM partition. */
403 if (use_default_ptable) { 553 if (ram_rootfs_partition < 0) {
404 printk(KERN_INFO " Using default partition table.\n"); 554 /* None set yet, put it at the end */
405 err = add_mtd_partitions(mymtd, axis_default_partitions, 555 ram_rootfs_partition = pidx;
406 NUM_DEFAULT_PARTITIONS); 556 pidx++;
407 } else {
408 err = add_mtd_partitions(mymtd, axis_partitions, pidx);
409 } 557 }
558 printk(KERN_INFO "axisflashmap: Adding partition for "
559 "root file system image in RAM\n");
560 axis_partitions[ram_rootfs_partition].size = romfs_length;
561 axis_partitions[ram_rootfs_partition].offset = romfs_start;
562 axis_partitions[ram_rootfs_partition].name = "romfs";
563 axis_partitions[ram_rootfs_partition].mask_flags |=
564 MTD_WRITEABLE;
565 }
410 566
411 if (err) { 567#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
412 panic("axisflashmap could not add MTD partitions!\n"); 568 if (main_mtd) {
413 } 569 main_partition.size = main_mtd->size;
570 err = add_mtd_partitions(main_mtd, &main_partition, 1);
571 if (err)
572 panic("axisflashmap: Could not initialize "
573 "partition for whole main mtd device!\n");
414 } 574 }
415/* CONFIG_EXTRAXFS_SIM */
416#endif 575#endif
417 576
418 if (!romfs_in_flash) { 577 /* Now, register all partitions with mtd.
419 /* Create an RAM device for the root partition (romfs). */ 578 * We do this one at a time so we can slip in an MTDRAM device
579 * in the proper place if required. */
580
581 for (part = 0; part < pidx; part++) {
582 if (part == ram_rootfs_partition) {
583 /* add MTDRAM partition here */
584 struct mtd_info *mtd_ram;
585
586 mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
587 if (!mtd_ram)
588 panic("axisflashmap: Couldn't allocate memory "
589 "for mtd_info!\n");
590 printk(KERN_INFO "axisflashmap: Adding RAM partition "
591 "for rootfs image.\n");
592 err = mtdram_init_device(mtd_ram,
593 (void *)partition[part].offset,
594 partition[part].size,
595 partition[part].name);
596 if (err)
597 panic("axisflashmap: Could not initialize "
598 "MTD RAM device!\n");
599 /* JFFS2 likes to have an erasesize. Keep potential
600 * JFFS2 rootfs happy by providing one. Since image
601 * was most likely created for main mtd, use that
602 * erasesize, if available. Otherwise, make a guess. */
603 mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize :
604 CONFIG_ETRAX_PTABLE_SECTOR);
605 } else {
606 err = add_mtd_partitions(main_mtd, &partition[part], 1);
607 if (err)
608 panic("axisflashmap: Could not add mtd "
609 "partition %d\n", part);
610 }
611 }
612#endif /* CONFIG_EXTRAX_VCS_SIM */
613
614#ifdef CONFIG_ETRAX_VCS_SIM
615 /* For simulator, always use a RAM partition.
616 * The rootfs will be found after the kernel in RAM,
617 * with romfs_start and romfs_end indicating location and size.
618 */
619 struct mtd_info *mtd_ram;
620
621 mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
622 if (!mtd_ram) {
623 panic("axisflashmap: Couldn't allocate memory for "
624 "mtd_info!\n");
625 }
420 626
421#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) 627 printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, "
422 /* No use trying to boot this kernel from RAM. Panic! */ 628 "at %u, size %u\n",
423 printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " 629 (unsigned) romfs_start, (unsigned) romfs_length);
424 "device due to kernel (mis)configuration!\n");
425 panic("This kernel cannot boot from RAM!\n");
426#else
427 struct mtd_info *mtd_ram;
428 630
429 mtd_ram = kmalloc(sizeof(struct mtd_info), 631 err = mtdram_init_device(mtd_ram, (void *)romfs_start,
430 GFP_KERNEL); 632 romfs_length, "romfs");
431 if (!mtd_ram) { 633 if (err) {
432 panic("axisflashmap couldn't allocate memory for " 634 panic("axisflashmap: Could not initialize MTD RAM "
433 "mtd_info!\n"); 635 "device!\n");
434 } 636 }
637#endif /* CONFIG_EXTRAX_VCS_SIM */
435 638
436 printk(KERN_INFO " Adding RAM partition for romfs image:\n"); 639#ifndef CONFIG_ETRAX_VCS_SIM
437 printk(pmsg, pidx, romfs_start, romfs_length); 640 if (aux_mtd) {
641 aux_partition.size = aux_mtd->size;
642 err = add_mtd_partitions(aux_mtd, &aux_partition, 1);
643 if (err)
644 panic("axisflashmap: Could not initialize "
645 "aux mtd device!\n");
438 646
439 err = mtdram_init_device(mtd_ram, (void*)romfs_start,
440 romfs_length, "romfs");
441 if (err) {
442 panic("axisflashmap could not initialize MTD RAM "
443 "device!\n");
444 }
445#endif
446 } 647 }
648#endif /* CONFIG_EXTRAX_VCS_SIM */
447 649
448 return err; 650 return err;
449} 651}
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index e8914d401696..9fb58202be99 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -1,8 +1,7 @@
1/* $Id: cryptocop.c,v 1.13 2005/04/21 17:27:55 henriken Exp $ 1/*
2 *
3 * Stream co-processor driver for the ETRAX FS 2 * Stream co-processor driver for the ETRAX FS
4 * 3 *
5 * Copyright (C) 2003-2005 Axis Communications AB 4 * Copyright (C) 2003-2007 Axis Communications AB
6 */ 5 */
7 6
8#include <linux/init.h> 7#include <linux/init.h>
@@ -25,17 +24,29 @@
25#include <asm/signal.h> 24#include <asm/signal.h>
26#include <asm/irq.h> 25#include <asm/irq.h>
27 26
28#include <asm/arch/dma.h> 27#include <dma.h>
29#include <asm/arch/hwregs/dma.h> 28#include <hwregs/dma.h>
30#include <asm/arch/hwregs/reg_map.h> 29#include <hwregs/reg_map.h>
31#include <asm/arch/hwregs/reg_rdwr.h> 30#include <hwregs/reg_rdwr.h>
32#include <asm/arch/hwregs/intr_vect_defs.h> 31#include <hwregs/intr_vect_defs.h>
33 32
34#include <asm/arch/hwregs/strcop.h> 33#include <hwregs/strcop.h>
35#include <asm/arch/hwregs/strcop_defs.h> 34#include <hwregs/strcop_defs.h>
36#include <asm/arch/cryptocop.h> 35#include <cryptocop.h>
37 36
38 37#ifdef CONFIG_ETRAXFS
38#define IN_DMA 9
39#define OUT_DMA 8
40#define IN_DMA_INST regi_dma9
41#define OUT_DMA_INST regi_dma8
42#define DMA_IRQ DMA9_INTR_VECT
43#else
44#define IN_DMA 3
45#define OUT_DMA 2
46#define IN_DMA_INST regi_dma3
47#define OUT_DMA_INST regi_dma2
48#define DMA_IRQ DMA3_INTR_VECT
49#endif
39 50
40#define DESCR_ALLOC_PAD (31) 51#define DESCR_ALLOC_PAD (31)
41 52
@@ -1886,14 +1897,14 @@ static void cryptocop_do_tasklet(unsigned long unused)
1886} 1897}
1887 1898
1888static irqreturn_t 1899static irqreturn_t
1889dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs) 1900dma_done_interrupt(int irq, void *dev_id)
1890{ 1901{
1891 struct cryptocop_prio_job *done_job; 1902 struct cryptocop_prio_job *done_job;
1892 reg_dma_rw_ack_intr ack_intr = { 1903 reg_dma_rw_ack_intr ack_intr = {
1893 .data = 1, 1904 .data = 1,
1894 }; 1905 };
1895 1906
1896 REG_WR (dma, regi_dma9, rw_ack_intr, ack_intr); 1907 REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr);
1897 1908
1898 DEBUG(printk("cryptocop DMA done\n")); 1909 DEBUG(printk("cryptocop DMA done\n"));
1899 1910
@@ -1937,7 +1948,6 @@ dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1937static int init_cryptocop(void) 1948static int init_cryptocop(void)
1938{ 1949{
1939 unsigned long flags; 1950 unsigned long flags;
1940 reg_intr_vect_rw_mask intr_mask;
1941 reg_dma_rw_cfg dma_cfg = {.en = 1}; 1951 reg_dma_rw_cfg dma_cfg = {.en = 1};
1942 reg_dma_rw_intr_mask intr_mask_in = {.data = regk_dma_yes}; /* Only want descriptor interrupts from the DMA in channel. */ 1952 reg_dma_rw_intr_mask intr_mask_in = {.data = regk_dma_yes}; /* Only want descriptor interrupts from the DMA in channel. */
1943 reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; 1953 reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 };
@@ -1950,10 +1960,14 @@ static int init_cryptocop(void)
1950 .en = 1 1960 .en = 1
1951 }; 1961 };
1952 1962
1953 if (request_irq(DMA9_INTR_VECT, dma_done_interrupt, 0, "stream co-processor DMA", NULL)) panic("request_irq stream co-processor irq dma9"); 1963 if (request_irq(DMA_IRQ, dma_done_interrupt, 0,
1964 "stream co-processor DMA", NULL))
1965 panic("request_irq stream co-processor irq dma9");
1954 1966
1955 (void)crisv32_request_dma(8, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp); 1967 (void)crisv32_request_dma(OUT_DMA, "strcop", DMA_PANIC_ON_ERROR,
1956 (void)crisv32_request_dma(9, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp); 1968 0, dma_strp);
1969 (void)crisv32_request_dma(IN_DMA, "strcop", DMA_PANIC_ON_ERROR,
1970 0, dma_strp);
1957 1971
1958 local_irq_save(flags); 1972 local_irq_save(flags);
1959 1973
@@ -1963,24 +1977,19 @@ static int init_cryptocop(void)
1963 strcop_cfg.en = 1; 1977 strcop_cfg.en = 1;
1964 REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg); 1978 REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg);
1965 1979
1966 /* Enable DMA9 interrupt */
1967 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
1968 intr_mask.dma9 = 1;
1969 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
1970
1971 /* Enable DMAs. */ 1980 /* Enable DMAs. */
1972 REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */ 1981 REG_WR(dma, IN_DMA_INST, rw_cfg, dma_cfg); /* input DMA */
1973 REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */ 1982 REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_cfg); /* output DMA */
1974 1983
1975 /* Set up wordsize = 4 for DMAs. */ 1984 /* Set up wordsize = 4 for DMAs. */
1976 DMA_WR_CMD (regi_dma8, regk_dma_set_w_size4); 1985 DMA_WR_CMD(OUT_DMA_INST, regk_dma_set_w_size4);
1977 DMA_WR_CMD (regi_dma9, regk_dma_set_w_size4); 1986 DMA_WR_CMD(IN_DMA_INST, regk_dma_set_w_size4);
1978 1987
1979 /* Enable interrupts. */ 1988 /* Enable interrupts. */
1980 REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in); 1989 REG_WR(dma, IN_DMA_INST, rw_intr_mask, intr_mask_in);
1981 1990
1982 /* Clear intr ack. */ 1991 /* Clear intr ack. */
1983 REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr); 1992 REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr);
1984 1993
1985 local_irq_restore(flags); 1994 local_irq_restore(flags);
1986 1995
@@ -1991,7 +2000,6 @@ static int init_cryptocop(void)
1991static void release_cryptocop(void) 2000static void release_cryptocop(void)
1992{ 2001{
1993 unsigned long flags; 2002 unsigned long flags;
1994 reg_intr_vect_rw_mask intr_mask;
1995 reg_dma_rw_cfg dma_cfg = {.en = 0}; 2003 reg_dma_rw_cfg dma_cfg = {.en = 0};
1996 reg_dma_rw_intr_mask intr_mask_in = {0}; 2004 reg_dma_rw_intr_mask intr_mask_in = {0};
1997 reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; 2005 reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 };
@@ -1999,26 +2007,21 @@ static void release_cryptocop(void)
1999 local_irq_save(flags); 2007 local_irq_save(flags);
2000 2008
2001 /* Clear intr ack. */ 2009 /* Clear intr ack. */
2002 REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr); 2010 REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr);
2003
2004 /* Disable DMA9 interrupt */
2005 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
2006 intr_mask.dma9 = 0;
2007 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
2008 2011
2009 /* Disable DMAs. */ 2012 /* Disable DMAs. */
2010 REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */ 2013 REG_WR(dma, IN_DMA_INST, rw_cfg, dma_cfg); /* input DMA */
2011 REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */ 2014 REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_cfg); /* output DMA */
2012 2015
2013 /* Disable interrupts. */ 2016 /* Disable interrupts. */
2014 REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in); 2017 REG_WR(dma, IN_DMA_INST, rw_intr_mask, intr_mask_in);
2015 2018
2016 local_irq_restore(flags); 2019 local_irq_restore(flags);
2017 2020
2018 free_irq(DMA9_INTR_VECT, NULL); 2021 free_irq(DMA_IRQ, NULL);
2019 2022
2020 (void)crisv32_free_dma(8); 2023 (void)crisv32_free_dma(OUT_DMA);
2021 (void)crisv32_free_dma(9); 2024 (void)crisv32_free_dma(IN_DMA);
2022} 2025}
2023 2026
2024 2027
@@ -2076,13 +2079,13 @@ static void cryptocop_job_queue_close(void)
2076 reg_dma_rw_cfg dma_out_cfg, dma_in_cfg; 2079 reg_dma_rw_cfg dma_out_cfg, dma_in_cfg;
2077 2080
2078 /* Stop DMA. */ 2081 /* Stop DMA. */
2079 dma_out_cfg = REG_RD(dma, regi_dma8, rw_cfg); 2082 dma_out_cfg = REG_RD(dma, OUT_DMA_INST, rw_cfg);
2080 dma_out_cfg.en = regk_dma_no; 2083 dma_out_cfg.en = regk_dma_no;
2081 REG_WR(dma, regi_dma8, rw_cfg, dma_out_cfg); 2084 REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_out_cfg);
2082 2085
2083 dma_in_cfg = REG_RD(dma, regi_dma9, rw_cfg); 2086 dma_in_cfg = REG_RD(dma, IN_DMA_INST, rw_cfg);
2084 dma_in_cfg.en = regk_dma_no; 2087 dma_in_cfg.en = regk_dma_no;
2085 REG_WR(dma, regi_dma9, rw_cfg, dma_in_cfg); 2088 REG_WR(dma, IN_DMA_INST, rw_cfg, dma_in_cfg);
2086 2089
2087 /* Disble the cryptocop. */ 2090 /* Disble the cryptocop. */
2088 rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg); 2091 rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg);
@@ -2226,10 +2229,11 @@ static void cryptocop_start_job(void)
2226 &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out))); 2229 &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out)));
2227 2230
2228 /* Start input DMA. */ 2231 /* Start input DMA. */
2229 DMA_START_CONTEXT(regi_dma9, virt_to_phys(&pj->iop->ctx_in)); 2232 flush_dma_context(&pj->iop->ctx_in);
2233 DMA_START_CONTEXT(IN_DMA_INST, virt_to_phys(&pj->iop->ctx_in));
2230 2234
2231 /* Start output DMA. */ 2235 /* Start output DMA. */
2232 DMA_START_CONTEXT(regi_dma8, virt_to_phys(&pj->iop->ctx_out)); 2236 DMA_START_CONTEXT(OUT_DMA_INST, virt_to_phys(&pj->iop->ctx_out));
2233 2237
2234 spin_unlock_irqrestore(&running_job_lock, running_job_flags); 2238 spin_unlock_irqrestore(&running_job_lock, running_job_flags);
2235 DEBUG(printk("cryptocop_start_job: exiting\n")); 2239 DEBUG(printk("cryptocop_start_job: exiting\n"));
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index f1edd2e359b2..c2fb7a5c1396 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -19,10 +19,10 @@
19*! 19*!
20*! --------------------------------------------------------------------------- 20*! ---------------------------------------------------------------------------
21*! 21*!
22*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN 22*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
23*! 23*!
24*!***************************************************************************/ 24*!***************************************************************************/
25/* $Id: i2c.c,v 1.2 2005/05/09 15:29:49 starvik Exp $ */ 25
26/****************** INCLUDE FILES SECTION ***********************************/ 26/****************** INCLUDE FILES SECTION ***********************************/
27 27
28#include <linux/module.h> 28#include <linux/module.h>
@@ -79,6 +79,8 @@ static const char i2c_name[] = "i2c";
79 79
80#define i2c_delay(usecs) udelay(usecs) 80#define i2c_delay(usecs) udelay(usecs)
81 81
82static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
83
82/****************** VARIABLE SECTION ************************************/ 84/****************** VARIABLE SECTION ************************************/
83 85
84static struct crisv32_iopin cris_i2c_clk; 86static struct crisv32_iopin cris_i2c_clk;
@@ -252,6 +254,7 @@ i2c_getack(void)
252 * generate ACK clock pulse 254 * generate ACK clock pulse
253 */ 255 */
254 i2c_clk(I2C_CLOCK_HIGH); 256 i2c_clk(I2C_CLOCK_HIGH);
257#if 0
255 /* 258 /*
256 * Use PORT PB instead of I2C 259 * Use PORT PB instead of I2C
257 * for input. (I2C not working) 260 * for input. (I2C not working)
@@ -264,6 +267,8 @@ i2c_getack(void)
264 i2c_data(1); 267 i2c_data(1);
265 i2c_disable(); 268 i2c_disable();
266 i2c_dir_in(); 269 i2c_dir_in();
270#endif
271
267 /* 272 /*
268 * now wait for ack 273 * now wait for ack
269 */ 274 */
@@ -271,11 +276,11 @@ i2c_getack(void)
271 /* 276 /*
272 * check for ack 277 * check for ack
273 */ 278 */
274 if(i2c_getbit()) 279 if (i2c_getbit())
275 ack = 0; 280 ack = 0;
276 i2c_delay(CLOCK_HIGH_TIME/2); 281 i2c_delay(CLOCK_HIGH_TIME/2);
277 if(!ack){ 282 if (!ack) {
278 if(!i2c_getbit()) /* receiver pulled SDA low */ 283 if (!i2c_getbit()) /* receiver pulld SDA low */
279 ack = 1; 284 ack = 1;
280 i2c_delay(CLOCK_HIGH_TIME/2); 285 i2c_delay(CLOCK_HIGH_TIME/2);
281 } 286 }
@@ -285,6 +290,7 @@ i2c_getack(void)
285 * before we enable our output. If we keep data high 290 * before we enable our output. If we keep data high
286 * and enable output, we would generate a stop condition. 291 * and enable output, we would generate a stop condition.
287 */ 292 */
293#if 0
288 i2c_data(I2C_DATA_LOW); 294 i2c_data(I2C_DATA_LOW);
289 295
290 /* 296 /*
@@ -292,6 +298,7 @@ i2c_getack(void)
292 */ 298 */
293 i2c_enable(); 299 i2c_enable();
294 i2c_dir_out(); 300 i2c_dir_out();
301#endif
295 i2c_clk(I2C_CLOCK_LOW); 302 i2c_clk(I2C_CLOCK_LOW);
296 i2c_delay(CLOCK_HIGH_TIME/4); 303 i2c_delay(CLOCK_HIGH_TIME/4);
297 /* 304 /*
@@ -375,6 +382,121 @@ i2c_sendnack(void)
375 382
376/*#--------------------------------------------------------------------------- 383/*#---------------------------------------------------------------------------
377*# 384*#
385*# FUNCTION NAME: i2c_write
386*#
387*# DESCRIPTION : Writes a value to an I2C device
388*#
389*#--------------------------------------------------------------------------*/
390int
391i2c_write(unsigned char theSlave, void *data, size_t nbytes)
392{
393 int error, cntr = 3;
394 unsigned char bytes_wrote = 0;
395 unsigned char value;
396 unsigned long flags;
397
398 spin_lock_irqsave(&i2c_lock, flags);
399
400 do {
401 error = 0;
402
403 i2c_start();
404 /*
405 * send slave address
406 */
407 i2c_outbyte((theSlave & 0xfe));
408 /*
409 * wait for ack
410 */
411 if (!i2c_getack())
412 error = 1;
413 /*
414 * send data
415 */
416 for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) {
417 memcpy(&value, data + bytes_wrote, sizeof value);
418 i2c_outbyte(value);
419 /*
420 * now it's time to wait for ack
421 */
422 if (!i2c_getack())
423 error |= 4;
424 }
425 /*
426 * end byte stream
427 */
428 i2c_stop();
429
430 } while (error && cntr--);
431
432 i2c_delay(CLOCK_LOW_TIME);
433
434 spin_unlock_irqrestore(&i2c_lock, flags);
435
436 return -error;
437}
438
439/*#---------------------------------------------------------------------------
440*#
441*# FUNCTION NAME: i2c_read
442*#
443*# DESCRIPTION : Reads a value from an I2C device
444*#
445*#--------------------------------------------------------------------------*/
446int
447i2c_read(unsigned char theSlave, void *data, size_t nbytes)
448{
449 unsigned char b = 0;
450 unsigned char bytes_read = 0;
451 int error, cntr = 3;
452 unsigned long flags;
453
454 spin_lock_irqsave(&i2c_lock, flags);
455
456 do {
457 error = 0;
458 memset(data, 0, nbytes);
459 /*
460 * generate start condition
461 */
462 i2c_start();
463 /*
464 * send slave address
465 */
466 i2c_outbyte((theSlave | 0x01));
467 /*
468 * wait for ack
469 */
470 if (!i2c_getack())
471 error = 1;
472 /*
473 * fetch data
474 */
475 for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
476 b = i2c_inbyte();
477 memcpy(data + bytes_read, &b, sizeof b);
478
479 if (bytes_read < (nbytes - 1))
480 i2c_sendack();
481 }
482 /*
483 * last received byte needs to be nacked
484 * instead of acked
485 */
486 i2c_sendnack();
487 /*
488 * end sequence
489 */
490 i2c_stop();
491 } while (error && cntr--);
492
493 spin_unlock_irqrestore(&i2c_lock, flags);
494
495 return -error;
496}
497
498/*#---------------------------------------------------------------------------
499*#
378*# FUNCTION NAME: i2c_writereg 500*# FUNCTION NAME: i2c_writereg
379*# 501*#
380*# DESCRIPTION : Writes a value to an I2C device 502*# DESCRIPTION : Writes a value to an I2C device
@@ -387,12 +509,10 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg,
387 int error, cntr = 3; 509 int error, cntr = 3;
388 unsigned long flags; 510 unsigned long flags;
389 511
512 spin_lock_irqsave(&i2c_lock, flags);
513
390 do { 514 do {
391 error = 0; 515 error = 0;
392 /*
393 * we don't like to be interrupted
394 */
395 local_irq_save(flags);
396 516
397 i2c_start(); 517 i2c_start();
398 /* 518 /*
@@ -427,15 +547,12 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg,
427 * end byte stream 547 * end byte stream
428 */ 548 */
429 i2c_stop(); 549 i2c_stop();
430 /*
431 * enable interrupt again
432 */
433 local_irq_restore(flags);
434
435 } while(error && cntr--); 550 } while(error && cntr--);
436 551
437 i2c_delay(CLOCK_LOW_TIME); 552 i2c_delay(CLOCK_LOW_TIME);
438 553
554 spin_unlock_irqrestore(&i2c_lock, flags);
555
439 return -error; 556 return -error;
440} 557}
441 558
@@ -453,13 +570,11 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
453 int error, cntr = 3; 570 int error, cntr = 3;
454 unsigned long flags; 571 unsigned long flags;
455 572
573 spin_lock_irqsave(&i2c_lock, flags);
574
456 do { 575 do {
457 error = 0; 576 error = 0;
458 /* 577 /*
459 * we don't like to be interrupted
460 */
461 local_irq_save(flags);
462 /*
463 * generate start condition 578 * generate start condition
464 */ 579 */
465 i2c_start(); 580 i2c_start();
@@ -482,7 +597,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
482 * now it's time to wait for ack 597 * now it's time to wait for ack
483 */ 598 */
484 if(!i2c_getack()) 599 if(!i2c_getack())
485 error = 1; 600 error |= 2;
486 /* 601 /*
487 * repeat start condition 602 * repeat start condition
488 */ 603 */
@@ -496,7 +611,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
496 * wait for ack 611 * wait for ack
497 */ 612 */
498 if(!i2c_getack()) 613 if(!i2c_getack())
499 error = 1; 614 error |= 4;
500 /* 615 /*
501 * fetch register 616 * fetch register
502 */ 617 */
@@ -510,13 +625,11 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
510 * end sequence 625 * end sequence
511 */ 626 */
512 i2c_stop(); 627 i2c_stop();
513 /*
514 * enable interrupt again
515 */
516 local_irq_restore(flags);
517 628
518 } while(error && cntr--); 629 } while(error && cntr--);
519 630
631 spin_unlock_irqrestore(&i2c_lock, flags);
632
520 return b; 633 return b;
521} 634}
522 635
@@ -540,7 +653,7 @@ i2c_ioctl(struct inode *inode, struct file *file,
540 unsigned int cmd, unsigned long arg) 653 unsigned int cmd, unsigned long arg)
541{ 654{
542 if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { 655 if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
543 return -EINVAL; 656 return -ENOTTY;
544 } 657 }
545 658
546 switch (_IOC_NR(cmd)) { 659 switch (_IOC_NR(cmd)) {
@@ -580,31 +693,52 @@ static const struct file_operations i2c_fops = {
580 .release = i2c_release, 693 .release = i2c_release,
581}; 694};
582 695
583int __init 696static int __init i2c_init(void)
584i2c_init(void)
585{ 697{
586 int res; 698 static int res;
699 static int first = 1;
587 700
588 /* Setup and enable the Port B I2C interface */ 701 if (!first)
702 return res;
589 703
590 crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT); 704 first = 0;
591 crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT); 705
706 /* Setup and enable the DATA and CLK pins */
707
708 res = crisv32_io_get_name(&cris_i2c_data,
709 CONFIG_ETRAX_V32_I2C_DATA_PORT);
710 if (res < 0)
711 return res;
712
713 res = crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_V32_I2C_CLK_PORT);
714 crisv32_io_set_dir(&cris_i2c_clk, crisv32_io_dir_out);
715
716 return res;
717}
718
719
720static int __init i2c_register(void)
721{
722 int res;
723
724 res = i2c_init();
725 if (res < 0)
726 return res;
592 727
593 /* register char device */ 728 /* register char device */
594 729
595 res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); 730 res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
596 if(res < 0) { 731 if (res < 0) {
597 printk(KERN_ERR "i2c: couldn't get a major number.\n"); 732 printk(KERN_ERR "i2c: couldn't get a major number.\n");
598 return res; 733 return res;
599 } 734 }
600 735
601 printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); 736 printk(KERN_INFO
737 "I2C driver v2.2, (c) 1999-2007 Axis Communications AB\n");
602 738
603 return 0; 739 return 0;
604} 740}
605
606/* this makes sure that i2c_init is called during boot */ 741/* this makes sure that i2c_init is called during boot */
607 742module_init(i2c_register);
608module_init(i2c_init);
609 743
610/****************** END OF FILE i2c.c ********************************/ 744/****************** END OF FILE i2c.c ********************************/
diff --git a/arch/cris/arch-v32/drivers/i2c.h b/arch/cris/arch-v32/drivers/i2c.h
index bfe1a13f9f35..c073cf4ba016 100644
--- a/arch/cris/arch-v32/drivers/i2c.h
+++ b/arch/cris/arch-v32/drivers/i2c.h
@@ -3,6 +3,8 @@
3 3
4/* High level I2C actions */ 4/* High level I2C actions */
5int __init i2c_init(void); 5int __init i2c_init(void);
6int i2c_write(unsigned char theSlave, void *data, size_t nbytes);
7int i2c_read(unsigned char theSlave, void *data, size_t nbytes);
6int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); 8int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
7unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg); 9unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
8 10
diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c
index f4bdc1dfa320..3b3857ec1f15 100644
--- a/arch/cris/arch-v32/drivers/iop_fw_load.c
+++ b/arch/cris/arch-v32/drivers/iop_fw_load.c
@@ -1,5 +1,4 @@
1/* $Id: iop_fw_load.c,v 1.4 2005/04/07 09:27:46 larsv Exp $ 1/*
2 *
3 * Firmware loader for ETRAX FS IO-Processor 2 * Firmware loader for ETRAX FS IO-Processor
4 * 3 *
5 * Copyright (C) 2004 Axis Communications AB 4 * Copyright (C) 2004 Axis Communications AB
@@ -11,12 +10,13 @@
11#include <linux/device.h> 10#include <linux/device.h>
12#include <linux/firmware.h> 11#include <linux/firmware.h>
13 12
14#include <asm/arch/hwregs/reg_map.h> 13#include <hwregs/reg_rdwr.h>
15#include <asm/arch/hwregs/iop/iop_reg_space.h> 14#include <hwregs/reg_map.h>
16#include <asm/arch/hwregs/iop/iop_mpu_macros.h> 15#include <hwregs/iop/iop_reg_space.h>
17#include <asm/arch/hwregs/iop/iop_mpu_defs.h> 16#include <hwregs/iop/iop_mpu_macros.h>
18#include <asm/arch/hwregs/iop/iop_spu_defs.h> 17#include <hwregs/iop/iop_mpu_defs.h>
19#include <asm/arch/hwregs/iop/iop_sw_cpu_defs.h> 18#include <hwregs/iop/iop_spu_defs.h>
19#include <hwregs/iop/iop_sw_cpu_defs.h>
20 20
21#define IOP_TIMEOUT 100 21#define IOP_TIMEOUT 100
22 22
diff --git a/arch/cris/arch-v32/drivers/mach-a3/Makefile b/arch/cris/arch-v32/drivers/mach-a3/Makefile
new file mode 100644
index 000000000000..5c6d2a2a080e
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/mach-a3/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for Etrax-specific drivers
3#
4
5obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o
6obj-$(CONFIG_ETRAX_GPIO) += gpio.o
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
new file mode 100644
index 000000000000..de107dad9f4f
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
@@ -0,0 +1,984 @@
1/*
2 * Artec-3 general port I/O device
3 *
4 * Copyright (c) 2007 Axis Communications AB
5 *
6 * Authors: Bjorn Wesen (initial version)
7 * Ola Knutsson (LED handling)
8 * Johan Adolfsson (read/set directions, write, port G,
9 * port to ETRAX FS.
10 * Ricard Wanderlof (PWM for Artpec-3)
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <linux/ioport.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/fs.h>
21#include <linux/string.h>
22#include <linux/poll.h>
23#include <linux/init.h>
24#include <linux/interrupt.h>
25#include <linux/spinlock.h>
26
27#include <asm/etraxgpio.h>
28#include <hwregs/reg_map.h>
29#include <hwregs/reg_rdwr.h>
30#include <hwregs/gio_defs.h>
31#include <hwregs/intr_vect_defs.h>
32#include <asm/io.h>
33#include <asm/system.h>
34#include <asm/irq.h>
35#include <asm/arch/mach/pinmux.h>
36
37#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
38#include "../i2c.h"
39
40#define VIRT_I2C_ADDR 0x40
41#endif
42
43/* The following gio ports on ARTPEC-3 is available:
44 * pa 32 bits
45 * pb 32 bits
46 * pc 16 bits
47 * each port has a rw_px_dout, r_px_din and rw_px_oe register.
48 */
49
50#define GPIO_MAJOR 120 /* experimental MAJOR number */
51
52#define I2C_INTERRUPT_BITS 0x300 /* i2c0_done and i2c1_done bits */
53
54#define D(x)
55
56#if 0
57static int dp_cnt;
58#define DP(x) \
59 do { \
60 dp_cnt++; \
61 if (dp_cnt % 1000 == 0) \
62 x; \
63 } while (0)
64#else
65#define DP(x)
66#endif
67
68static char gpio_name[] = "etrax gpio";
69
70#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
71static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
72 unsigned long arg);
73#endif
74static int gpio_ioctl(struct inode *inode, struct file *file,
75 unsigned int cmd, unsigned long arg);
76static ssize_t gpio_write(struct file *file, const char __user *buf,
77 size_t count, loff_t *off);
78static int gpio_open(struct inode *inode, struct file *filp);
79static int gpio_release(struct inode *inode, struct file *filp);
80static unsigned int gpio_poll(struct file *filp,
81 struct poll_table_struct *wait);
82
83/* private data per open() of this driver */
84
85struct gpio_private {
86 struct gpio_private *next;
87 /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
88 unsigned char clk_mask;
89 unsigned char data_mask;
90 unsigned char write_msb;
91 unsigned char pad1;
92 /* These fields are generic */
93 unsigned long highalarm, lowalarm;
94 wait_queue_head_t alarm_wq;
95 int minor;
96};
97
98static void gpio_set_alarm(struct gpio_private *priv);
99static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
100static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd,
101 unsigned long arg);
102
103
104/* linked list of alarms to check for */
105
106static struct gpio_private *alarmlist;
107
108static int wanted_interrupts;
109
110static DEFINE_SPINLOCK(gpio_lock);
111
112#define NUM_PORTS (GPIO_MINOR_LAST+1)
113#define GIO_REG_RD_ADDR(reg) \
114 (unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
115#define GIO_REG_WR_ADDR(reg) \
116 (unsigned long *)(regi_gio + REG_WR_ADDR_gio_##reg)
117static unsigned long led_dummy;
118static unsigned long port_d_dummy; /* Only input on Artpec-3 */
119#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
120static unsigned long port_e_dummy; /* Non existent on Artpec-3 */
121static unsigned long virtual_dummy;
122static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
123static unsigned short cached_virtual_gpio_read;
124#endif
125
126static unsigned long *data_out[NUM_PORTS] = {
127 GIO_REG_WR_ADDR(rw_pa_dout),
128 GIO_REG_WR_ADDR(rw_pb_dout),
129 &led_dummy,
130 GIO_REG_WR_ADDR(rw_pc_dout),
131 &port_d_dummy,
132#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
133 &port_e_dummy,
134 &virtual_dummy,
135#endif
136};
137
138static unsigned long *data_in[NUM_PORTS] = {
139 GIO_REG_RD_ADDR(r_pa_din),
140 GIO_REG_RD_ADDR(r_pb_din),
141 &led_dummy,
142 GIO_REG_RD_ADDR(r_pc_din),
143 GIO_REG_RD_ADDR(r_pd_din),
144#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
145 &port_e_dummy,
146 &virtual_dummy,
147#endif
148};
149
150static unsigned long changeable_dir[NUM_PORTS] = {
151 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
152 CONFIG_ETRAX_PB_CHANGEABLE_DIR,
153 0,
154 CONFIG_ETRAX_PC_CHANGEABLE_DIR,
155 0,
156#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
157 0,
158 CONFIG_ETRAX_PV_CHANGEABLE_DIR,
159#endif
160};
161
162static unsigned long changeable_bits[NUM_PORTS] = {
163 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
164 CONFIG_ETRAX_PB_CHANGEABLE_BITS,
165 0,
166 CONFIG_ETRAX_PC_CHANGEABLE_BITS,
167 0,
168#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
169 0,
170 CONFIG_ETRAX_PV_CHANGEABLE_BITS,
171#endif
172};
173
174static unsigned long *dir_oe[NUM_PORTS] = {
175 GIO_REG_WR_ADDR(rw_pa_oe),
176 GIO_REG_WR_ADDR(rw_pb_oe),
177 &led_dummy,
178 GIO_REG_WR_ADDR(rw_pc_oe),
179 &port_d_dummy,
180#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
181 &port_e_dummy,
182 &virtual_rw_pv_oe,
183#endif
184};
185
186static void gpio_set_alarm(struct gpio_private *priv)
187{
188 int bit;
189 int intr_cfg;
190 int mask;
191 int pins;
192 unsigned long flags;
193
194 spin_lock_irqsave(&gpio_lock, flags);
195 intr_cfg = REG_RD_INT(gio, regi_gio, rw_intr_cfg);
196 pins = REG_RD_INT(gio, regi_gio, rw_intr_pins);
197 mask = REG_RD_INT(gio, regi_gio, rw_intr_mask) & I2C_INTERRUPT_BITS;
198
199 for (bit = 0; bit < 32; bit++) {
200 int intr = bit % 8;
201 int pin = bit / 8;
202 if (priv->minor < GPIO_MINOR_LEDS)
203 pin += priv->minor * 4;
204 else
205 pin += (priv->minor - 1) * 4;
206
207 if (priv->highalarm & (1<<bit)) {
208 intr_cfg |= (regk_gio_hi << (intr * 3));
209 mask |= 1 << intr;
210 wanted_interrupts = mask & 0xff;
211 pins |= pin << (intr * 4);
212 } else if (priv->lowalarm & (1<<bit)) {
213 intr_cfg |= (regk_gio_lo << (intr * 3));
214 mask |= 1 << intr;
215 wanted_interrupts = mask & 0xff;
216 pins |= pin << (intr * 4);
217 }
218 }
219
220 REG_WR_INT(gio, regi_gio, rw_intr_cfg, intr_cfg);
221 REG_WR_INT(gio, regi_gio, rw_intr_pins, pins);
222 REG_WR_INT(gio, regi_gio, rw_intr_mask, mask);
223
224 spin_unlock_irqrestore(&gpio_lock, flags);
225}
226
227static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
228{
229 unsigned int mask = 0;
230 struct gpio_private *priv = file->private_data;
231 unsigned long data;
232 unsigned long tmp;
233
234 if (priv->minor >= GPIO_MINOR_PWM0 &&
235 priv->minor <= GPIO_MINOR_LAST_PWM)
236 return 0;
237
238 poll_wait(file, &priv->alarm_wq, wait);
239 if (priv->minor <= GPIO_MINOR_D) {
240 data = readl(data_in[priv->minor]);
241 REG_WR_INT(gio, regi_gio, rw_ack_intr, wanted_interrupts);
242 tmp = REG_RD_INT(gio, regi_gio, rw_intr_mask);
243 tmp &= I2C_INTERRUPT_BITS;
244 tmp |= wanted_interrupts;
245 REG_WR_INT(gio, regi_gio, rw_intr_mask, tmp);
246 } else
247 return 0;
248
249 if ((data & priv->highalarm) || (~data & priv->lowalarm))
250 mask = POLLIN|POLLRDNORM;
251
252 DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
253 return mask;
254}
255
256static irqreturn_t gpio_interrupt(int irq, void *dev_id)
257{
258 reg_gio_rw_intr_mask intr_mask;
259 reg_gio_r_masked_intr masked_intr;
260 reg_gio_rw_ack_intr ack_intr;
261 unsigned long flags;
262 unsigned long tmp;
263 unsigned long tmp2;
264#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
265 unsigned char enable_gpiov_ack = 0;
266#endif
267
268 /* Find what PA interrupts are active */
269 masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
270 tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
271
272 /* Find those that we have enabled */
273 spin_lock_irqsave(&gpio_lock, flags);
274 tmp &= wanted_interrupts;
275 spin_unlock_irqrestore(&gpio_lock, flags);
276
277#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
278 /* Something changed on virtual GPIO. Interrupt is acked by
279 * reading the device.
280 */
281 if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
282 i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
283 sizeof(cached_virtual_gpio_read));
284 enable_gpiov_ack = 1;
285 }
286#endif
287
288 /* Ack them */
289 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
290 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
291
292 /* Disable those interrupts.. */
293 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
294 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
295 tmp2 &= ~tmp;
296#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
297 /* Do not disable interrupt on virtual GPIO. Changes on virtual
298 * pins are only noticed by an interrupt.
299 */
300 if (enable_gpiov_ack)
301 tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
302#endif
303 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
304 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
305
306 return IRQ_RETVAL(tmp);
307}
308
309static void gpio_write_bit(unsigned long *port, unsigned char data, int bit,
310 unsigned char clk_mask, unsigned char data_mask)
311{
312 unsigned long shadow = readl(port) & ~clk_mask;
313 writel(shadow, port);
314 if (data & 1 << bit)
315 shadow |= data_mask;
316 else
317 shadow &= ~data_mask;
318 writel(shadow, port);
319 /* For FPGA: min 5.0ns (DCC) before CCLK high */
320 shadow |= clk_mask;
321 writel(shadow, port);
322}
323
324static void gpio_write_byte(struct gpio_private *priv, unsigned long *port,
325 unsigned char data)
326{
327 int i;
328
329 if (priv->write_msb)
330 for (i = 7; i >= 0; i--)
331 gpio_write_bit(port, data, i, priv->clk_mask,
332 priv->data_mask);
333 else
334 for (i = 0; i <= 7; i++)
335 gpio_write_bit(port, data, i, priv->clk_mask,
336 priv->data_mask);
337}
338
339
340static ssize_t gpio_write(struct file *file, const char __user *buf,
341 size_t count, loff_t *off)
342{
343 struct gpio_private *priv = file->private_data;
344 unsigned long flags;
345 ssize_t retval = count;
346 /* Only bits 0-7 may be used for write operations but allow all
347 devices except leds... */
348#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
349 if (priv->minor == GPIO_MINOR_V)
350 return -EFAULT;
351#endif
352 if (priv->minor == GPIO_MINOR_LEDS)
353 return -EFAULT;
354
355 if (priv->minor >= GPIO_MINOR_PWM0 &&
356 priv->minor <= GPIO_MINOR_LAST_PWM)
357 return -EFAULT;
358
359 if (!access_ok(VERIFY_READ, buf, count))
360 return -EFAULT;
361
362 /* It must have been configured using the IO_CFG_WRITE_MODE */
363 /* Perhaps a better error code? */
364 if (priv->clk_mask == 0 || priv->data_mask == 0)
365 return -EPERM;
366
367 D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
368 "msb: %i\n",
369 count, priv->data_mask, priv->clk_mask, priv->write_msb));
370
371 spin_lock_irqsave(&gpio_lock, flags);
372
373 while (count--)
374 gpio_write_byte(priv, data_out[priv->minor], *buf++);
375
376 spin_unlock_irqrestore(&gpio_lock, flags);
377 return retval;
378}
379
380static int gpio_open(struct inode *inode, struct file *filp)
381{
382 struct gpio_private *priv;
383 int p = iminor(inode);
384
385 if (p > GPIO_MINOR_LAST_PWM ||
386 (p > GPIO_MINOR_LAST && p < GPIO_MINOR_PWM0))
387 return -EINVAL;
388
389 priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
390
391 if (!priv)
392 return -ENOMEM;
393 memset(priv, 0, sizeof(*priv));
394
395 priv->minor = p;
396 filp->private_data = priv;
397
398 /* initialize the io/alarm struct, not for PWM ports though */
399 if (p <= GPIO_MINOR_LAST) {
400
401 priv->clk_mask = 0;
402 priv->data_mask = 0;
403 priv->highalarm = 0;
404 priv->lowalarm = 0;
405
406 init_waitqueue_head(&priv->alarm_wq);
407
408 /* link it into our alarmlist */
409 spin_lock_irq(&gpio_lock);
410 priv->next = alarmlist;
411 alarmlist = priv;
412 spin_unlock_irq(&gpio_lock);
413 }
414
415 return 0;
416}
417
418static int gpio_release(struct inode *inode, struct file *filp)
419{
420 struct gpio_private *p;
421 struct gpio_private *todel;
422 /* local copies while updating them: */
423 unsigned long a_high, a_low;
424
425 /* prepare to free private structure */
426 todel = filp->private_data;
427
428 /* unlink from alarmlist - only for non-PWM ports though */
429 if (todel->minor <= GPIO_MINOR_LAST) {
430 spin_lock_irq(&gpio_lock);
431 p = alarmlist;
432
433 if (p == todel)
434 alarmlist = todel->next;
435 else {
436 while (p->next != todel)
437 p = p->next;
438 p->next = todel->next;
439 }
440
441 /* Check if there are still any alarms set */
442 p = alarmlist;
443 a_high = 0;
444 a_low = 0;
445 while (p) {
446 if (p->minor == GPIO_MINOR_A) {
447#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
448 p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
449#endif
450 a_high |= p->highalarm;
451 a_low |= p->lowalarm;
452 }
453
454 p = p->next;
455 }
456
457#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
458 /* Variable 'a_low' needs to be set here again
459 * to ensure that interrupt for virtual GPIO is handled.
460 */
461 a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
462#endif
463
464 spin_unlock_irq(&gpio_lock);
465 }
466 kfree(todel);
467
468 return 0;
469}
470
471/* Main device API. ioctl's to read/set/clear bits, as well as to
472 * set alarms to wait for using a subsequent select().
473 */
474
475inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
476{
477 /* Set direction 0=unchanged 1=input,
478 * return mask with 1=input
479 */
480 unsigned long flags;
481 unsigned long dir_shadow;
482
483 spin_lock_irqsave(&gpio_lock, flags);
484
485 dir_shadow = readl(dir_oe[priv->minor]) &
486 ~(arg & changeable_dir[priv->minor]);
487 writel(dir_shadow, dir_oe[priv->minor]);
488
489 spin_unlock_irqrestore(&gpio_lock, flags);
490
491 if (priv->minor == GPIO_MINOR_C)
492 dir_shadow ^= 0xFFFF; /* Only 16 bits */
493#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
494 else if (priv->minor == GPIO_MINOR_V)
495 dir_shadow ^= 0xFFFF; /* Only 16 bits */
496#endif
497 else
498 dir_shadow ^= 0xFFFFFFFF; /* PA, PB and PD 32 bits */
499
500 return dir_shadow;
501
502} /* setget_input */
503
504static inline unsigned long setget_output(struct gpio_private *priv,
505 unsigned long arg)
506{
507 unsigned long flags;
508 unsigned long dir_shadow;
509
510 spin_lock_irqsave(&gpio_lock, flags);
511
512 dir_shadow = readl(dir_oe[priv->minor]) |
513 (arg & changeable_dir[priv->minor]);
514 writel(dir_shadow, dir_oe[priv->minor]);
515
516 spin_unlock_irqrestore(&gpio_lock, flags);
517 return dir_shadow;
518} /* setget_output */
519
520static int gpio_ioctl(struct inode *inode, struct file *file,
521 unsigned int cmd, unsigned long arg)
522{
523 unsigned long flags;
524 unsigned long val;
525 unsigned long shadow;
526 struct gpio_private *priv = file->private_data;
527
528 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
529 return -ENOTTY;
530
531 /* Check for special ioctl handlers first */
532
533#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
534 if (priv->minor == GPIO_MINOR_V)
535 return virtual_gpio_ioctl(file, cmd, arg);
536#endif
537
538 if (priv->minor == GPIO_MINOR_LEDS)
539 return gpio_leds_ioctl(cmd, arg);
540
541 if (priv->minor >= GPIO_MINOR_PWM0 &&
542 priv->minor <= GPIO_MINOR_LAST_PWM)
543 return gpio_pwm_ioctl(priv, cmd, arg);
544
545 switch (_IOC_NR(cmd)) {
546 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
547 /* Read the port. */
548 return readl(data_in[priv->minor]);
549 case IO_SETBITS:
550 spin_lock_irqsave(&gpio_lock, flags);
551 /* Set changeable bits with a 1 in arg. */
552 shadow = readl(data_out[priv->minor]) |
553 (arg & changeable_bits[priv->minor]);
554 writel(shadow, data_out[priv->minor]);
555 spin_unlock_irqrestore(&gpio_lock, flags);
556 break;
557 case IO_CLRBITS:
558 spin_lock_irqsave(&gpio_lock, flags);
559 /* Clear changeable bits with a 1 in arg. */
560 shadow = readl(data_out[priv->minor]) &
561 ~(arg & changeable_bits[priv->minor]);
562 writel(shadow, data_out[priv->minor]);
563 spin_unlock_irqrestore(&gpio_lock, flags);
564 break;
565 case IO_HIGHALARM:
566 /* Set alarm when bits with 1 in arg go high. */
567 priv->highalarm |= arg;
568 gpio_set_alarm(priv);
569 break;
570 case IO_LOWALARM:
571 /* Set alarm when bits with 1 in arg go low. */
572 priv->lowalarm |= arg;
573 gpio_set_alarm(priv);
574 break;
575 case IO_CLRALARM:
576 /* Clear alarm for bits with 1 in arg. */
577 priv->highalarm &= ~arg;
578 priv->lowalarm &= ~arg;
579 gpio_set_alarm(priv);
580 break;
581 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
582 /* Read direction 0=input 1=output */
583 return readl(dir_oe[priv->minor]);
584
585 case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
586 /* Set direction 0=unchanged 1=input,
587 * return mask with 1=input
588 */
589 return setget_input(priv, arg);
590
591 case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
592 /* Set direction 0=unchanged 1=output,
593 * return mask with 1=output
594 */
595 return setget_output(priv, arg);
596
597 case IO_CFG_WRITE_MODE:
598 {
599 int res = -EPERM;
600 unsigned long dir_shadow, clk_mask, data_mask, write_msb;
601
602 clk_mask = arg & 0xFF;
603 data_mask = (arg >> 8) & 0xFF;
604 write_msb = (arg >> 16) & 0x01;
605
606 /* Check if we're allowed to change the bits and
607 * the direction is correct
608 */
609 spin_lock_irqsave(&gpio_lock, flags);
610 dir_shadow = readl(dir_oe[priv->minor]);
611 if ((clk_mask & changeable_bits[priv->minor]) &&
612 (data_mask & changeable_bits[priv->minor]) &&
613 (clk_mask & dir_shadow) &&
614 (data_mask & dir_shadow)) {
615 priv->clk_mask = clk_mask;
616 priv->data_mask = data_mask;
617 priv->write_msb = write_msb;
618 res = 0;
619 }
620 spin_unlock_irqrestore(&gpio_lock, flags);
621
622 return res;
623 }
624 case IO_READ_INBITS:
625 /* *arg is result of reading the input pins */
626 val = readl(data_in[priv->minor]);
627 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
628 return -EFAULT;
629 return 0;
630 case IO_READ_OUTBITS:
631 /* *arg is result of reading the output shadow */
632 val = *data_out[priv->minor];
633 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
634 return -EFAULT;
635 break;
636 case IO_SETGET_INPUT:
637 /* bits set in *arg is set to input,
638 * *arg updated with current input pins.
639 */
640 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
641 return -EFAULT;
642 val = setget_input(priv, val);
643 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
644 return -EFAULT;
645 break;
646 case IO_SETGET_OUTPUT:
647 /* bits set in *arg is set to output,
648 * *arg updated with current output pins.
649 */
650 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
651 return -EFAULT;
652 val = setget_output(priv, val);
653 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
654 return -EFAULT;
655 break;
656 default:
657 return -EINVAL;
658 } /* switch */
659
660 return 0;
661}
662
663#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
664static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
665 unsigned long arg)
666{
667 unsigned long flags;
668 unsigned short val;
669 unsigned short shadow;
670 struct gpio_private *priv = file->private_data;
671
672 switch (_IOC_NR(cmd)) {
673 case IO_SETBITS:
674 spin_lock_irqsave(&gpio_lock, flags);
675 /* Set changeable bits with a 1 in arg. */
676 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
677 shadow |= ~readl(dir_oe[priv->minor]) |
678 (arg & changeable_bits[priv->minor]);
679 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
680 spin_lock_irqrestore(&gpio_lock, flags);
681 break;
682 case IO_CLRBITS:
683 spin_lock_irqsave(&gpio_lock, flags);
684 /* Clear changeable bits with a 1 in arg. */
685 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
686 shadow |= ~readl(dir_oe[priv->minor]) &
687 ~(arg & changeable_bits[priv->minor]);
688 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
689 spin_lock_irqrestore(&gpio_lock, flags);
690 break;
691 case IO_HIGHALARM:
692 /* Set alarm when bits with 1 in arg go high. */
693 priv->highalarm |= arg;
694 break;
695 case IO_LOWALARM:
696 /* Set alarm when bits with 1 in arg go low. */
697 priv->lowalarm |= arg;
698 break;
699 case IO_CLRALARM:
700 /* Clear alarm for bits with 1 in arg. */
701 priv->highalarm &= ~arg;
702 priv->lowalarm &= ~arg;
703 break;
704 case IO_CFG_WRITE_MODE:
705 {
706 unsigned long dir_shadow;
707 dir_shadow = readl(dir_oe[priv->minor]);
708
709 priv->clk_mask = arg & 0xFF;
710 priv->data_mask = (arg >> 8) & 0xFF;
711 priv->write_msb = (arg >> 16) & 0x01;
712 /* Check if we're allowed to change the bits and
713 * the direction is correct
714 */
715 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
716 (priv->data_mask & changeable_bits[priv->minor]) &&
717 (priv->clk_mask & dir_shadow) &&
718 (priv->data_mask & dir_shadow))) {
719 priv->clk_mask = 0;
720 priv->data_mask = 0;
721 return -EPERM;
722 }
723 break;
724 }
725 case IO_READ_INBITS:
726 /* *arg is result of reading the input pins */
727 val = cached_virtual_gpio_read & ~readl(dir_oe[priv->minor]);
728 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
729 return -EFAULT;
730 return 0;
731
732 case IO_READ_OUTBITS:
733 /* *arg is result of reading the output shadow */
734 i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
735 val &= readl(dir_oe[priv->minor]);
736 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
737 return -EFAULT;
738 break;
739 case IO_SETGET_INPUT:
740 {
741 /* bits set in *arg is set to input,
742 * *arg updated with current input pins.
743 */
744 unsigned short input_mask = ~readl(dir_oe[priv->minor]);
745 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
746 return -EFAULT;
747 val = setget_input(priv, val);
748 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
749 return -EFAULT;
750 if ((input_mask & val) != input_mask) {
751 /* Input pins changed. All ports desired as input
752 * should be set to logic 1.
753 */
754 unsigned short change = input_mask ^ val;
755 i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
756 sizeof(shadow));
757 shadow &= ~change;
758 shadow |= val;
759 i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
760 sizeof(shadow));
761 }
762 break;
763 }
764 case IO_SETGET_OUTPUT:
765 /* bits set in *arg is set to output,
766 * *arg updated with current output pins.
767 */
768 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
769 return -EFAULT;
770 val = setget_output(priv, val);
771 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
772 return -EFAULT;
773 break;
774 default:
775 return -EINVAL;
776 } /* switch */
777 return 0;
778}
779#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
780
781static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
782{
783 unsigned char green;
784 unsigned char red;
785
786 switch (_IOC_NR(cmd)) {
787 case IO_LEDACTIVE_SET:
788 green = ((unsigned char) arg) & 1;
789 red = (((unsigned char) arg) >> 1) & 1;
790 CRIS_LED_ACTIVE_SET_G(green);
791 CRIS_LED_ACTIVE_SET_R(red);
792 break;
793
794 default:
795 return -EINVAL;
796 } /* switch */
797
798 return 0;
799}
800
801static int gpio_pwm_set_mode(unsigned long arg, int pwm_port)
802{
803 int pinmux_pwm = pinmux_pwm0 + pwm_port;
804 int mode;
805 reg_gio_rw_pwm0_ctrl rw_pwm_ctrl = {
806 .ccd_val = 0,
807 .ccd_override = regk_gio_no,
808 .mode = regk_gio_no
809 };
810 int allocstatus;
811
812 if (get_user(mode, &((struct io_pwm_set_mode *) arg)->mode))
813 return -EFAULT;
814 rw_pwm_ctrl.mode = mode;
815 if (mode != PWM_OFF)
816 allocstatus = crisv32_pinmux_alloc_fixed(pinmux_pwm);
817 else
818 allocstatus = crisv32_pinmux_dealloc_fixed(pinmux_pwm);
819 if (allocstatus)
820 return allocstatus;
821 REG_WRITE(reg_gio_rw_pwm0_ctrl, REG_ADDR(gio, regi_gio, rw_pwm0_ctrl) +
822 12 * pwm_port, rw_pwm_ctrl);
823 return 0;
824}
825
826static int gpio_pwm_set_period(unsigned long arg, int pwm_port)
827{
828 struct io_pwm_set_period periods;
829 reg_gio_rw_pwm0_var rw_pwm_widths;
830
831 if (copy_from_user(&periods, (void __user *)arg, sizeof(periods)))
832 return -EFAULT;
833 if (periods.lo > 8191 || periods.hi > 8191)
834 return -EINVAL;
835 rw_pwm_widths.lo = periods.lo;
836 rw_pwm_widths.hi = periods.hi;
837 REG_WRITE(reg_gio_rw_pwm0_var, REG_ADDR(gio, regi_gio, rw_pwm0_var) +
838 12 * pwm_port, rw_pwm_widths);
839 return 0;
840}
841
842static int gpio_pwm_set_duty(unsigned long arg, int pwm_port)
843{
844 unsigned int duty;
845 reg_gio_rw_pwm0_data rw_pwm_duty;
846
847 if (get_user(duty, &((struct io_pwm_set_duty *) arg)->duty))
848 return -EFAULT;
849 if (duty > 255)
850 return -EINVAL;
851 rw_pwm_duty.data = duty;
852 REG_WRITE(reg_gio_rw_pwm0_data, REG_ADDR(gio, regi_gio, rw_pwm0_data) +
853 12 * pwm_port, rw_pwm_duty);
854 return 0;
855}
856
857static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd,
858 unsigned long arg)
859{
860 int pwm_port = priv->minor - GPIO_MINOR_PWM0;
861
862 switch (_IOC_NR(cmd)) {
863 case IO_PWM_SET_MODE:
864 return gpio_pwm_set_mode(arg, pwm_port);
865 case IO_PWM_SET_PERIOD:
866 return gpio_pwm_set_period(arg, pwm_port);
867 case IO_PWM_SET_DUTY:
868 return gpio_pwm_set_duty(arg, pwm_port);
869 default:
870 return -EINVAL;
871 }
872 return 0;
873}
874
875static const struct file_operations gpio_fops = {
876 .owner = THIS_MODULE,
877 .poll = gpio_poll,
878 .ioctl = gpio_ioctl,
879 .write = gpio_write,
880 .open = gpio_open,
881 .release = gpio_release,
882};
883
884#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
885static void __init virtual_gpio_init(void)
886{
887 reg_gio_rw_intr_cfg intr_cfg;
888 reg_gio_rw_intr_mask intr_mask;
889 unsigned short shadow;
890
891 shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
892 shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
893 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
894
895 /* Set interrupt mask and on what state the interrupt shall trigger.
896 * For virtual gpio the interrupt shall trigger on logic '0'.
897 */
898 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
899 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
900
901 switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
902 case 0:
903 intr_cfg.pa0 = regk_gio_lo;
904 intr_mask.pa0 = regk_gio_yes;
905 break;
906 case 1:
907 intr_cfg.pa1 = regk_gio_lo;
908 intr_mask.pa1 = regk_gio_yes;
909 break;
910 case 2:
911 intr_cfg.pa2 = regk_gio_lo;
912 intr_mask.pa2 = regk_gio_yes;
913 break;
914 case 3:
915 intr_cfg.pa3 = regk_gio_lo;
916 intr_mask.pa3 = regk_gio_yes;
917 break;
918 case 4:
919 intr_cfg.pa4 = regk_gio_lo;
920 intr_mask.pa4 = regk_gio_yes;
921 break;
922 case 5:
923 intr_cfg.pa5 = regk_gio_lo;
924 intr_mask.pa5 = regk_gio_yes;
925 break;
926 case 6:
927 intr_cfg.pa6 = regk_gio_lo;
928 intr_mask.pa6 = regk_gio_yes;
929 break;
930 case 7:
931 intr_cfg.pa7 = regk_gio_lo;
932 intr_mask.pa7 = regk_gio_yes;
933 break;
934 }
935
936 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
937 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
938}
939#endif
940
941/* main driver initialization routine, called from mem.c */
942
943static int __init gpio_init(void)
944{
945 int res;
946
947 printk(KERN_INFO "ETRAX FS GPIO driver v2.7, (c) 2003-2008 "
948 "Axis Communications AB\n");
949
950 /* do the formalities */
951
952 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
953 if (res < 0) {
954 printk(KERN_ERR "gpio: couldn't get a major number.\n");
955 return res;
956 }
957
958 /* Clear all leds */
959 CRIS_LED_NETWORK_GRP0_SET(0);
960 CRIS_LED_NETWORK_GRP1_SET(0);
961 CRIS_LED_ACTIVE_SET(0);
962 CRIS_LED_DISK_READ(0);
963 CRIS_LED_DISK_WRITE(0);
964
965 int res2 = request_irq(GIO_INTR_VECT, gpio_interrupt,
966 IRQF_SHARED | IRQF_DISABLED, "gpio", &alarmlist);
967 if (res2) {
968 printk(KERN_ERR "err: irq for gpio\n");
969 return res2;
970 }
971
972 /* No IRQs by default. */
973 REG_WR_INT(gio, regi_gio, rw_intr_pins, 0);
974
975#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
976 virtual_gpio_init();
977#endif
978
979 return res;
980}
981
982/* this makes sure that gpio_init is called during kernel boot */
983
984module_init(gpio_init);
diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c
new file mode 100644
index 000000000000..01ed0be2d0d1
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c
@@ -0,0 +1,180 @@
1/*
2 * arch/cris/arch-v32/drivers/nandflash.c
3 *
4 * Copyright (c) 2007
5 *
6 * Derived from drivers/mtd/nand/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/slab.h>
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/nand.h>
20#include <linux/mtd/partitions.h>
21#include <asm/arch/memmap.h>
22#include <hwregs/reg_map.h>
23#include <hwregs/reg_rdwr.h>
24#include <hwregs/pio_defs.h>
25#include <pinmux.h>
26#include <asm/io.h>
27
28#define MANUAL_ALE_CLE_CONTROL 1
29
30#define regf_ALE a0
31#define regf_CLE a1
32#define regf_NCE ce0_n
33
34#define CLE_BIT 10
35#define ALE_BIT 11
36#define CE_BIT 12
37
38struct mtd_info_wrapper {
39 struct mtd_info info;
40 struct nand_chip chip;
41};
42
43/* Bitmask for control pins */
44#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
45
46static struct mtd_info *crisv32_mtd;
47/*
48 * hardware specific access to control-lines
49 */
50static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
51 unsigned int ctrl)
52{
53 unsigned long flags;
54 reg_pio_rw_dout dout;
55 struct nand_chip *this = mtd->priv;
56
57 local_irq_save(flags);
58
59 /* control bits change */
60 if (ctrl & NAND_CTRL_CHANGE) {
61 dout = REG_RD(pio, regi_pio, rw_dout);
62 dout.regf_NCE = (ctrl & NAND_NCE) ? 0 : 1;
63
64#if !MANUAL_ALE_CLE_CONTROL
65 if (ctrl & NAND_ALE) {
66 /* A0 = ALE high */
67 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio,
68 regi_pio, rw_io_access1);
69 } else if (ctrl & NAND_CLE) {
70 /* A1 = CLE high */
71 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio,
72 regi_pio, rw_io_access2);
73 } else {
74 /* A1 = CLE and A0 = ALE low */
75 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio,
76 regi_pio, rw_io_access0);
77 }
78#else
79
80 dout.regf_CLE = (ctrl & NAND_CLE) ? 1 : 0;
81 dout.regf_ALE = (ctrl & NAND_ALE) ? 1 : 0;
82#endif
83 REG_WR(pio, regi_pio, rw_dout, dout);
84 }
85
86 /* command to chip */
87 if (cmd != NAND_CMD_NONE)
88 writeb(cmd, this->IO_ADDR_W);
89
90 local_irq_restore(flags);
91}
92
93/*
94* read device ready pin
95*/
96static int crisv32_device_ready(struct mtd_info *mtd)
97{
98 reg_pio_r_din din = REG_RD(pio, regi_pio, r_din);
99 return din.rdy;
100}
101
102/*
103 * Main initialization routine
104 */
105struct mtd_info *__init crisv32_nand_flash_probe(void)
106{
107 void __iomem *read_cs;
108 void __iomem *write_cs;
109
110 struct mtd_info_wrapper *wrapper;
111 struct nand_chip *this;
112 int err = 0;
113
114 reg_pio_rw_man_ctrl man_ctrl = {
115 .regf_NCE = regk_pio_yes,
116#if MANUAL_ALE_CLE_CONTROL
117 .regf_ALE = regk_pio_yes,
118 .regf_CLE = regk_pio_yes
119#endif
120 };
121 reg_pio_rw_oe oe = {
122 .regf_NCE = regk_pio_yes,
123#if MANUAL_ALE_CLE_CONTROL
124 .regf_ALE = regk_pio_yes,
125 .regf_CLE = regk_pio_yes
126#endif
127 };
128 reg_pio_rw_dout dout = { .regf_NCE = 1 };
129
130 /* Allocate pio pins to pio */
131 crisv32_pinmux_alloc_fixed(pinmux_pio);
132 /* Set up CE, ALE, CLE (ce0_n, a0, a1) for manual control and output */
133 REG_WR(pio, regi_pio, rw_man_ctrl, man_ctrl);
134 REG_WR(pio, regi_pio, rw_dout, dout);
135 REG_WR(pio, regi_pio, rw_oe, oe);
136
137 /* Allocate memory for MTD device structure and private data */
138 wrapper = kzalloc(sizeof(struct mtd_info_wrapper), GFP_KERNEL);
139 if (!wrapper) {
140 printk(KERN_ERR "Unable to allocate CRISv32 NAND MTD "
141 "device structure.\n");
142 err = -ENOMEM;
143 return NULL;
144 }
145
146 read_cs = write_cs = (void __iomem *)REG_ADDR(pio, regi_pio,
147 rw_io_access0);
148
149 /* Get pointer to private data */
150 this = &wrapper->chip;
151 crisv32_mtd = &wrapper->info;
152
153 /* Link the private data with the MTD structure */
154 crisv32_mtd->priv = this;
155
156 /* Set address of NAND IO lines */
157 this->IO_ADDR_R = read_cs;
158 this->IO_ADDR_W = write_cs;
159 this->cmd_ctrl = crisv32_hwcontrol;
160 this->dev_ready = crisv32_device_ready;
161 /* 20 us command delay time */
162 this->chip_delay = 20;
163 this->ecc.mode = NAND_ECC_SOFT;
164
165 /* Enable the following for a flash based bad block table */
166 /* this->options = NAND_USE_FLASH_BBT; */
167
168 /* Scan to find existance of the device */
169 if (nand_scan(crisv32_mtd, 1)) {
170 err = -ENXIO;
171 goto out_mtd;
172 }
173
174 return crisv32_mtd;
175
176out_mtd:
177 kfree(wrapper);
178 return NULL;
179}
180
diff --git a/arch/cris/arch-v32/drivers/mach-fs/Makefile b/arch/cris/arch-v32/drivers/mach-fs/Makefile
new file mode 100644
index 000000000000..5c6d2a2a080e
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/mach-fs/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for Etrax-specific drivers
3#
4
5obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o
6obj-$(CONFIG_ETRAX_GPIO) += gpio.o
diff --git a/arch/cris/arch-v32/drivers/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
index d82c5c561135..7863fd4efc2b 100644
--- a/arch/cris/arch-v32/drivers/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
@@ -1,68 +1,15 @@
1/* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $ 1/*
2 *
3 * ETRAX CRISv32 general port I/O device 2 * ETRAX CRISv32 general port I/O device
4 * 3 *
5 * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB 4 * Copyright (c) 1999-2006 Axis Communications AB
6 * 5 *
7 * Authors: Bjorn Wesen (initial version) 6 * Authors: Bjorn Wesen (initial version)
8 * Ola Knutsson (LED handling) 7 * Ola Knutsson (LED handling)
9 * Johan Adolfsson (read/set directions, write, port G, 8 * Johan Adolfsson (read/set directions, write, port G,
10 * port to ETRAX FS. 9 * port to ETRAX FS.
11 * 10 *
12 * $Log: gpio.c,v $
13 * Revision 1.16 2005/06/19 17:06:49 starvik
14 * Merge of Linux 2.6.12.
15 *
16 * Revision 1.15 2005/05/25 08:22:20 starvik
17 * Changed GPIO port order to fit packages/devices/axis-2.4.
18 *
19 * Revision 1.14 2005/04/24 18:35:08 starvik
20 * Updated with final register headers.
21 *
22 * Revision 1.13 2005/03/15 15:43:00 starvik
23 * dev_id needs to be supplied for shared IRQs.
24 *
25 * Revision 1.12 2005/03/10 17:12:00 starvik
26 * Protect alarm list with spinlock.
27 *
28 * Revision 1.11 2005/01/05 06:08:59 starvik
29 * No need to do local_irq_disable after local_irq_save.
30 *
31 * Revision 1.10 2004/11/19 08:38:31 starvik
32 * Removed old crap.
33 *
34 * Revision 1.9 2004/05/14 07:58:02 starvik
35 * Merge of changes from 2.4
36 *
37 * Revision 1.8 2003/09/11 07:29:50 starvik
38 * Merge of Linux 2.6.0-test5
39 *
40 * Revision 1.7 2003/07/10 13:25:46 starvik
41 * Compiles for 2.5.74
42 * Lindented ethernet.c
43 *
44 * Revision 1.6 2003/07/04 08:27:46 starvik
45 * Merge of Linux 2.5.74
46 *
47 * Revision 1.5 2003/06/10 08:26:37 johana
48 * Etrax -> ETRAX CRISv32
49 *
50 * Revision 1.4 2003/06/05 14:22:48 johana
51 * Initialise some_alarms.
52 *
53 * Revision 1.3 2003/06/05 10:15:46 johana
54 * New INTR_VECT macros.
55 * Enable interrupts in global config.
56 *
57 * Revision 1.2 2003/06/03 15:52:50 johana
58 * Initial CRIS v32 version.
59 *
60 * Revision 1.1 2003/06/03 08:53:15 johana
61 * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7.
62 *
63 */ 11 */
64 12
65
66#include <linux/module.h> 13#include <linux/module.h>
67#include <linux/sched.h> 14#include <linux/sched.h>
68#include <linux/slab.h> 15#include <linux/slab.h>
@@ -77,14 +24,20 @@
77#include <linux/spinlock.h> 24#include <linux/spinlock.h>
78 25
79#include <asm/etraxgpio.h> 26#include <asm/etraxgpio.h>
80#include <asm/arch/hwregs/reg_map.h> 27#include <hwregs/reg_map.h>
81#include <asm/arch/hwregs/reg_rdwr.h> 28#include <hwregs/reg_rdwr.h>
82#include <asm/arch/hwregs/gio_defs.h> 29#include <hwregs/gio_defs.h>
83#include <asm/arch/hwregs/intr_vect_defs.h> 30#include <hwregs/intr_vect_defs.h>
84#include <asm/io.h> 31#include <asm/io.h>
85#include <asm/system.h> 32#include <asm/system.h>
86#include <asm/irq.h> 33#include <asm/irq.h>
87 34
35#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
36#include "../i2c.h"
37
38#define VIRT_I2C_ADDR 0x40
39#endif
40
88/* The following gio ports on ETRAX FS is available: 41/* The following gio ports on ETRAX FS is available:
89 * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge 42 * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
90 * pb 18 bits 43 * pb 18 bits
@@ -100,7 +53,12 @@
100 53
101#if 0 54#if 0
102static int dp_cnt; 55static int dp_cnt;
103#define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0) 56#define DP(x) \
57 do { \
58 dp_cnt++; \
59 if (dp_cnt % 1000 == 0) \
60 x; \
61 } while (0)
104#else 62#else
105#define DP(x) 63#define DP(x)
106#endif 64#endif
@@ -111,13 +69,18 @@ static char gpio_name[] = "etrax gpio";
111static wait_queue_head_t *gpio_wq; 69static wait_queue_head_t *gpio_wq;
112#endif 70#endif
113 71
72#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
73static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
74 unsigned long arg);
75#endif
114static int gpio_ioctl(struct inode *inode, struct file *file, 76static int gpio_ioctl(struct inode *inode, struct file *file,
115 unsigned int cmd, unsigned long arg); 77 unsigned int cmd, unsigned long arg);
116static ssize_t gpio_write(struct file * file, const char * buf, size_t count, 78static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
117 loff_t *off); 79 loff_t *off);
118static int gpio_open(struct inode *inode, struct file *filp); 80static int gpio_open(struct inode *inode, struct file *filp);
119static int gpio_release(struct inode *inode, struct file *filp); 81static int gpio_release(struct inode *inode, struct file *filp);
120static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait); 82static unsigned int gpio_poll(struct file *filp,
83 struct poll_table_struct *wait);
121 84
122/* private data per open() of this driver */ 85/* private data per open() of this driver */
123 86
@@ -136,18 +99,25 @@ struct gpio_private {
136 99
137/* linked list of alarms to check for */ 100/* linked list of alarms to check for */
138 101
139static struct gpio_private *alarmlist = 0; 102static struct gpio_private *alarmlist;
140 103
141static int gpio_some_alarms = 0; /* Set if someone uses alarm */ 104static int gpio_some_alarms; /* Set if someone uses alarm */
142static unsigned long gpio_pa_high_alarms = 0; 105static unsigned long gpio_pa_high_alarms;
143static unsigned long gpio_pa_low_alarms = 0; 106static unsigned long gpio_pa_low_alarms;
144 107
145static DEFINE_SPINLOCK(alarm_lock); 108static DEFINE_SPINLOCK(alarm_lock);
146 109
147#define NUM_PORTS (GPIO_MINOR_LAST+1) 110#define NUM_PORTS (GPIO_MINOR_LAST+1)
148#define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg ) 111#define GIO_REG_RD_ADDR(reg) \
149#define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg ) 112 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
113#define GIO_REG_WR_ADDR(reg) \
114 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
150unsigned long led_dummy; 115unsigned long led_dummy;
116#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
117static unsigned long virtual_dummy;
118static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
119static unsigned short cached_virtual_gpio_read;
120#endif
151 121
152static volatile unsigned long *data_out[NUM_PORTS] = { 122static volatile unsigned long *data_out[NUM_PORTS] = {
153 GIO_REG_WR_ADDR(rw_pa_dout), 123 GIO_REG_WR_ADDR(rw_pa_dout),
@@ -156,6 +126,9 @@ static volatile unsigned long *data_out[NUM_PORTS] = {
156 GIO_REG_WR_ADDR(rw_pc_dout), 126 GIO_REG_WR_ADDR(rw_pc_dout),
157 GIO_REG_WR_ADDR(rw_pd_dout), 127 GIO_REG_WR_ADDR(rw_pd_dout),
158 GIO_REG_WR_ADDR(rw_pe_dout), 128 GIO_REG_WR_ADDR(rw_pe_dout),
129#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
130 &virtual_dummy,
131#endif
159}; 132};
160 133
161static volatile unsigned long *data_in[NUM_PORTS] = { 134static volatile unsigned long *data_in[NUM_PORTS] = {
@@ -165,6 +138,9 @@ static volatile unsigned long *data_in[NUM_PORTS] = {
165 GIO_REG_RD_ADDR(r_pc_din), 138 GIO_REG_RD_ADDR(r_pc_din),
166 GIO_REG_RD_ADDR(r_pd_din), 139 GIO_REG_RD_ADDR(r_pd_din),
167 GIO_REG_RD_ADDR(r_pe_din), 140 GIO_REG_RD_ADDR(r_pe_din),
141#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
142 &virtual_dummy,
143#endif
168}; 144};
169 145
170static unsigned long changeable_dir[NUM_PORTS] = { 146static unsigned long changeable_dir[NUM_PORTS] = {
@@ -174,6 +150,9 @@ static unsigned long changeable_dir[NUM_PORTS] = {
174 CONFIG_ETRAX_PC_CHANGEABLE_DIR, 150 CONFIG_ETRAX_PC_CHANGEABLE_DIR,
175 CONFIG_ETRAX_PD_CHANGEABLE_DIR, 151 CONFIG_ETRAX_PD_CHANGEABLE_DIR,
176 CONFIG_ETRAX_PE_CHANGEABLE_DIR, 152 CONFIG_ETRAX_PE_CHANGEABLE_DIR,
153#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
154 CONFIG_ETRAX_PV_CHANGEABLE_DIR,
155#endif
177}; 156};
178 157
179static unsigned long changeable_bits[NUM_PORTS] = { 158static unsigned long changeable_bits[NUM_PORTS] = {
@@ -183,6 +162,9 @@ static unsigned long changeable_bits[NUM_PORTS] = {
183 CONFIG_ETRAX_PC_CHANGEABLE_BITS, 162 CONFIG_ETRAX_PC_CHANGEABLE_BITS,
184 CONFIG_ETRAX_PD_CHANGEABLE_BITS, 163 CONFIG_ETRAX_PD_CHANGEABLE_BITS,
185 CONFIG_ETRAX_PE_CHANGEABLE_BITS, 164 CONFIG_ETRAX_PE_CHANGEABLE_BITS,
165#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
166 CONFIG_ETRAX_PV_CHANGEABLE_BITS,
167#endif
186}; 168};
187 169
188static volatile unsigned long *dir_oe[NUM_PORTS] = { 170static volatile unsigned long *dir_oe[NUM_PORTS] = {
@@ -192,13 +174,14 @@ static volatile unsigned long *dir_oe[NUM_PORTS] = {
192 GIO_REG_WR_ADDR(rw_pc_oe), 174 GIO_REG_WR_ADDR(rw_pc_oe),
193 GIO_REG_WR_ADDR(rw_pd_oe), 175 GIO_REG_WR_ADDR(rw_pd_oe),
194 GIO_REG_WR_ADDR(rw_pe_oe), 176 GIO_REG_WR_ADDR(rw_pe_oe),
177#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
178 &virtual_rw_pv_oe,
179#endif
195}; 180};
196 181
197 182
198 183
199static unsigned int 184static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
200gpio_poll(struct file *file,
201 poll_table *wait)
202{ 185{
203 unsigned int mask = 0; 186 unsigned int mask = 0;
204 struct gpio_private *priv = (struct gpio_private *)file->private_data; 187 struct gpio_private *priv = (struct gpio_private *)file->private_data;
@@ -210,65 +193,50 @@ gpio_poll(struct file *file,
210 unsigned long flags; 193 unsigned long flags;
211 194
212 local_irq_save(flags); 195 local_irq_save(flags);
213 data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, REG_RD(gio, regi_gio, r_pa_din)); 196 data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din,
197 REG_RD(gio, regi_gio, r_pa_din));
214 /* PA has support for interrupt 198 /* PA has support for interrupt
215 * lets activate high for those low and with highalarm set 199 * lets activate high for those low and with highalarm set
216 */ 200 */
217 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg); 201 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
218 202
219 tmp = ~data & priv->highalarm & 0xFF; 203 tmp = ~data & priv->highalarm & 0xFF;
220 if (tmp & (1 << 0)) { 204 if (tmp & (1 << 0))
221 intr_cfg.pa0 = regk_gio_hi; 205 intr_cfg.pa0 = regk_gio_hi;
222 } 206 if (tmp & (1 << 1))
223 if (tmp & (1 << 1)) {
224 intr_cfg.pa1 = regk_gio_hi; 207 intr_cfg.pa1 = regk_gio_hi;
225 } 208 if (tmp & (1 << 2))
226 if (tmp & (1 << 2)) {
227 intr_cfg.pa2 = regk_gio_hi; 209 intr_cfg.pa2 = regk_gio_hi;
228 } 210 if (tmp & (1 << 3))
229 if (tmp & (1 << 3)) {
230 intr_cfg.pa3 = regk_gio_hi; 211 intr_cfg.pa3 = regk_gio_hi;
231 } 212 if (tmp & (1 << 4))
232 if (tmp & (1 << 4)) {
233 intr_cfg.pa4 = regk_gio_hi; 213 intr_cfg.pa4 = regk_gio_hi;
234 } 214 if (tmp & (1 << 5))
235 if (tmp & (1 << 5)) {
236 intr_cfg.pa5 = regk_gio_hi; 215 intr_cfg.pa5 = regk_gio_hi;
237 } 216 if (tmp & (1 << 6))
238 if (tmp & (1 << 6)) {
239 intr_cfg.pa6 = regk_gio_hi; 217 intr_cfg.pa6 = regk_gio_hi;
240 } 218 if (tmp & (1 << 7))
241 if (tmp & (1 << 7)) {
242 intr_cfg.pa7 = regk_gio_hi; 219 intr_cfg.pa7 = regk_gio_hi;
243 }
244 /* 220 /*
245 * lets activate low for those high and with lowalarm set 221 * lets activate low for those high and with lowalarm set
246 */ 222 */
247 tmp = data & priv->lowalarm & 0xFF; 223 tmp = data & priv->lowalarm & 0xFF;
248 if (tmp & (1 << 0)) { 224 if (tmp & (1 << 0))
249 intr_cfg.pa0 = regk_gio_lo; 225 intr_cfg.pa0 = regk_gio_lo;
250 } 226 if (tmp & (1 << 1))
251 if (tmp & (1 << 1)) {
252 intr_cfg.pa1 = regk_gio_lo; 227 intr_cfg.pa1 = regk_gio_lo;
253 } 228 if (tmp & (1 << 2))
254 if (tmp & (1 << 2)) {
255 intr_cfg.pa2 = regk_gio_lo; 229 intr_cfg.pa2 = regk_gio_lo;
256 } 230 if (tmp & (1 << 3))
257 if (tmp & (1 << 3)) {
258 intr_cfg.pa3 = regk_gio_lo; 231 intr_cfg.pa3 = regk_gio_lo;
259 } 232 if (tmp & (1 << 4))
260 if (tmp & (1 << 4)) {
261 intr_cfg.pa4 = regk_gio_lo; 233 intr_cfg.pa4 = regk_gio_lo;
262 } 234 if (tmp & (1 << 5))
263 if (tmp & (1 << 5)) {
264 intr_cfg.pa5 = regk_gio_lo; 235 intr_cfg.pa5 = regk_gio_lo;
265 } 236 if (tmp & (1 << 6))
266 if (tmp & (1 << 6)) {
267 intr_cfg.pa6 = regk_gio_lo; 237 intr_cfg.pa6 = regk_gio_lo;
268 } 238 if (tmp & (1 << 7))
269 if (tmp & (1 << 7)) {
270 intr_cfg.pa7 = regk_gio_lo; 239 intr_cfg.pa7 = regk_gio_lo;
271 }
272 240
273 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg); 241 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
274 local_irq_restore(flags); 242 local_irq_restore(flags);
@@ -277,50 +245,65 @@ gpio_poll(struct file *file,
277 else 245 else
278 return 0; 246 return 0;
279 247
280 if ((data & priv->highalarm) || 248 if ((data & priv->highalarm) || (~data & priv->lowalarm))
281 (~data & priv->lowalarm)) {
282 mask = POLLIN|POLLRDNORM; 249 mask = POLLIN|POLLRDNORM;
283 }
284 250
285 DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); 251 DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
286 return mask; 252 return mask;
287} 253}
288 254
289int etrax_gpio_wake_up_check(void) 255int etrax_gpio_wake_up_check(void)
290{ 256{
291 struct gpio_private *priv = alarmlist; 257 struct gpio_private *priv;
292 unsigned long data = 0; 258 unsigned long data = 0;
293 int ret = 0; 259 unsigned long flags;
260 int ret = 0;
261 spin_lock_irqsave(&alarm_lock, flags);
262 priv = alarmlist;
294 while (priv) { 263 while (priv) {
264#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
265 if (priv->minor == GPIO_MINOR_V)
266 data = (unsigned long)cached_virtual_gpio_read;
267 else {
268 data = *data_in[priv->minor];
269 if (priv->minor == GPIO_MINOR_A)
270 priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
271 }
272#else
295 data = *data_in[priv->minor]; 273 data = *data_in[priv->minor];
274#endif
296 if ((data & priv->highalarm) || 275 if ((data & priv->highalarm) ||
297 (~data & priv->lowalarm)) { 276 (~data & priv->lowalarm)) {
298 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor)); 277 DP(printk(KERN_DEBUG
278 "etrax_gpio_wake_up_check %i\n", priv->minor));
299 wake_up_interruptible(&priv->alarm_wq); 279 wake_up_interruptible(&priv->alarm_wq);
300 ret = 1; 280 ret = 1;
301 } 281 }
302 priv = priv->next; 282 priv = priv->next;
303 } 283 }
304 return ret; 284 spin_unlock_irqrestore(&alarm_lock, flags);
285 return ret;
305} 286}
306 287
307static irqreturn_t 288static irqreturn_t
308gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 289gpio_poll_timer_interrupt(int irq, void *dev_id)
309{ 290{
310 if (gpio_some_alarms) { 291 if (gpio_some_alarms)
311 return IRQ_RETVAL(etrax_gpio_wake_up_check()); 292 return IRQ_RETVAL(etrax_gpio_wake_up_check());
312 } 293 return IRQ_NONE;
313 return IRQ_NONE;
314} 294}
315 295
316static irqreturn_t 296static irqreturn_t
317gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) 297gpio_pa_interrupt(int irq, void *dev_id)
318{ 298{
319 reg_gio_rw_intr_mask intr_mask; 299 reg_gio_rw_intr_mask intr_mask;
320 reg_gio_r_masked_intr masked_intr; 300 reg_gio_r_masked_intr masked_intr;
321 reg_gio_rw_ack_intr ack_intr; 301 reg_gio_rw_ack_intr ack_intr;
322 unsigned long tmp; 302 unsigned long tmp;
323 unsigned long tmp2; 303 unsigned long tmp2;
304#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
305 unsigned char enable_gpiov_ack = 0;
306#endif
324 307
325 /* Find what PA interrupts are active */ 308 /* Find what PA interrupts are active */
326 masked_intr = REG_RD(gio, regi_gio, r_masked_intr); 309 masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
@@ -331,6 +314,17 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
331 tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms); 314 tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
332 spin_unlock(&alarm_lock); 315 spin_unlock(&alarm_lock);
333 316
317#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
318 /* Something changed on virtual GPIO. Interrupt is acked by
319 * reading the device.
320 */
321 if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
322 i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
323 sizeof(cached_virtual_gpio_read));
324 enable_gpiov_ack = 1;
325 }
326#endif
327
334 /* Ack them */ 328 /* Ack them */
335 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp); 329 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
336 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr); 330 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
@@ -339,18 +333,24 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
339 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); 333 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
340 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask); 334 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
341 tmp2 &= ~tmp; 335 tmp2 &= ~tmp;
336#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
337 /* Do not disable interrupt on virtual GPIO. Changes on virtual
338 * pins are only noticed by an interrupt.
339 */
340 if (enable_gpiov_ack)
341 tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
342#endif
342 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2); 343 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
343 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); 344 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
344 345
345 if (gpio_some_alarms) { 346 if (gpio_some_alarms)
346 return IRQ_RETVAL(etrax_gpio_wake_up_check()); 347 return IRQ_RETVAL(etrax_gpio_wake_up_check());
347 } 348 return IRQ_NONE;
348 return IRQ_NONE;
349} 349}
350 350
351 351
352static ssize_t gpio_write(struct file * file, const char * buf, size_t count, 352static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
353 loff_t *off) 353 loff_t *off)
354{ 354{
355 struct gpio_private *priv = (struct gpio_private *)file->private_data; 355 struct gpio_private *priv = (struct gpio_private *)file->private_data;
356 unsigned char data, clk_mask, data_mask, write_msb; 356 unsigned char data, clk_mask, data_mask, write_msb;
@@ -360,29 +360,31 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
360 ssize_t retval = count; 360 ssize_t retval = count;
361 /* Only bits 0-7 may be used for write operations but allow all 361 /* Only bits 0-7 may be used for write operations but allow all
362 devices except leds... */ 362 devices except leds... */
363 if (priv->minor == GPIO_MINOR_LEDS) { 363#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
364 if (priv->minor == GPIO_MINOR_V)
365 return -EFAULT;
366#endif
367 if (priv->minor == GPIO_MINOR_LEDS)
364 return -EFAULT; 368 return -EFAULT;
365 }
366 369
367 if (!access_ok(VERIFY_READ, buf, count)) { 370 if (!access_ok(VERIFY_READ, buf, count))
368 return -EFAULT; 371 return -EFAULT;
369 }
370 clk_mask = priv->clk_mask; 372 clk_mask = priv->clk_mask;
371 data_mask = priv->data_mask; 373 data_mask = priv->data_mask;
372 /* It must have been configured using the IO_CFG_WRITE_MODE */ 374 /* It must have been configured using the IO_CFG_WRITE_MODE */
373 /* Perhaps a better error code? */ 375 /* Perhaps a better error code? */
374 if (clk_mask == 0 || data_mask == 0) { 376 if (clk_mask == 0 || data_mask == 0)
375 return -EPERM; 377 return -EPERM;
376 }
377 write_msb = priv->write_msb; 378 write_msb = priv->write_msb;
378 D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); 379 D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
380 "msb: %i\n", count, data_mask, clk_mask, write_msb));
379 port = data_out[priv->minor]; 381 port = data_out[priv->minor];
380 382
381 while (count--) { 383 while (count--) {
382 int i; 384 int i;
383 data = *buf++; 385 data = *buf++;
384 if (priv->write_msb) { 386 if (priv->write_msb) {
385 for (i = 7; i >= 0;i--) { 387 for (i = 7; i >= 0; i--) {
386 local_irq_save(flags); 388 local_irq_save(flags);
387 shadow = *port; 389 shadow = *port;
388 *port = shadow &= ~clk_mask; 390 *port = shadow &= ~clk_mask;
@@ -395,7 +397,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
395 local_irq_restore(flags); 397 local_irq_restore(flags);
396 } 398 }
397 } else { 399 } else {
398 for (i = 0; i <= 7;i++) { 400 for (i = 0; i <= 7; i++) {
399 local_irq_save(flags); 401 local_irq_save(flags);
400 shadow = *port; 402 shadow = *port;
401 *port = shadow &= ~clk_mask; 403 *port = shadow &= ~clk_mask;
@@ -423,18 +425,16 @@ gpio_open(struct inode *inode, struct file *filp)
423 if (p > GPIO_MINOR_LAST) 425 if (p > GPIO_MINOR_LAST)
424 return -EINVAL; 426 return -EINVAL;
425 427
426 priv = kmalloc(sizeof(struct gpio_private), 428 priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
427 GFP_KERNEL);
428 429
429 if (!priv) 430 if (!priv)
430 return -ENOMEM; 431 return -ENOMEM;
432 memset(priv, 0, sizeof(*priv));
431 433
432 priv->minor = p; 434 priv->minor = p;
433 435
434 /* initialize the io/alarm struct and link it into our alarmlist */ 436 /* initialize the io/alarm struct */
435 437
436 priv->next = alarmlist;
437 alarmlist = priv;
438 priv->clk_mask = 0; 438 priv->clk_mask = 0;
439 priv->data_mask = 0; 439 priv->data_mask = 0;
440 priv->highalarm = 0; 440 priv->highalarm = 0;
@@ -443,20 +443,30 @@ gpio_open(struct inode *inode, struct file *filp)
443 443
444 filp->private_data = (void *)priv; 444 filp->private_data = (void *)priv;
445 445
446 /* link it into our alarmlist */
447 spin_lock_irq(&alarm_lock);
448 priv->next = alarmlist;
449 alarmlist = priv;
450 spin_unlock_irq(&alarm_lock);
451
446 return 0; 452 return 0;
447} 453}
448 454
449static int 455static int
450gpio_release(struct inode *inode, struct file *filp) 456gpio_release(struct inode *inode, struct file *filp)
451{ 457{
452 struct gpio_private *p = alarmlist; 458 struct gpio_private *p;
453 struct gpio_private *todel = (struct gpio_private *)filp->private_data; 459 struct gpio_private *todel;
454 /* local copies while updating them: */ 460 /* local copies while updating them: */
455 unsigned long a_high, a_low; 461 unsigned long a_high, a_low;
456 unsigned long some_alarms; 462 unsigned long some_alarms;
457 463
458 /* unlink from alarmlist and free the private structure */ 464 /* unlink from alarmlist and free the private structure */
459 465
466 spin_lock_irq(&alarm_lock);
467 p = alarmlist;
468 todel = (struct gpio_private *)filp->private_data;
469
460 if (p == todel) { 470 if (p == todel) {
461 alarmlist = todel->next; 471 alarmlist = todel->next;
462 } else { 472 } else {
@@ -468,26 +478,35 @@ gpio_release(struct inode *inode, struct file *filp)
468 kfree(todel); 478 kfree(todel);
469 /* Check if there are still any alarms set */ 479 /* Check if there are still any alarms set */
470 p = alarmlist; 480 p = alarmlist;
471 some_alarms = 0; 481 some_alarms = 0;
472 a_high = 0; 482 a_high = 0;
473 a_low = 0; 483 a_low = 0;
474 while (p) { 484 while (p) {
475 if (p->minor == GPIO_MINOR_A) { 485 if (p->minor == GPIO_MINOR_A) {
486#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
487 p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
488#endif
476 a_high |= p->highalarm; 489 a_high |= p->highalarm;
477 a_low |= p->lowalarm; 490 a_low |= p->lowalarm;
478 } 491 }
479 492
480 if (p->highalarm | p->lowalarm) { 493 if (p->highalarm | p->lowalarm)
481 some_alarms = 1; 494 some_alarms = 1;
482 }
483 p = p->next; 495 p = p->next;
484 } 496 }
485 497
486 spin_lock(&alarm_lock); 498#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
499 /* Variables 'some_alarms' and 'a_low' needs to be set here again
500 * to ensure that interrupt for virtual GPIO is handled.
501 */
502 some_alarms = 1;
503 a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
504#endif
505
487 gpio_some_alarms = some_alarms; 506 gpio_some_alarms = some_alarms;
488 gpio_pa_high_alarms = a_high; 507 gpio_pa_high_alarms = a_high;
489 gpio_pa_low_alarms = a_low; 508 gpio_pa_low_alarms = a_low;
490 spin_unlock(&alarm_lock); 509 spin_unlock_irq(&alarm_lock);
491 510
492 return 0; 511 return 0;
493} 512}
@@ -496,7 +515,7 @@ gpio_release(struct inode *inode, struct file *filp)
496 * set alarms to wait for using a subsequent select(). 515 * set alarms to wait for using a subsequent select().
497 */ 516 */
498 517
499unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) 518inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
500{ 519{
501 /* Set direction 0=unchanged 1=input, 520 /* Set direction 0=unchanged 1=input,
502 * return mask with 1=input 521 * return mask with 1=input
@@ -512,13 +531,17 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
512 531
513 if (priv->minor == GPIO_MINOR_A) 532 if (priv->minor == GPIO_MINOR_A)
514 dir_shadow ^= 0xFF; /* Only 8 bits */ 533 dir_shadow ^= 0xFF; /* Only 8 bits */
534#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
535 else if (priv->minor == GPIO_MINOR_V)
536 dir_shadow ^= 0xFFFF; /* Only 16 bits */
537#endif
515 else 538 else
516 dir_shadow ^= 0x3FFFF; /* Only 18 bits */ 539 dir_shadow ^= 0x3FFFF; /* Only 18 bits */
517 return dir_shadow; 540 return dir_shadow;
518 541
519} /* setget_input */ 542} /* setget_input */
520 543
521unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) 544inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg)
522{ 545{
523 unsigned long flags; 546 unsigned long flags;
524 unsigned long dir_shadow; 547 unsigned long dir_shadow;
@@ -542,20 +565,22 @@ gpio_ioctl(struct inode *inode, struct file *file,
542 unsigned long val; 565 unsigned long val;
543 unsigned long shadow; 566 unsigned long shadow;
544 struct gpio_private *priv = (struct gpio_private *)file->private_data; 567 struct gpio_private *priv = (struct gpio_private *)file->private_data;
545 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { 568 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
546 return -EINVAL; 569 return -EINVAL;
547 } 570
571#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
572 if (priv->minor == GPIO_MINOR_V)
573 return virtual_gpio_ioctl(file, cmd, arg);
574#endif
548 575
549 switch (_IOC_NR(cmd)) { 576 switch (_IOC_NR(cmd)) {
550 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ 577 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
551 // read the port 578 /* Read the port. */
552 return *data_in[priv->minor]; 579 return *data_in[priv->minor];
553 break; 580 break;
554 case IO_SETBITS: 581 case IO_SETBITS:
555 local_irq_save(flags); 582 local_irq_save(flags);
556 if (arg & 0x04) 583 /* Set changeable bits with a 1 in arg. */
557 printk("GPIO SET 2\n");
558 // set changeable bits with a 1 in arg
559 shadow = *data_out[priv->minor]; 584 shadow = *data_out[priv->minor];
560 shadow |= (arg & changeable_bits[priv->minor]); 585 shadow |= (arg & changeable_bits[priv->minor]);
561 *data_out[priv->minor] = shadow; 586 *data_out[priv->minor] = shadow;
@@ -563,46 +588,42 @@ gpio_ioctl(struct inode *inode, struct file *file,
563 break; 588 break;
564 case IO_CLRBITS: 589 case IO_CLRBITS:
565 local_irq_save(flags); 590 local_irq_save(flags);
566 if (arg & 0x04) 591 /* Clear changeable bits with a 1 in arg. */
567 printk("GPIO CLR 2\n");
568 // clear changeable bits with a 1 in arg
569 shadow = *data_out[priv->minor]; 592 shadow = *data_out[priv->minor];
570 shadow &= ~(arg & changeable_bits[priv->minor]); 593 shadow &= ~(arg & changeable_bits[priv->minor]);
571 *data_out[priv->minor] = shadow; 594 *data_out[priv->minor] = shadow;
572 local_irq_restore(flags); 595 local_irq_restore(flags);
573 break; 596 break;
574 case IO_HIGHALARM: 597 case IO_HIGHALARM:
575 // set alarm when bits with 1 in arg go high 598 /* Set alarm when bits with 1 in arg go high. */
576 priv->highalarm |= arg; 599 priv->highalarm |= arg;
577 spin_lock(&alarm_lock); 600 spin_lock_irqsave(&alarm_lock, flags);
578 gpio_some_alarms = 1; 601 gpio_some_alarms = 1;
579 if (priv->minor == GPIO_MINOR_A) { 602 if (priv->minor == GPIO_MINOR_A)
580 gpio_pa_high_alarms |= arg; 603 gpio_pa_high_alarms |= arg;
581 } 604 spin_unlock_irqrestore(&alarm_lock, flags);
582 spin_unlock(&alarm_lock);
583 break; 605 break;
584 case IO_LOWALARM: 606 case IO_LOWALARM:
585 // set alarm when bits with 1 in arg go low 607 /* Set alarm when bits with 1 in arg go low. */
586 priv->lowalarm |= arg; 608 priv->lowalarm |= arg;
587 spin_lock(&alarm_lock); 609 spin_lock_irqsave(&alarm_lock, flags);
588 gpio_some_alarms = 1; 610 gpio_some_alarms = 1;
589 if (priv->minor == GPIO_MINOR_A) { 611 if (priv->minor == GPIO_MINOR_A)
590 gpio_pa_low_alarms |= arg; 612 gpio_pa_low_alarms |= arg;
591 } 613 spin_unlock_irqrestore(&alarm_lock, flags);
592 spin_unlock(&alarm_lock);
593 break; 614 break;
594 case IO_CLRALARM: 615 case IO_CLRALARM:
595 // clear alarm for bits with 1 in arg 616 /* Clear alarm for bits with 1 in arg. */
596 priv->highalarm &= ~arg; 617 priv->highalarm &= ~arg;
597 priv->lowalarm &= ~arg; 618 priv->lowalarm &= ~arg;
598 spin_lock(&alarm_lock); 619 spin_lock_irqsave(&alarm_lock, flags);
599 if (priv->minor == GPIO_MINOR_A) { 620 if (priv->minor == GPIO_MINOR_A) {
600 if (gpio_pa_high_alarms & arg || 621 if (gpio_pa_high_alarms & arg ||
601 gpio_pa_low_alarms & arg) { 622 gpio_pa_low_alarms & arg)
602 /* Must update the gpio_pa_*alarms masks */ 623 /* Must update the gpio_pa_*alarms masks */
603 } 624 ;
604 } 625 }
605 spin_unlock(&alarm_lock); 626 spin_unlock_irqrestore(&alarm_lock, flags);
606 break; 627 break;
607 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ 628 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
608 /* Read direction 0=input 1=output */ 629 /* Read direction 0=input 1=output */
@@ -633,8 +654,7 @@ gpio_ioctl(struct inode *inode, struct file *file,
633 if (!((priv->clk_mask & changeable_bits[priv->minor]) && 654 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
634 (priv->data_mask & changeable_bits[priv->minor]) && 655 (priv->data_mask & changeable_bits[priv->minor]) &&
635 (priv->clk_mask & dir_shadow) && 656 (priv->clk_mask & dir_shadow) &&
636 (priv->data_mask & dir_shadow))) 657 (priv->data_mask & dir_shadow))) {
637 {
638 priv->clk_mask = 0; 658 priv->clk_mask = 0;
639 priv->data_mask = 0; 659 priv->data_mask = 0;
640 return -EPERM; 660 return -EPERM;
@@ -644,34 +664,34 @@ gpio_ioctl(struct inode *inode, struct file *file,
644 case IO_READ_INBITS: 664 case IO_READ_INBITS:
645 /* *arg is result of reading the input pins */ 665 /* *arg is result of reading the input pins */
646 val = *data_in[priv->minor]; 666 val = *data_in[priv->minor];
647 if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) 667 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
648 return -EFAULT; 668 return -EFAULT;
649 return 0; 669 return 0;
650 break; 670 break;
651 case IO_READ_OUTBITS: 671 case IO_READ_OUTBITS:
652 /* *arg is result of reading the output shadow */ 672 /* *arg is result of reading the output shadow */
653 val = *data_out[priv->minor]; 673 val = *data_out[priv->minor];
654 if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) 674 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
655 return -EFAULT; 675 return -EFAULT;
656 break; 676 break;
657 case IO_SETGET_INPUT: 677 case IO_SETGET_INPUT:
658 /* bits set in *arg is set to input, 678 /* bits set in *arg is set to input,
659 * *arg updated with current input pins. 679 * *arg updated with current input pins.
660 */ 680 */
661 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) 681 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
662 return -EFAULT; 682 return -EFAULT;
663 val = setget_input(priv, val); 683 val = setget_input(priv, val);
664 if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) 684 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
665 return -EFAULT; 685 return -EFAULT;
666 break; 686 break;
667 case IO_SETGET_OUTPUT: 687 case IO_SETGET_OUTPUT:
668 /* bits set in *arg is set to output, 688 /* bits set in *arg is set to output,
669 * *arg updated with current output pins. 689 * *arg updated with current output pins.
670 */ 690 */
671 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) 691 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
672 return -EFAULT; 692 return -EFAULT;
673 val = setget_output(priv, val); 693 val = setget_output(priv, val);
674 if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) 694 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
675 return -EFAULT; 695 return -EFAULT;
676 break; 696 break;
677 default: 697 default:
@@ -684,6 +704,133 @@ gpio_ioctl(struct inode *inode, struct file *file,
684 return 0; 704 return 0;
685} 705}
686 706
707#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
708static int
709virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
710{
711 unsigned long flags;
712 unsigned short val;
713 unsigned short shadow;
714 struct gpio_private *priv = (struct gpio_private *)file->private_data;
715
716 switch (_IOC_NR(cmd)) {
717 case IO_SETBITS:
718 local_irq_save(flags);
719 /* Set changeable bits with a 1 in arg. */
720 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
721 shadow |= ~*dir_oe[priv->minor];
722 shadow |= (arg & changeable_bits[priv->minor]);
723 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
724 local_irq_restore(flags);
725 break;
726 case IO_CLRBITS:
727 local_irq_save(flags);
728 /* Clear changeable bits with a 1 in arg. */
729 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
730 shadow |= ~*dir_oe[priv->minor];
731 shadow &= ~(arg & changeable_bits[priv->minor]);
732 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
733 local_irq_restore(flags);
734 break;
735 case IO_HIGHALARM:
736 /* Set alarm when bits with 1 in arg go high. */
737 priv->highalarm |= arg;
738 spin_lock(&alarm_lock);
739 gpio_some_alarms = 1;
740 spin_unlock(&alarm_lock);
741 break;
742 case IO_LOWALARM:
743 /* Set alarm when bits with 1 in arg go low. */
744 priv->lowalarm |= arg;
745 spin_lock(&alarm_lock);
746 gpio_some_alarms = 1;
747 spin_unlock(&alarm_lock);
748 break;
749 case IO_CLRALARM:
750 /* Clear alarm for bits with 1 in arg. */
751 priv->highalarm &= ~arg;
752 priv->lowalarm &= ~arg;
753 spin_lock(&alarm_lock);
754 spin_unlock(&alarm_lock);
755 break;
756 case IO_CFG_WRITE_MODE:
757 {
758 unsigned long dir_shadow;
759 dir_shadow = *dir_oe[priv->minor];
760
761 priv->clk_mask = arg & 0xFF;
762 priv->data_mask = (arg >> 8) & 0xFF;
763 priv->write_msb = (arg >> 16) & 0x01;
764 /* Check if we're allowed to change the bits and
765 * the direction is correct
766 */
767 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
768 (priv->data_mask & changeable_bits[priv->minor]) &&
769 (priv->clk_mask & dir_shadow) &&
770 (priv->data_mask & dir_shadow))) {
771 priv->clk_mask = 0;
772 priv->data_mask = 0;
773 return -EPERM;
774 }
775 break;
776 }
777 case IO_READ_INBITS:
778 /* *arg is result of reading the input pins */
779 val = cached_virtual_gpio_read;
780 val &= ~*dir_oe[priv->minor];
781 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
782 return -EFAULT;
783 return 0;
784 break;
785 case IO_READ_OUTBITS:
786 /* *arg is result of reading the output shadow */
787 i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
788 val &= *dir_oe[priv->minor];
789 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
790 return -EFAULT;
791 break;
792 case IO_SETGET_INPUT:
793 {
794 /* bits set in *arg is set to input,
795 * *arg updated with current input pins.
796 */
797 unsigned short input_mask = ~*dir_oe[priv->minor];
798 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
799 return -EFAULT;
800 val = setget_input(priv, val);
801 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
802 return -EFAULT;
803 if ((input_mask & val) != input_mask) {
804 /* Input pins changed. All ports desired as input
805 * should be set to logic 1.
806 */
807 unsigned short change = input_mask ^ val;
808 i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
809 sizeof(shadow));
810 shadow &= ~change;
811 shadow |= val;
812 i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
813 sizeof(shadow));
814 }
815 break;
816 }
817 case IO_SETGET_OUTPUT:
818 /* bits set in *arg is set to output,
819 * *arg updated with current output pins.
820 */
821 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
822 return -EFAULT;
823 val = setget_output(priv, val);
824 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
825 return -EFAULT;
826 break;
827 default:
828 return -EINVAL;
829 } /* switch */
830 return 0;
831}
832#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
833
687static int 834static int
688gpio_leds_ioctl(unsigned int cmd, unsigned long arg) 835gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
689{ 836{
@@ -694,8 +841,8 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
694 case IO_LEDACTIVE_SET: 841 case IO_LEDACTIVE_SET:
695 green = ((unsigned char) arg) & 1; 842 green = ((unsigned char) arg) & 1;
696 red = (((unsigned char) arg) >> 1) & 1; 843 red = (((unsigned char) arg) >> 1) & 1;
697 LED_ACTIVE_SET_G(green); 844 CRIS_LED_ACTIVE_SET_G(green);
698 LED_ACTIVE_SET_R(red); 845 CRIS_LED_ACTIVE_SET_R(red);
699 break; 846 break;
700 847
701 default: 848 default:
@@ -705,7 +852,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
705 return 0; 852 return 0;
706} 853}
707 854
708const struct file_operations gpio_fops = { 855struct file_operations gpio_fops = {
709 .owner = THIS_MODULE, 856 .owner = THIS_MODULE,
710 .poll = gpio_poll, 857 .poll = gpio_poll,
711 .ioctl = gpio_ioctl, 858 .ioctl = gpio_ioctl,
@@ -714,6 +861,66 @@ const struct file_operations gpio_fops = {
714 .release = gpio_release, 861 .release = gpio_release,
715}; 862};
716 863
864#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
865static void
866virtual_gpio_init(void)
867{
868 reg_gio_rw_intr_cfg intr_cfg;
869 reg_gio_rw_intr_mask intr_mask;
870 unsigned short shadow;
871
872 shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
873 shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
874 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
875
876 /* Set interrupt mask and on what state the interrupt shall trigger.
877 * For virtual gpio the interrupt shall trigger on logic '0'.
878 */
879 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
880 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
881
882 switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
883 case 0:
884 intr_cfg.pa0 = regk_gio_lo;
885 intr_mask.pa0 = regk_gio_yes;
886 break;
887 case 1:
888 intr_cfg.pa1 = regk_gio_lo;
889 intr_mask.pa1 = regk_gio_yes;
890 break;
891 case 2:
892 intr_cfg.pa2 = regk_gio_lo;
893 intr_mask.pa2 = regk_gio_yes;
894 break;
895 case 3:
896 intr_cfg.pa3 = regk_gio_lo;
897 intr_mask.pa3 = regk_gio_yes;
898 break;
899 case 4:
900 intr_cfg.pa4 = regk_gio_lo;
901 intr_mask.pa4 = regk_gio_yes;
902 break;
903 case 5:
904 intr_cfg.pa5 = regk_gio_lo;
905 intr_mask.pa5 = regk_gio_yes;
906 break;
907 case 6:
908 intr_cfg.pa6 = regk_gio_lo;
909 intr_mask.pa6 = regk_gio_yes;
910 break;
911 case 7:
912 intr_cfg.pa7 = regk_gio_lo;
913 intr_mask.pa7 = regk_gio_yes;
914 break;
915 }
916
917 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
918 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
919
920 gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
921 gpio_some_alarms = 1;
922}
923#endif
717 924
718/* main driver initialization routine, called from mem.c */ 925/* main driver initialization routine, called from mem.c */
719 926
@@ -721,7 +928,6 @@ static __init int
721gpio_init(void) 928gpio_init(void)
722{ 929{
723 int res; 930 int res;
724 reg_intr_vect_rw_mask intr_mask;
725 931
726 /* do the formalities */ 932 /* do the formalities */
727 933
@@ -732,30 +938,30 @@ gpio_init(void)
732 } 938 }
733 939
734 /* Clear all leds */ 940 /* Clear all leds */
735 LED_NETWORK_SET(0); 941 CRIS_LED_NETWORK_GRP0_SET(0);
736 LED_ACTIVE_SET(0); 942 CRIS_LED_NETWORK_GRP1_SET(0);
737 LED_DISK_READ(0); 943 CRIS_LED_ACTIVE_SET(0);
738 LED_DISK_WRITE(0); 944 CRIS_LED_DISK_READ(0);
739 945 CRIS_LED_DISK_WRITE(0);
740 printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n"); 946
947 printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
948 "Axis Communications AB\n");
741 /* We call etrax_gpio_wake_up_check() from timer interrupt and 949 /* We call etrax_gpio_wake_up_check() from timer interrupt and
742 * from cpu_idle() in kernel/process.c 950 * from cpu_idle() in kernel/process.c
743 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms 951 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
744 * in some tests. 952 * in some tests.
745 */ 953 */
746 if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt, 954 if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt,
747 IRQF_SHARED | IRQF_DISABLED,"gpio poll", &alarmlist)) { 955 IRQF_SHARED | IRQF_DISABLED, "gpio poll", &alarmlist))
748 printk("err: timer0 irq for gpio\n"); 956 printk(KERN_ERR "timer0 irq for gpio\n");
749 } 957
750 if (request_irq(GEN_IO_INTR_VECT, gpio_pa_interrupt, 958 if (request_irq(GIO_INTR_VECT, gpio_pa_interrupt,
751 IRQF_SHARED | IRQF_DISABLED,"gpio PA", &alarmlist)) { 959 IRQF_SHARED | IRQF_DISABLED, "gpio PA", &alarmlist))
752 printk("err: PA irq for gpio\n"); 960 printk(KERN_ERR "PA irq for gpio\n");
753 } 961
754 /* enable the gio and timer irq in global config */ 962#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
755 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); 963 virtual_gpio_init();
756 intr_mask.timer = 1; 964#endif
757 intr_mask.gen_io = 1;
758 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
759 965
760 return res; 966 return res;
761} 967}
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c
index 5ce015c6bb0d..aa01b134458a 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c
@@ -4,9 +4,7 @@
4 * Copyright (c) 2004 4 * Copyright (c) 2004
5 * 5 *
6 * Derived from drivers/mtd/nand/spia.c 6 * Derived from drivers/mtd/nand/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 *
9 * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $
10 * 8 *
11 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -21,10 +19,10 @@
21#include <linux/mtd/nand.h> 19#include <linux/mtd/nand.h>
22#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
23#include <asm/arch/memmap.h> 21#include <asm/arch/memmap.h>
24#include <asm/arch/hwregs/reg_map.h> 22#include <hwregs/reg_map.h>
25#include <asm/arch/hwregs/reg_rdwr.h> 23#include <hwregs/reg_rdwr.h>
26#include <asm/arch/hwregs/gio_defs.h> 24#include <hwregs/gio_defs.h>
27#include <asm/arch/hwregs/bif_core_defs.h> 25#include <hwregs/bif_core_defs.h>
28#include <asm/io.h> 26#include <asm/io.h>
29 27
30#define CE_BIT 4 28#define CE_BIT 4
@@ -32,44 +30,65 @@
32#define ALE_BIT 6 30#define ALE_BIT 6
33#define BY_BIT 7 31#define BY_BIT 7
34 32
35static struct mtd_info *crisv32_mtd = NULL; 33struct mtd_info_wrapper {
34 struct mtd_info info;
35 struct nand_chip chip;
36};
37
38/* Bitmask for control pins */
39#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
40
41/* Bitmask for mtd nand control bits */
42#define CTRL_BITMASK (NAND_NCE | NAND_CLE | NAND_ALE)
43
44
45static struct mtd_info *crisv32_mtd;
36/* 46/*
37 * hardware specific access to control-lines 47 * hardware specific access to control-lines
38*/ 48 */
39static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd) 49static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
50 unsigned int ctrl)
40{ 51{
41 unsigned long flags; 52 unsigned long flags;
42 reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout); 53 reg_gio_rw_pa_dout dout;
54 struct nand_chip *this = mtd->priv;
43 55
44 local_irq_save(flags); 56 local_irq_save(flags);
45 switch(cmd){ 57
46 case NAND_CTL_SETCLE: 58 /* control bits change */
47 dout.data |= (1<<CLE_BIT); 59 if (ctrl & NAND_CTRL_CHANGE) {
48 break; 60 dout = REG_RD(gio, regi_gio, rw_pa_dout);
49 case NAND_CTL_CLRCLE: 61 dout.data &= ~PIN_BITMASK;
50 dout.data &= ~(1<<CLE_BIT); 62
51 break; 63#if (CE_BIT == 4 && NAND_NCE == 1 && \
52 case NAND_CTL_SETALE: 64 CLE_BIT == 5 && NAND_CLE == 2 && \
53 dout.data |= (1<<ALE_BIT); 65 ALE_BIT == 6 && NAND_ALE == 4)
54 break; 66 /* Pins in same order as control bits, but shifted.
55 case NAND_CTL_CLRALE: 67 * Optimize for this case; works for 2.6.18 */
56 dout.data &= ~(1<<ALE_BIT); 68 dout.data |= ((ctrl & CTRL_BITMASK) ^ NAND_NCE) << CE_BIT;
57 break; 69#else
58 case NAND_CTL_SETNCE: 70 /* the slow way */
59 dout.data |= (1<<CE_BIT); 71 if (!(ctrl & NAND_NCE))
60 break; 72 dout.data |= (1 << CE_BIT);
61 case NAND_CTL_CLRNCE: 73 if (ctrl & NAND_CLE)
62 dout.data &= ~(1<<CE_BIT); 74 dout.data |= (1 << CLE_BIT);
63 break; 75 if (ctrl & NAND_ALE)
76 dout.data |= (1 << ALE_BIT);
77#endif
78 REG_WR(gio, regi_gio, rw_pa_dout, dout);
64 } 79 }
65 REG_WR(gio, regi_gio, rw_pa_dout, dout); 80
81 /* command to chip */
82 if (cmd != NAND_CMD_NONE)
83 writeb(cmd, this->IO_ADDR_W);
84
66 local_irq_restore(flags); 85 local_irq_restore(flags);
67} 86}
68 87
69/* 88/*
70* read device ready pin 89* read device ready pin
71*/ 90*/
72int crisv32_device_ready(struct mtd_info *mtd) 91static int crisv32_device_ready(struct mtd_info *mtd)
73{ 92{
74 reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din); 93 reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din);
75 return ((din.data & (1 << BY_BIT)) >> BY_BIT); 94 return ((din.data & (1 << BY_BIT)) >> BY_BIT);
@@ -78,21 +97,23 @@ int crisv32_device_ready(struct mtd_info *mtd)
78/* 97/*
79 * Main initialization routine 98 * Main initialization routine
80 */ 99 */
81struct mtd_info* __init crisv32_nand_flash_probe (void) 100struct mtd_info *__init crisv32_nand_flash_probe(void)
82{ 101{
83 void __iomem *read_cs; 102 void __iomem *read_cs;
84 void __iomem *write_cs; 103 void __iomem *write_cs;
85 104
86 reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg); 105 reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core,
106 rw_grp3_cfg);
87 reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe); 107 reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe);
108 struct mtd_info_wrapper *wrapper;
88 struct nand_chip *this; 109 struct nand_chip *this;
89 int err = 0; 110 int err = 0;
90 111
91 /* Allocate memory for MTD device structure and private data */ 112 /* Allocate memory for MTD device structure and private data */
92 crisv32_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), 113 wrapper = kzalloc(sizeof(struct mtd_info_wrapper), GFP_KERNEL);
93 GFP_KERNEL); 114 if (!wrapper) {
94 if (!crisv32_mtd) { 115 printk(KERN_ERR "Unable to allocate CRISv32 NAND MTD "
95 printk ("Unable to allocate CRISv32 NAND MTD device structure.\n"); 116 "device structure.\n");
96 err = -ENOMEM; 117 err = -ENOMEM;
97 return NULL; 118 return NULL;
98 } 119 }
@@ -101,45 +122,42 @@ struct mtd_info* __init crisv32_nand_flash_probe (void)
101 write_cs = ioremap(MEM_CSP1_START | MEM_NON_CACHEABLE, 8192); 122 write_cs = ioremap(MEM_CSP1_START | MEM_NON_CACHEABLE, 8192);
102 123
103 if (!read_cs || !write_cs) { 124 if (!read_cs || !write_cs) {
104 printk("CRISv32 NAND ioremap failed\n"); 125 printk(KERN_ERR "CRISv32 NAND ioremap failed\n");
105 err = -EIO; 126 err = -EIO;
106 goto out_mtd; 127 goto out_mtd;
107 } 128 }
108 129
109 /* Get pointer to private data */ 130 /* Get pointer to private data */
110 this = (struct nand_chip *) (&crisv32_mtd[1]); 131 this = &wrapper->chip;
132 crisv32_mtd = &wrapper->info;
111 133
112 pa_oe.oe |= 1 << CE_BIT; 134 pa_oe.oe |= 1 << CE_BIT;
113 pa_oe.oe |= 1 << ALE_BIT; 135 pa_oe.oe |= 1 << ALE_BIT;
114 pa_oe.oe |= 1 << CLE_BIT; 136 pa_oe.oe |= 1 << CLE_BIT;
115 pa_oe.oe &= ~ (1 << BY_BIT); 137 pa_oe.oe &= ~(1 << BY_BIT);
116 REG_WR(gio, regi_gio, rw_pa_oe, pa_oe); 138 REG_WR(gio, regi_gio, rw_pa_oe, pa_oe);
117 139
118 bif_cfg.gated_csp0 = regk_bif_core_rd; 140 bif_cfg.gated_csp0 = regk_bif_core_rd;
119 bif_cfg.gated_csp1 = regk_bif_core_wr; 141 bif_cfg.gated_csp1 = regk_bif_core_wr;
120 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); 142 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
121 143
122 /* Initialize structures */
123 memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info));
124 memset((char *) this, 0, sizeof(struct nand_chip));
125
126 /* Link the private data with the MTD structure */ 144 /* Link the private data with the MTD structure */
127 crisv32_mtd->priv = this; 145 crisv32_mtd->priv = this;
128 146
129 /* Set address of NAND IO lines */ 147 /* Set address of NAND IO lines */
130 this->IO_ADDR_R = read_cs; 148 this->IO_ADDR_R = read_cs;
131 this->IO_ADDR_W = write_cs; 149 this->IO_ADDR_W = write_cs;
132 this->hwcontrol = crisv32_hwcontrol; 150 this->cmd_ctrl = crisv32_hwcontrol;
133 this->dev_ready = crisv32_device_ready; 151 this->dev_ready = crisv32_device_ready;
134 /* 20 us command delay time */ 152 /* 20 us command delay time */
135 this->chip_delay = 20; 153 this->chip_delay = 20;
136 this->eccmode = NAND_ECC_SOFT; 154 this->ecc.mode = NAND_ECC_SOFT;
137 155
138 /* Enable the following for a flash based bad block table */ 156 /* Enable the following for a flash based bad block table */
139 this->options = NAND_USE_FLASH_BBT; 157 /* this->options = NAND_USE_FLASH_BBT; */
140 158
141 /* Scan to find existence of the device */ 159 /* Scan to find existance of the device */
142 if (nand_scan (crisv32_mtd, 1)) { 160 if (nand_scan(crisv32_mtd, 1)) {
143 err = -ENXIO; 161 err = -ENXIO;
144 goto out_ior; 162 goto out_ior;
145 } 163 }
@@ -150,7 +168,7 @@ out_ior:
150 iounmap((void *)read_cs); 168 iounmap((void *)read_cs);
151 iounmap((void *)write_cs); 169 iounmap((void *)write_cs);
152out_mtd: 170out_mtd:
153 kfree (crisv32_mtd); 171 kfree(wrapper);
154 return NULL; 172 return NULL;
155} 173}
156 174
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index 6dbd700d3d66..53db3870ba04 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -10,7 +10,7 @@
10 * 400 kbits/s. The built-in word address register is incremented 10 * 400 kbits/s. The built-in word address register is incremented
11 * automatically after each written or read byte. 11 * automatically after each written or read byte.
12 * 12 *
13 * Copyright (c) 2002-2003, Axis Communications AB 13 * Copyright (c) 2002-2007, Axis Communications AB
14 * All rights reserved. 14 * All rights reserved.
15 * 15 *
16 * Author: Tobias Anderberg <tobiasa@axis.com>. 16 * Author: Tobias Anderberg <tobiasa@axis.com>.
@@ -26,6 +26,7 @@
26#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/bcd.h> 28#include <linux/bcd.h>
29#include <linux/mutex.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/system.h> 32#include <asm/system.h>
@@ -37,24 +38,27 @@
37#define PCF8563_MAJOR 121 /* Local major number. */ 38#define PCF8563_MAJOR 121 /* Local major number. */
38#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ 39#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
39#define PCF8563_NAME "PCF8563" 40#define PCF8563_NAME "PCF8563"
40#define DRIVER_VERSION "$Revision: 1.1 $" 41#define DRIVER_VERSION "$Revision: 1.17 $"
41 42
42/* Two simple wrapper macros, saves a few keystrokes. */ 43/* Two simple wrapper macros, saves a few keystrokes. */
43#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) 44#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
44#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) 45#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
45 46
47static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
48
46static const unsigned char days_in_month[] = 49static const unsigned char days_in_month[] =
47 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 50 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
48 51
49int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 52int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
50int pcf8563_open(struct inode *, struct file *); 53
51int pcf8563_release(struct inode *, struct file *); 54/* Cache VL bit value read at driver init since writing the RTC_SECOND
55 * register clears the VL status.
56 */
57static int voltage_low;
52 58
53static const struct file_operations pcf8563_fops = { 59static const struct file_operations pcf8563_fops = {
54 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
55 .ioctl = pcf8563_ioctl, 61 .ioctl = pcf8563_ioctl
56 .open = pcf8563_open,
57 .release = pcf8563_release,
58}; 62};
59 63
60unsigned char 64unsigned char
@@ -62,7 +66,7 @@ pcf8563_readreg(int reg)
62{ 66{
63 unsigned char res = rtc_read(reg); 67 unsigned char res = rtc_read(reg);
64 68
65 /* The PCF8563 does not return 0 for unimplemented bits */ 69 /* The PCF8563 does not return 0 for unimplemented bits. */
66 switch (reg) { 70 switch (reg) {
67 case RTC_SECONDS: 71 case RTC_SECONDS:
68 case RTC_MINUTES: 72 case RTC_MINUTES:
@@ -95,11 +99,6 @@ pcf8563_readreg(int reg)
95void 99void
96pcf8563_writereg(int reg, unsigned char val) 100pcf8563_writereg(int reg, unsigned char val)
97{ 101{
98#ifdef CONFIG_ETRAX_RTC_READONLY
99 if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
100 return;
101#endif
102
103 rtc_write(reg, val); 102 rtc_write(reg, val);
104} 103}
105 104
@@ -114,11 +113,13 @@ get_rtc_time(struct rtc_time *tm)
114 tm->tm_mon = rtc_read(RTC_MONTH); 113 tm->tm_mon = rtc_read(RTC_MONTH);
115 tm->tm_year = rtc_read(RTC_YEAR); 114 tm->tm_year = rtc_read(RTC_YEAR);
116 115
117 if (tm->tm_sec & 0x80) 116 if (tm->tm_sec & 0x80) {
118 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " 117 printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time "
119 "information is no longer guaranteed!\n", PCF8563_NAME); 118 "information is no longer guaranteed!\n", PCF8563_NAME);
119 }
120 120
121 tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); 121 tm->tm_year = BCD_TO_BIN(tm->tm_year) +
122 ((tm->tm_mon & 0x80) ? 100 : 0);
122 tm->tm_sec &= 0x7F; 123 tm->tm_sec &= 0x7F;
123 tm->tm_min &= 0x7F; 124 tm->tm_min &= 0x7F;
124 tm->tm_hour &= 0x3F; 125 tm->tm_hour &= 0x3F;
@@ -137,8 +138,19 @@ get_rtc_time(struct rtc_time *tm)
137int __init 138int __init
138pcf8563_init(void) 139pcf8563_init(void)
139{ 140{
141 static int res;
142 static int first = 1;
143
144 if (!first)
145 return res;
146 first = 0;
147
140 /* Initiate the i2c protocol. */ 148 /* Initiate the i2c protocol. */
141 i2c_init(); 149 res = i2c_init();
150 if (res < 0) {
151 printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
152 return res;
153 }
142 154
143 /* 155 /*
144 * First of all we need to reset the chip. This is done by 156 * First of all we need to reset the chip. This is done by
@@ -170,24 +182,20 @@ pcf8563_init(void)
170 if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) 182 if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
171 goto err; 183 goto err;
172 184
173 if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { 185 /* Check for low voltage, and warn about it. */
174 printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n", 186 if (rtc_read(RTC_SECONDS) & 0x80) {
175 PCF8563_NAME, PCF8563_MAJOR); 187 voltage_low = 1;
176 return -1; 188 printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
189 "date/time information is no longer guaranteed!\n",
190 PCF8563_NAME);
177 } 191 }
178 192
179 printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); 193 return res;
180
181 /* Check for low voltage, and warn about it.. */
182 if (rtc_read(RTC_SECONDS) & 0x80)
183 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
184 "information is no longer guaranteed!\n", PCF8563_NAME);
185
186 return 0;
187 194
188err: 195err:
189 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); 196 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
190 return -1; 197 res = -1;
198 return res;
191} 199}
192 200
193void __exit 201void __exit
@@ -200,8 +208,8 @@ pcf8563_exit(void)
200 * ioctl calls for this driver. Why return -ENOTTY upon error? Because 208 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
201 * POSIX says so! 209 * POSIX says so!
202 */ 210 */
203int 211int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
204pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 212 unsigned long arg)
205{ 213{
206 /* Some sanity checks. */ 214 /* Some sanity checks. */
207 if (_IOC_TYPE(cmd) != RTC_MAGIC) 215 if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -211,125 +219,147 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned
211 return -ENOTTY; 219 return -ENOTTY;
212 220
213 switch (cmd) { 221 switch (cmd) {
214 case RTC_RD_TIME: 222 case RTC_RD_TIME:
215 { 223 {
216 struct rtc_time tm; 224 struct rtc_time tm;
217 225
218 memset(&tm, 0, sizeof (struct rtc_time)); 226 mutex_lock(&rtc_lock);
219 get_rtc_time(&tm); 227 memset(&tm, 0, sizeof tm);
220 228 get_rtc_time(&tm);
221 if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { 229
222 return -EFAULT; 230 if (copy_to_user((struct rtc_time *) arg, &tm,
223 } 231 sizeof tm)) {
224 232 spin_unlock(&rtc_lock);
225 return 0; 233 return -EFAULT;
226 } 234 }
227 235
228 case RTC_SET_TIME: 236 mutex_unlock(&rtc_lock);
229 { 237
230#ifdef CONFIG_ETRAX_RTC_READONLY 238 return 0;
239 }
240 case RTC_SET_TIME:
241 {
242 int leap;
243 int year;
244 int century;
245 struct rtc_time tm;
246
247 memset(&tm, 0, sizeof tm);
248 if (!capable(CAP_SYS_TIME))
231 return -EPERM; 249 return -EPERM;
232#else
233 int leap;
234 int year;
235 int century;
236 struct rtc_time tm;
237
238 if (!capable(CAP_SYS_TIME))
239 return -EPERM;
240
241 if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
242 return -EFAULT;
243
244 /* Convert from struct tm to struct rtc_time. */
245 tm.tm_year += 1900;
246 tm.tm_mon += 1;
247
248 /*
249 * Check if tm.tm_year is a leap year. A year is a leap
250 * year if it is divisible by 4 but not 100, except
251 * that years divisible by 400 _are_ leap years.
252 */
253 year = tm.tm_year;
254 leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
255
256 /* Perform some sanity checks. */
257 if ((tm.tm_year < 1970) ||
258 (tm.tm_mon > 12) ||
259 (tm.tm_mday == 0) ||
260 (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
261 (tm.tm_wday >= 7) ||
262 (tm.tm_hour >= 24) ||
263 (tm.tm_min >= 60) ||
264 (tm.tm_sec >= 60))
265 return -EINVAL;
266
267 century = (tm.tm_year >= 2000) ? 0x80 : 0;
268 tm.tm_year = tm.tm_year % 100;
269
270 BIN_TO_BCD(tm.tm_year);
271 BIN_TO_BCD(tm.tm_mday);
272 BIN_TO_BCD(tm.tm_hour);
273 BIN_TO_BCD(tm.tm_min);
274 BIN_TO_BCD(tm.tm_sec);
275 tm.tm_mon |= century;
276
277 rtc_write(RTC_YEAR, tm.tm_year);
278 rtc_write(RTC_MONTH, tm.tm_mon);
279 rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
280 rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
281 rtc_write(RTC_HOURS, tm.tm_hour);
282 rtc_write(RTC_MINUTES, tm.tm_min);
283 rtc_write(RTC_SECONDS, tm.tm_sec);
284
285 return 0;
286#endif /* !CONFIG_ETRAX_RTC_READONLY */
287 }
288 250
289 case RTC_VLOW_RD: 251 if (copy_from_user(&tm, (struct rtc_time *) arg,
290 { 252 sizeof tm))
291 int vl_bit = 0; 253 return -EFAULT;
254
255 /* Convert from struct tm to struct rtc_time. */
256 tm.tm_year += 1900;
257 tm.tm_mon += 1;
258
259 /*
260 * Check if tm.tm_year is a leap year. A year is a leap
261 * year if it is divisible by 4 but not 100, except
262 * that years divisible by 400 _are_ leap years.
263 */
264 year = tm.tm_year;
265 leap = (tm.tm_mon == 2) &&
266 ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
267
268 /* Perform some sanity checks. */
269 if ((tm.tm_year < 1970) ||
270 (tm.tm_mon > 12) ||
271 (tm.tm_mday == 0) ||
272 (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
273 (tm.tm_wday >= 7) ||
274 (tm.tm_hour >= 24) ||
275 (tm.tm_min >= 60) ||
276 (tm.tm_sec >= 60))
277 return -EINVAL;
278
279 century = (tm.tm_year >= 2000) ? 0x80 : 0;
280 tm.tm_year = tm.tm_year % 100;
281
282 BIN_TO_BCD(tm.tm_year);
283 BIN_TO_BCD(tm.tm_mon);
284 BIN_TO_BCD(tm.tm_mday);
285 BIN_TO_BCD(tm.tm_hour);
286 BIN_TO_BCD(tm.tm_min);
287 BIN_TO_BCD(tm.tm_sec);
288 tm.tm_mon |= century;
289
290 mutex_lock(&rtc_lock);
291
292 rtc_write(RTC_YEAR, tm.tm_year);
293 rtc_write(RTC_MONTH, tm.tm_mon);
294 rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
295 rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
296 rtc_write(RTC_HOURS, tm.tm_hour);
297 rtc_write(RTC_MINUTES, tm.tm_min);
298 rtc_write(RTC_SECONDS, tm.tm_sec);
299
300 mutex_unlock(&rtc_lock);
301
302 return 0;
303 }
304 case RTC_VL_READ:
305 if (voltage_low)
306 printk(KERN_ERR "%s: RTC Voltage Low - "
307 "reliable date/time information is no "
308 "longer guaranteed!\n", PCF8563_NAME);
292 309
293 if (rtc_read(RTC_SECONDS) & 0x80) { 310 if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
294 vl_bit = 1; 311 return -EFAULT;
295 printk(KERN_WARNING "%s: RTC Voltage Low - reliable " 312 return 0;
296 "date/time information is no longer guaranteed!\n",
297 PCF8563_NAME);
298 }
299 if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
300 return -EFAULT;
301 313
302 return 0; 314 case RTC_VL_CLR:
303 } 315 {
316 /* Clear the VL bit in the seconds register in case
317 * the time has not been set already (which would
318 * have cleared it). This does not really matter
319 * because of the cached voltage_low value but do it
320 * anyway for consistency. */
304 321
305 case RTC_VLOW_SET: 322 int ret = rtc_read(RTC_SECONDS);
306 {
307 /* Clear the VL bit in the seconds register */
308 int ret = rtc_read(RTC_SECONDS);
309 323
310 rtc_write(RTC_SECONDS, (ret & 0x7F)); 324 rtc_write(RTC_SECONDS, (ret & 0x7F));
311 325
312 return 0; 326 /* Clear the cached value. */
313 } 327 voltage_low = 0;
314 328
315 default: 329 return 0;
316 return -ENOTTY; 330 }
331 default:
332 return -ENOTTY;
317 } 333 }
318 334
319 return 0; 335 return 0;
320} 336}
321 337
322int 338static int __init pcf8563_register(void)
323pcf8563_open(struct inode *inode, struct file *filp)
324{ 339{
325 return 0; 340 if (pcf8563_init() < 0) {
326} 341 printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
342 "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
343 return -1;
344 }
345
346 if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
347 printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
348 "device.\n", PCF8563_NAME, PCF8563_MAJOR);
349 return -1;
350 }
351
352 printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
353 DRIVER_VERSION);
354
355 /* Check for low voltage, and warn about it. */
356 if (voltage_low) {
357 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
358 "information is no longer guaranteed!\n", PCF8563_NAME);
359 }
327 360
328int
329pcf8563_release(struct inode *inode, struct file *filp)
330{
331 return 0; 361 return 0;
332} 362}
333 363
334module_init(pcf8563_init); 364module_init(pcf8563_register);
335module_exit(pcf8563_exit); 365module_exit(pcf8563_exit);
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index d581b0a92a3f..47c377df6fb3 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Simple synchronous serial port driver for ETRAX FS. 2 * Simple synchronous serial port driver for ETRAX FS and Artpec-3.
3 * 3 *
4 * Copyright (c) 2005 Axis Communications AB 4 * Copyright (c) 2005 Axis Communications AB
5 * 5 *
@@ -21,17 +21,18 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22 22
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/arch/dma.h> 24#include <dma.h>
25#include <asm/arch/pinmux.h> 25#include <pinmux.h>
26#include <asm/arch/hwregs/reg_rdwr.h> 26#include <hwregs/reg_rdwr.h>
27#include <asm/arch/hwregs/sser_defs.h> 27#include <hwregs/sser_defs.h>
28#include <asm/arch/hwregs/dma_defs.h> 28#include <hwregs/dma_defs.h>
29#include <asm/arch/hwregs/dma.h> 29#include <hwregs/dma.h>
30#include <asm/arch/hwregs/intr_vect_defs.h> 30#include <hwregs/intr_vect_defs.h>
31#include <asm/arch/hwregs/intr_vect.h> 31#include <hwregs/intr_vect.h>
32#include <asm/arch/hwregs/reg_map.h> 32#include <hwregs/reg_map.h>
33#include <asm/sync_serial.h> 33#include <asm/sync_serial.h>
34 34
35
35/* The receiver is a bit tricky beacuse of the continuous stream of data.*/ 36/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
36/* */ 37/* */
37/* Three DMA descriptors are linked together. Each DMA descriptor is */ 38/* Three DMA descriptors are linked together. Each DMA descriptor is */
@@ -63,8 +64,10 @@
63/* words can be handled */ 64/* words can be handled */
64#define IN_BUFFER_SIZE 12288 65#define IN_BUFFER_SIZE 12288
65#define IN_DESCR_SIZE 256 66#define IN_DESCR_SIZE 256
66#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE) 67#define NBR_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
67#define OUT_BUFFER_SIZE 4096 68
69#define OUT_BUFFER_SIZE 1024*8
70#define NBR_OUT_DESCR 8
68 71
69#define DEFAULT_FRAME_RATE 0 72#define DEFAULT_FRAME_RATE 0
70#define DEFAULT_WORD_RATE 7 73#define DEFAULT_WORD_RATE 7
@@ -78,6 +81,8 @@
78#define DEBUGPOLL(x) 81#define DEBUGPOLL(x)
79#define DEBUGRXINT(x) 82#define DEBUGRXINT(x)
80#define DEBUGTXINT(x) 83#define DEBUGTXINT(x)
84#define DEBUGTRDMA(x)
85#define DEBUGOUTBUF(x)
81 86
82typedef struct sync_port 87typedef struct sync_port
83{ 88{
@@ -97,10 +102,11 @@ typedef struct sync_port
97 int output; 102 int output;
98 int input; 103 int input;
99 104
100 volatile unsigned int out_count; /* Remaining bytes for current transfer */ 105 /* Next byte to be read by application */
101 unsigned char* outp; /* Current position in out_buffer */ 106 volatile unsigned char *volatile readp;
102 volatile unsigned char* volatile readp; /* Next byte to be read by application */ 107 /* Next byte to be written by etrax */
103 volatile unsigned char* volatile writep; /* Next byte to be written by etrax */ 108 volatile unsigned char *volatile writep;
109
104 unsigned int in_buffer_size; 110 unsigned int in_buffer_size;
105 unsigned int inbufchunk; 111 unsigned int inbufchunk;
106 unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32))); 112 unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
@@ -108,11 +114,30 @@ typedef struct sync_port
108 unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32))); 114 unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
109 struct dma_descr_data* next_rx_desc; 115 struct dma_descr_data* next_rx_desc;
110 struct dma_descr_data* prev_rx_desc; 116 struct dma_descr_data* prev_rx_desc;
117
118 /* Pointer to the first available descriptor in the ring,
119 * unless active_tr_descr == catch_tr_descr and a dma
120 * transfer is active */
121 struct dma_descr_data *active_tr_descr;
122
123 /* Pointer to the first allocated descriptor in the ring */
124 struct dma_descr_data *catch_tr_descr;
125
126 /* Pointer to the descriptor with the current end-of-list */
127 struct dma_descr_data *prev_tr_descr;
111 int full; 128 int full;
112 129
113 dma_descr_data in_descr[NUM_IN_DESCR] __attribute__ ((__aligned__(16))); 130 /* Pointer to the first byte being read by DMA
131 * or current position in out_buffer if not using DMA. */
132 unsigned char *out_rd_ptr;
133
134 /* Number of bytes currently locked for being read by DMA */
135 int out_buf_count;
136
137 dma_descr_data in_descr[NBR_IN_DESCR] __attribute__ ((__aligned__(16)));
114 dma_descr_context in_context __attribute__ ((__aligned__(32))); 138 dma_descr_context in_context __attribute__ ((__aligned__(32)));
115 dma_descr_data out_descr __attribute__ ((__aligned__(16))); 139 dma_descr_data out_descr[NBR_OUT_DESCR]
140 __attribute__ ((__aligned__(16)));
116 dma_descr_context out_context __attribute__ ((__aligned__(32))); 141 dma_descr_context out_context __attribute__ ((__aligned__(32)));
117 wait_queue_head_t out_wait_q; 142 wait_queue_head_t out_wait_q;
118 wait_queue_head_t in_wait_q; 143 wait_queue_head_t in_wait_q;
@@ -143,11 +168,11 @@ static ssize_t sync_serial_read(struct file *file, char *buf,
143#endif 168#endif
144 169
145static void send_word(sync_port* port); 170static void send_word(sync_port* port);
146static void start_dma(struct sync_port *port, const char* data, int count); 171static void start_dma_out(struct sync_port *port, const char *data, int count);
147static void start_dma_in(sync_port* port); 172static void start_dma_in(sync_port* port);
148#ifdef SYNC_SER_DMA 173#ifdef SYNC_SER_DMA
149static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs); 174static irqreturn_t tr_interrupt(int irq, void *dev_id);
150static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); 175static irqreturn_t rx_interrupt(int irq, void *dev_id);
151#endif 176#endif
152 177
153#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ 178#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
@@ -157,22 +182,49 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
157#define SYNC_SER_MANUAL 182#define SYNC_SER_MANUAL
158#endif 183#endif
159#ifdef SYNC_SER_MANUAL 184#ifdef SYNC_SER_MANUAL
160static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs); 185static irqreturn_t manual_interrupt(int irq, void *dev_id);
186#endif
187
188#ifdef CONFIG_ETRAXFS /* ETRAX FS */
189#define OUT_DMA_NBR 4
190#define IN_DMA_NBR 5
191#define PINMUX_SSER pinmux_sser0
192#define SYNCSER_INST regi_sser0
193#define SYNCSER_INTR_VECT SSER0_INTR_VECT
194#define OUT_DMA_INST regi_dma4
195#define IN_DMA_INST regi_dma5
196#define DMA_OUT_INTR_VECT DMA4_INTR_VECT
197#define DMA_IN_INTR_VECT DMA5_INTR_VECT
198#define REQ_DMA_SYNCSER dma_sser0
199#else /* Artpec-3 */
200#define OUT_DMA_NBR 6
201#define IN_DMA_NBR 7
202#define PINMUX_SSER pinmux_sser
203#define SYNCSER_INST regi_sser
204#define SYNCSER_INTR_VECT SSER_INTR_VECT
205#define OUT_DMA_INST regi_dma6
206#define IN_DMA_INST regi_dma7
207#define DMA_OUT_INTR_VECT DMA6_INTR_VECT
208#define DMA_IN_INTR_VECT DMA7_INTR_VECT
209#define REQ_DMA_SYNCSER dma_sser
161#endif 210#endif
162 211
163/* The ports */ 212/* The ports */
164static struct sync_port ports[]= 213static struct sync_port ports[]=
165{ 214{
166 { 215 {
167 .regi_sser = regi_sser0, 216 .regi_sser = SYNCSER_INST,
168 .regi_dmaout = regi_dma4, 217 .regi_dmaout = OUT_DMA_INST,
169 .regi_dmain = regi_dma5, 218 .regi_dmain = IN_DMA_INST,
170#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) 219#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
171 .use_dma = 1, 220 .use_dma = 1,
172#else 221#else
173 .use_dma = 0, 222 .use_dma = 0,
174#endif 223#endif
175 }, 224 }
225#ifdef CONFIG_ETRAXFS
226 ,
227
176 { 228 {
177 .regi_sser = regi_sser1, 229 .regi_sser = regi_sser1,
178 .regi_dmaout = regi_dma6, 230 .regi_dmaout = regi_dma6,
@@ -183,9 +235,10 @@ static struct sync_port ports[]=
183 .use_dma = 0, 235 .use_dma = 0,
184#endif 236#endif
185 } 237 }
238#endif
186}; 239};
187 240
188#define NUMBER_OF_PORTS ARRAY_SIZE(ports) 241#define NBR_PORTS ARRAY_SIZE(ports)
189 242
190static const struct file_operations sync_serial_fops = { 243static const struct file_operations sync_serial_fops = {
191 .owner = THIS_MODULE, 244 .owner = THIS_MODULE,
@@ -200,19 +253,21 @@ static const struct file_operations sync_serial_fops = {
200static int __init etrax_sync_serial_init(void) 253static int __init etrax_sync_serial_init(void)
201{ 254{
202 ports[0].enabled = 0; 255 ports[0].enabled = 0;
256#ifdef CONFIG_ETRAXFS
203 ports[1].enabled = 0; 257 ports[1].enabled = 0;
204 258#endif
205 if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) 259 if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial",
206 { 260 &sync_serial_fops) < 0) {
207 printk("unable to get major for synchronous serial port\n"); 261 printk(KERN_WARNING
262 "Unable to get major for synchronous serial port\n");
208 return -EBUSY; 263 return -EBUSY;
209 } 264 }
210 265
211 /* Initialize Ports */ 266 /* Initialize Ports */
212#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) 267#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
213 if (crisv32_pinmux_alloc_fixed(pinmux_sser0)) 268 if (crisv32_pinmux_alloc_fixed(PINMUX_SSER)) {
214 { 269 printk(KERN_WARNING
215 printk("Unable to allocate pins for syncrhronous serial port 0\n"); 270 "Unable to alloc pins for synchronous serial port 0\n");
216 return -EIO; 271 return -EIO;
217 } 272 }
218 ports[0].enabled = 1; 273 ports[0].enabled = 1;
@@ -220,33 +275,40 @@ static int __init etrax_sync_serial_init(void)
220#endif 275#endif
221 276
222#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) 277#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
223 if (crisv32_pinmux_alloc_fixed(pinmux_sser1)) 278 if (crisv32_pinmux_alloc_fixed(pinmux_sser1)) {
224 { 279 printk(KERN_WARNING
225 printk("Unable to allocate pins for syncrhronous serial port 0\n"); 280 "Unable to alloc pins for synchronous serial port 0\n");
226 return -EIO; 281 return -EIO;
227 } 282 }
228 ports[1].enabled = 1; 283 ports[1].enabled = 1;
229 initialize_port(1); 284 initialize_port(1);
230#endif 285#endif
231 286
232 printk("ETRAX FS synchronous serial port driver\n"); 287#ifdef CONFIG_ETRAXFS
288 printk(KERN_INFO "ETRAX FS synchronous serial port driver\n");
289#else
290 printk(KERN_INFO "Artpec-3 synchronous serial port driver\n");
291#endif
233 return 0; 292 return 0;
234} 293}
235 294
236static void __init initialize_port(int portnbr) 295static void __init initialize_port(int portnbr)
237{ 296{
238 struct sync_port* port = &ports[portnbr]; 297 int __attribute__((unused)) i;
298 struct sync_port *port = &ports[portnbr];
239 reg_sser_rw_cfg cfg = {0}; 299 reg_sser_rw_cfg cfg = {0};
240 reg_sser_rw_frm_cfg frm_cfg = {0}; 300 reg_sser_rw_frm_cfg frm_cfg = {0};
241 reg_sser_rw_tr_cfg tr_cfg = {0}; 301 reg_sser_rw_tr_cfg tr_cfg = {0};
242 reg_sser_rw_rec_cfg rec_cfg = {0}; 302 reg_sser_rw_rec_cfg rec_cfg = {0};
243 303
244 DEBUG(printk("Init sync serial port %d\n", portnbr)); 304 DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr));
245 305
246 port->port_nbr = portnbr; 306 port->port_nbr = portnbr;
247 port->init_irqs = 1; 307 port->init_irqs = 1;
248 308
249 port->outp = port->out_buffer; 309 port->out_rd_ptr = port->out_buffer;
310 port->out_buf_count = 0;
311
250 port->output = 1; 312 port->output = 1;
251 port->input = 0; 313 port->input = 0;
252 314
@@ -255,7 +317,7 @@ static void __init initialize_port(int portnbr)
255 port->in_buffer_size = IN_BUFFER_SIZE; 317 port->in_buffer_size = IN_BUFFER_SIZE;
256 port->inbufchunk = IN_DESCR_SIZE; 318 port->inbufchunk = IN_DESCR_SIZE;
257 port->next_rx_desc = &port->in_descr[0]; 319 port->next_rx_desc = &port->in_descr[0];
258 port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1]; 320 port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR-1];
259 port->prev_rx_desc->eol = 1; 321 port->prev_rx_desc->eol = 1;
260 322
261 init_waitqueue_head(&port->out_wait_q); 323 init_waitqueue_head(&port->out_wait_q);
@@ -286,8 +348,13 @@ static void __init initialize_port(int portnbr)
286 tr_cfg.sample_size = 7; 348 tr_cfg.sample_size = 7;
287 tr_cfg.sh_dir = regk_sser_msbfirst; 349 tr_cfg.sh_dir = regk_sser_msbfirst;
288 tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; 350 tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
351#if 0
289 tr_cfg.rate_ctrl = regk_sser_bulk; 352 tr_cfg.rate_ctrl = regk_sser_bulk;
290 tr_cfg.data_pin_use = regk_sser_dout; 353 tr_cfg.data_pin_use = regk_sser_dout;
354#else
355 tr_cfg.rate_ctrl = regk_sser_iso;
356 tr_cfg.data_pin_use = regk_sser_dout;
357#endif
291 tr_cfg.bulk_wspace = 1; 358 tr_cfg.bulk_wspace = 1;
292 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); 359 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
293 360
@@ -296,6 +363,27 @@ static void __init initialize_port(int portnbr)
296 rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; 363 rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
297 rec_cfg.fifo_thr = regk_sser_inf; 364 rec_cfg.fifo_thr = regk_sser_inf;
298 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); 365 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
366
367#ifdef SYNC_SER_DMA
368 /* Setup the descriptor ring for dma out/transmit. */
369 for (i = 0; i < NBR_OUT_DESCR; i++) {
370 port->out_descr[i].wait = 0;
371 port->out_descr[i].intr = 1;
372 port->out_descr[i].eol = 0;
373 port->out_descr[i].out_eop = 0;
374 port->out_descr[i].next =
375 (dma_descr_data *)virt_to_phys(&port->out_descr[i+1]);
376 }
377
378 /* Create a ring from the list. */
379 port->out_descr[NBR_OUT_DESCR-1].next =
380 (dma_descr_data *)virt_to_phys(&port->out_descr[0]);
381
382 /* Setup context for traversing the ring. */
383 port->active_tr_descr = &port->out_descr[0];
384 port->prev_tr_descr = &port->out_descr[NBR_OUT_DESCR-1];
385 port->catch_tr_descr = &port->out_descr[0];
386#endif
299} 387}
300 388
301static inline int sync_data_avail(struct sync_port *port) 389static inline int sync_data_avail(struct sync_port *port)
@@ -311,7 +399,7 @@ static inline int sync_data_avail(struct sync_port *port)
311 * ^rp ^wp ^wp ^rp 399 * ^rp ^wp ^wp ^rp
312 */ 400 */
313 401
314 if (end >= start) 402 if (end >= start)
315 avail = end - start; 403 avail = end - start;
316 else 404 else
317 avail = port->in_buffer_size - (start - end); 405 avail = port->in_buffer_size - (start - end);
@@ -331,7 +419,7 @@ static inline int sync_data_avail_to_end(struct sync_port *port)
331 * ^rp ^wp ^wp ^rp 419 * ^rp ^wp ^wp ^rp
332 */ 420 */
333 421
334 if (end >= start) 422 if (end >= start)
335 avail = end - start; 423 avail = end - start;
336 else 424 else
337 avail = port->flip + port->in_buffer_size - start; 425 avail = port->flip + port->in_buffer_size - start;
@@ -341,66 +429,69 @@ static inline int sync_data_avail_to_end(struct sync_port *port)
341static int sync_serial_open(struct inode *inode, struct file *file) 429static int sync_serial_open(struct inode *inode, struct file *file)
342{ 430{
343 int dev = iminor(inode); 431 int dev = iminor(inode);
344 sync_port* port; 432 sync_port *port;
345 reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; 433 reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
346 reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; 434 reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
347 435
348 DEBUG(printk("Open sync serial port %d\n", dev)); 436 DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
349 437
350 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) 438 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
351 { 439 {
352 DEBUG(printk("Invalid minor %d\n", dev)); 440 DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
353 return -ENODEV; 441 return -ENODEV;
354 } 442 }
355 port = &ports[dev]; 443 port = &ports[dev];
356 /* Allow open this device twice (assuming one reader and one writer) */ 444 /* Allow open this device twice (assuming one reader and one writer) */
357 if (port->busy == 2) 445 if (port->busy == 2)
358 { 446 {
359 DEBUG(printk("Device is busy.. \n")); 447 DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
360 return -EBUSY; 448 return -EBUSY;
361 } 449 }
450
451
362 if (port->init_irqs) { 452 if (port->init_irqs) {
363 if (port->use_dma) { 453 if (port->use_dma) {
364 if (port == &ports[0]){ 454 if (port == &ports[0]) {
365#ifdef SYNC_SER_DMA 455#ifdef SYNC_SER_DMA
366 if(request_irq(DMA4_INTR_VECT, 456 if (request_irq(DMA_OUT_INTR_VECT,
367 tr_interrupt, 457 tr_interrupt,
368 0, 458 0,
369 "synchronous serial 0 dma tr", 459 "synchronous serial 0 dma tr",
370 &ports[0])) { 460 &ports[0])) {
371 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); 461 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
372 return -EBUSY; 462 return -EBUSY;
373 } else if(request_irq(DMA5_INTR_VECT, 463 } else if (request_irq(DMA_IN_INTR_VECT,
374 rx_interrupt, 464 rx_interrupt,
375 0, 465 0,
376 "synchronous serial 1 dma rx", 466 "synchronous serial 1 dma rx",
377 &ports[0])) { 467 &ports[0])) {
378 free_irq(DMA4_INTR_VECT, &port[0]); 468 free_irq(DMA_OUT_INTR_VECT, &port[0]);
379 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); 469 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
380 return -EBUSY; 470 return -EBUSY;
381 } else if (crisv32_request_dma(SYNC_SER0_TX_DMA_NBR, 471 } else if (crisv32_request_dma(OUT_DMA_NBR,
382 "synchronous serial 0 dma tr", 472 "synchronous serial 0 dma tr",
383 DMA_VERBOSE_ON_ERROR, 473 DMA_VERBOSE_ON_ERROR,
384 0, 474 0,
385 dma_sser0)) { 475 REQ_DMA_SYNCSER)) {
386 free_irq(DMA4_INTR_VECT, &port[0]); 476 free_irq(DMA_OUT_INTR_VECT, &port[0]);
387 free_irq(DMA5_INTR_VECT, &port[0]); 477 free_irq(DMA_IN_INTR_VECT, &port[0]);
388 printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel"); 478 printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel");
389 return -EBUSY; 479 return -EBUSY;
390 } else if (crisv32_request_dma(SYNC_SER0_RX_DMA_NBR, 480 } else if (crisv32_request_dma(IN_DMA_NBR,
391 "synchronous serial 0 dma rec", 481 "synchronous serial 0 dma rec",
392 DMA_VERBOSE_ON_ERROR, 482 DMA_VERBOSE_ON_ERROR,
393 0, 483 0,
394 dma_sser0)) { 484 REQ_DMA_SYNCSER)) {
395 crisv32_free_dma(SYNC_SER0_TX_DMA_NBR); 485 crisv32_free_dma(OUT_DMA_NBR);
396 free_irq(DMA4_INTR_VECT, &port[0]); 486 free_irq(DMA_OUT_INTR_VECT, &port[0]);
397 free_irq(DMA5_INTR_VECT, &port[0]); 487 free_irq(DMA_IN_INTR_VECT, &port[0]);
398 printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel"); 488 printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
399 return -EBUSY; 489 return -EBUSY;
400 } 490 }
401#endif 491#endif
402 } 492 }
403 else if (port == &ports[1]){ 493#ifdef CONFIG_ETRAXFS
494 else if (port == &ports[1]) {
404#ifdef SYNC_SER_DMA 495#ifdef SYNC_SER_DMA
405 if (request_irq(DMA6_INTR_VECT, 496 if (request_irq(DMA6_INTR_VECT,
406 tr_interrupt, 497 tr_interrupt,
@@ -417,20 +508,22 @@ static int sync_serial_open(struct inode *inode, struct file *file)
417 free_irq(DMA6_INTR_VECT, &ports[1]); 508 free_irq(DMA6_INTR_VECT, &ports[1]);
418 printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); 509 printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
419 return -EBUSY; 510 return -EBUSY;
420 } else if (crisv32_request_dma(SYNC_SER1_TX_DMA_NBR, 511 } else if (crisv32_request_dma(
421 "synchronous serial 1 dma tr", 512 SYNC_SER1_TX_DMA_NBR,
422 DMA_VERBOSE_ON_ERROR, 513 "synchronous serial 1 dma tr",
423 0, 514 DMA_VERBOSE_ON_ERROR,
424 dma_sser1)) { 515 0,
425 free_irq(21, &ports[1]); 516 dma_sser1)) {
426 free_irq(20, &ports[1]); 517 free_irq(DMA6_INTR_VECT, &ports[1]);
518 free_irq(DMA7_INTR_VECT, &ports[1]);
427 printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); 519 printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
428 return -EBUSY; 520 return -EBUSY;
429 } else if (crisv32_request_dma(SYNC_SER1_RX_DMA_NBR, 521 } else if (crisv32_request_dma(
430 "synchronous serial 3 dma rec", 522 SYNC_SER1_RX_DMA_NBR,
431 DMA_VERBOSE_ON_ERROR, 523 "synchronous serial 3 dma rec",
432 0, 524 DMA_VERBOSE_ON_ERROR,
433 dma_sser1)) { 525 0,
526 dma_sser1)) {
434 crisv32_free_dma(SYNC_SER1_TX_DMA_NBR); 527 crisv32_free_dma(SYNC_SER1_TX_DMA_NBR);
435 free_irq(DMA6_INTR_VECT, &ports[1]); 528 free_irq(DMA6_INTR_VECT, &ports[1]);
436 free_irq(DMA7_INTR_VECT, &ports[1]); 529 free_irq(DMA7_INTR_VECT, &ports[1]);
@@ -439,14 +532,14 @@ static int sync_serial_open(struct inode *inode, struct file *file)
439 } 532 }
440#endif 533#endif
441 } 534 }
442 535#endif
443 /* Enable DMAs */ 536 /* Enable DMAs */
444 REG_WR(dma, port->regi_dmain, rw_cfg, cfg); 537 REG_WR(dma, port->regi_dmain, rw_cfg, cfg);
445 REG_WR(dma, port->regi_dmaout, rw_cfg, cfg); 538 REG_WR(dma, port->regi_dmaout, rw_cfg, cfg);
446 /* Enable DMA IRQs */ 539 /* Enable DMA IRQs */
447 REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask); 540 REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
448 REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask); 541 REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
449 /* Set up wordsize = 2 for DMAs. */ 542 /* Set up wordsize = 1 for DMAs. */
450 DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1); 543 DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1);
451 DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1); 544 DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1);
452 545
@@ -455,7 +548,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
455 } else { /* !port->use_dma */ 548 } else { /* !port->use_dma */
456#ifdef SYNC_SER_MANUAL 549#ifdef SYNC_SER_MANUAL
457 if (port == &ports[0]) { 550 if (port == &ports[0]) {
458 if (request_irq(SSER0_INTR_VECT, 551 if (request_irq(SYNCSER_INTR_VECT,
459 manual_interrupt, 552 manual_interrupt,
460 0, 553 0,
461 "synchronous serial manual irq", 554 "synchronous serial manual irq",
@@ -463,7 +556,9 @@ static int sync_serial_open(struct inode *inode, struct file *file)
463 printk("Can't allocate sync serial manual irq"); 556 printk("Can't allocate sync serial manual irq");
464 return -EBUSY; 557 return -EBUSY;
465 } 558 }
466 } else if (port == &ports[1]) { 559 }
560#ifdef CONFIG_ETRAXFS
561 else if (port == &ports[1]) {
467 if (request_irq(SSER1_INTR_VECT, 562 if (request_irq(SSER1_INTR_VECT,
468 manual_interrupt, 563 manual_interrupt,
469 0, 564 0,
@@ -473,11 +568,13 @@ static int sync_serial_open(struct inode *inode, struct file *file)
473 return -EBUSY; 568 return -EBUSY;
474 } 569 }
475 } 570 }
571#endif
476 port->init_irqs = 0; 572 port->init_irqs = 0;
477#else 573#else
478 panic("sync_serial: Manual mode not supported.\n"); 574 panic("sync_serial: Manual mode not supported.\n");
479#endif /* SYNC_SER_MANUAL */ 575#endif /* SYNC_SER_MANUAL */
480 } 576 }
577
481 } /* port->init_irqs */ 578 } /* port->init_irqs */
482 579
483 port->busy++; 580 port->busy++;
@@ -487,9 +584,9 @@ static int sync_serial_open(struct inode *inode, struct file *file)
487static int sync_serial_release(struct inode *inode, struct file *file) 584static int sync_serial_release(struct inode *inode, struct file *file)
488{ 585{
489 int dev = iminor(inode); 586 int dev = iminor(inode);
490 sync_port* port; 587 sync_port *port;
491 588
492 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) 589 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
493 { 590 {
494 DEBUG(printk("Invalid minor %d\n", dev)); 591 DEBUG(printk("Invalid minor %d\n", dev));
495 return -ENODEV; 592 return -ENODEV;
@@ -506,17 +603,37 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
506{ 603{
507 int dev = iminor(file->f_path.dentry->d_inode); 604 int dev = iminor(file->f_path.dentry->d_inode);
508 unsigned int mask = 0; 605 unsigned int mask = 0;
509 sync_port* port; 606 sync_port *port;
510 DEBUGPOLL( static unsigned int prev_mask = 0; ); 607 DEBUGPOLL( static unsigned int prev_mask = 0; );
511 608
512 port = &ports[dev]; 609 port = &ports[dev];
610
611 if (!port->started) {
612 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
613 reg_sser_rw_rec_cfg rec_cfg =
614 REG_RD(sser, port->regi_sser, rw_rec_cfg);
615 cfg.en = regk_sser_yes;
616 rec_cfg.rec_en = port->input;
617 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
618 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
619 port->started = 1;
620 }
621
513 poll_wait(file, &port->out_wait_q, wait); 622 poll_wait(file, &port->out_wait_q, wait);
514 poll_wait(file, &port->in_wait_q, wait); 623 poll_wait(file, &port->in_wait_q, wait);
515 /* Some room to write */ 624
516 if (port->out_count < OUT_BUFFER_SIZE) 625 /* No active transfer, descriptors are available */
626 if (port->output && !port->tr_running)
627 mask |= POLLOUT | POLLWRNORM;
628
629 /* Descriptor and buffer space available. */
630 if (port->output &&
631 port->active_tr_descr != port->catch_tr_descr &&
632 port->out_buf_count < OUT_BUFFER_SIZE)
517 mask |= POLLOUT | POLLWRNORM; 633 mask |= POLLOUT | POLLWRNORM;
634
518 /* At least an inbufchunk of data */ 635 /* At least an inbufchunk of data */
519 if (sync_data_avail(port) >= port->inbufchunk) 636 if (port->input && sync_data_avail(port) >= port->inbufchunk)
520 mask |= POLLIN | POLLRDNORM; 637 mask |= POLLIN | POLLRDNORM;
521 638
522 DEBUGPOLL(if (mask != prev_mask) 639 DEBUGPOLL(if (mask != prev_mask)
@@ -531,15 +648,16 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
531 unsigned int cmd, unsigned long arg) 648 unsigned int cmd, unsigned long arg)
532{ 649{
533 int return_val = 0; 650 int return_val = 0;
651 int dma_w_size = regk_dma_set_w_size1;
534 int dev = iminor(file->f_path.dentry->d_inode); 652 int dev = iminor(file->f_path.dentry->d_inode);
535 sync_port* port; 653 sync_port *port;
536 reg_sser_rw_tr_cfg tr_cfg; 654 reg_sser_rw_tr_cfg tr_cfg;
537 reg_sser_rw_rec_cfg rec_cfg; 655 reg_sser_rw_rec_cfg rec_cfg;
538 reg_sser_rw_frm_cfg frm_cfg; 656 reg_sser_rw_frm_cfg frm_cfg;
539 reg_sser_rw_cfg gen_cfg; 657 reg_sser_rw_cfg gen_cfg;
540 reg_sser_rw_intr_mask intr_mask; 658 reg_sser_rw_intr_mask intr_mask;
541 659
542 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) 660 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
543 { 661 {
544 DEBUG(printk("Invalid minor %d\n", dev)); 662 DEBUG(printk("Invalid minor %d\n", dev));
545 return -1; 663 return -1;
@@ -558,61 +676,81 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
558 case SSP_SPEED: 676 case SSP_SPEED:
559 if (GET_SPEED(arg) == CODEC) 677 if (GET_SPEED(arg) == CODEC)
560 { 678 {
679 unsigned int freq;
680
561 gen_cfg.base_freq = regk_sser_f32; 681 gen_cfg.base_freq = regk_sser_f32;
562 /* FREQ = 0 => 4 MHz => clk_div = 7*/ 682
563 gen_cfg.clk_div = 6 + (1 << GET_FREQ(arg)); 683 /* Clock divider will internally be
564 } 684 * gen_cfg.clk_div + 1.
565 else 685 */
566 { 686
687 freq = GET_FREQ(arg);
688 switch (freq) {
689 case FREQ_32kHz:
690 case FREQ_64kHz:
691 case FREQ_128kHz:
692 case FREQ_256kHz:
693 gen_cfg.clk_div = 125 *
694 (1 << (freq - FREQ_256kHz)) - 1;
695 break;
696 case FREQ_512kHz:
697 gen_cfg.clk_div = 62;
698 break;
699 case FREQ_1MHz:
700 case FREQ_2MHz:
701 case FREQ_4MHz:
702 gen_cfg.clk_div = 8 * (1 << freq) - 1;
703 break;
704 }
705 } else {
567 gen_cfg.base_freq = regk_sser_f29_493; 706 gen_cfg.base_freq = regk_sser_f29_493;
568 switch (GET_SPEED(arg)) 707 switch (GET_SPEED(arg)) {
569 { 708 case SSP150:
570 case SSP150: 709 gen_cfg.clk_div = 29493000 / (150 * 8) - 1;
571 gen_cfg.clk_div = 29493000 / (150 * 8) - 1; 710 break;
572 break; 711 case SSP300:
573 case SSP300: 712 gen_cfg.clk_div = 29493000 / (300 * 8) - 1;
574 gen_cfg.clk_div = 29493000 / (300 * 8) - 1; 713 break;
575 break; 714 case SSP600:
576 case SSP600: 715 gen_cfg.clk_div = 29493000 / (600 * 8) - 1;
577 gen_cfg.clk_div = 29493000 / (600 * 8) - 1; 716 break;
578 break; 717 case SSP1200:
579 case SSP1200: 718 gen_cfg.clk_div = 29493000 / (1200 * 8) - 1;
580 gen_cfg.clk_div = 29493000 / (1200 * 8) - 1; 719 break;
581 break; 720 case SSP2400:
582 case SSP2400: 721 gen_cfg.clk_div = 29493000 / (2400 * 8) - 1;
583 gen_cfg.clk_div = 29493000 / (2400 * 8) - 1; 722 break;
584 break; 723 case SSP4800:
585 case SSP4800: 724 gen_cfg.clk_div = 29493000 / (4800 * 8) - 1;
586 gen_cfg.clk_div = 29493000 / (4800 * 8) - 1; 725 break;
587 break; 726 case SSP9600:
588 case SSP9600: 727 gen_cfg.clk_div = 29493000 / (9600 * 8) - 1;
589 gen_cfg.clk_div = 29493000 / (9600 * 8) - 1; 728 break;
590 break; 729 case SSP19200:
591 case SSP19200: 730 gen_cfg.clk_div = 29493000 / (19200 * 8) - 1;
592 gen_cfg.clk_div = 29493000 / (19200 * 8) - 1; 731 break;
593 break; 732 case SSP28800:
594 case SSP28800: 733 gen_cfg.clk_div = 29493000 / (28800 * 8) - 1;
595 gen_cfg.clk_div = 29493000 / (28800 * 8) - 1; 734 break;
596 break; 735 case SSP57600:
597 case SSP57600: 736 gen_cfg.clk_div = 29493000 / (57600 * 8) - 1;
598 gen_cfg.clk_div = 29493000 / (57600 * 8) - 1; 737 break;
599 break; 738 case SSP115200:
600 case SSP115200: 739 gen_cfg.clk_div = 29493000 / (115200 * 8) - 1;
601 gen_cfg.clk_div = 29493000 / (115200 * 8) - 1; 740 break;
602 break; 741 case SSP230400:
603 case SSP230400: 742 gen_cfg.clk_div = 29493000 / (230400 * 8) - 1;
604 gen_cfg.clk_div = 29493000 / (230400 * 8) - 1; 743 break;
605 break; 744 case SSP460800:
606 case SSP460800: 745 gen_cfg.clk_div = 29493000 / (460800 * 8) - 1;
607 gen_cfg.clk_div = 29493000 / (460800 * 8) - 1; 746 break;
608 break; 747 case SSP921600:
609 case SSP921600: 748 gen_cfg.clk_div = 29493000 / (921600 * 8) - 1;
610 gen_cfg.clk_div = 29493000 / (921600 * 8) - 1; 749 break;
611 break; 750 case SSP3125000:
612 case SSP3125000: 751 gen_cfg.base_freq = regk_sser_f100;
613 gen_cfg.base_freq = regk_sser_f100; 752 gen_cfg.clk_div = 100000000 / (3125000 * 8) - 1;
614 gen_cfg.clk_div = 100000000 / (3125000 * 8) - 1; 753 break;
615 break;
616 754
617 } 755 }
618 } 756 }
@@ -625,46 +763,60 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
625 case MASTER_OUTPUT: 763 case MASTER_OUTPUT:
626 port->output = 1; 764 port->output = 1;
627 port->input = 0; 765 port->input = 0;
766 frm_cfg.out_on = regk_sser_tr;
767 frm_cfg.frame_pin_dir = regk_sser_out;
628 gen_cfg.clk_dir = regk_sser_out; 768 gen_cfg.clk_dir = regk_sser_out;
629 break; 769 break;
630 case SLAVE_OUTPUT: 770 case SLAVE_OUTPUT:
631 port->output = 1; 771 port->output = 1;
632 port->input = 0; 772 port->input = 0;
773 frm_cfg.frame_pin_dir = regk_sser_in;
633 gen_cfg.clk_dir = regk_sser_in; 774 gen_cfg.clk_dir = regk_sser_in;
634 break; 775 break;
635 case MASTER_INPUT: 776 case MASTER_INPUT:
636 port->output = 0; 777 port->output = 0;
637 port->input = 1; 778 port->input = 1;
779 frm_cfg.frame_pin_dir = regk_sser_out;
780 frm_cfg.out_on = regk_sser_intern_tb;
638 gen_cfg.clk_dir = regk_sser_out; 781 gen_cfg.clk_dir = regk_sser_out;
639 break; 782 break;
640 case SLAVE_INPUT: 783 case SLAVE_INPUT:
641 port->output = 0; 784 port->output = 0;
642 port->input = 1; 785 port->input = 1;
786 frm_cfg.frame_pin_dir = regk_sser_in;
643 gen_cfg.clk_dir = regk_sser_in; 787 gen_cfg.clk_dir = regk_sser_in;
644 break; 788 break;
645 case MASTER_BIDIR: 789 case MASTER_BIDIR:
646 port->output = 1; 790 port->output = 1;
647 port->input = 1; 791 port->input = 1;
792 frm_cfg.frame_pin_dir = regk_sser_out;
793 frm_cfg.out_on = regk_sser_intern_tb;
648 gen_cfg.clk_dir = regk_sser_out; 794 gen_cfg.clk_dir = regk_sser_out;
649 break; 795 break;
650 case SLAVE_BIDIR: 796 case SLAVE_BIDIR:
651 port->output = 1; 797 port->output = 1;
652 port->input = 1; 798 port->input = 1;
799 frm_cfg.frame_pin_dir = regk_sser_in;
653 gen_cfg.clk_dir = regk_sser_in; 800 gen_cfg.clk_dir = regk_sser_in;
654 break; 801 break;
655 default: 802 default:
656 spin_unlock_irq(&port->lock); 803 spin_unlock_irq(&port->lock);
657 return -EINVAL; 804 return -EINVAL;
658
659 } 805 }
660 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)) 806 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT))
661 intr_mask.rdav = regk_sser_yes; 807 intr_mask.rdav = regk_sser_yes;
662 break; 808 break;
663 case SSP_FRAME_SYNC: 809 case SSP_FRAME_SYNC:
664 if (arg & NORMAL_SYNC) 810 if (arg & NORMAL_SYNC) {
811 frm_cfg.rec_delay = 1;
665 frm_cfg.tr_delay = 1; 812 frm_cfg.tr_delay = 1;
813 }
666 else if (arg & EARLY_SYNC) 814 else if (arg & EARLY_SYNC)
667 frm_cfg.tr_delay = 0; 815 frm_cfg.rec_delay = frm_cfg.tr_delay = 0;
816 else if (arg & SECOND_WORD_SYNC) {
817 frm_cfg.rec_delay = 7;
818 frm_cfg.tr_delay = 1;
819 }
668 820
669 tr_cfg.bulk_wspace = frm_cfg.tr_delay; 821 tr_cfg.bulk_wspace = frm_cfg.tr_delay;
670 frm_cfg.early_wend = regk_sser_yes; 822 frm_cfg.early_wend = regk_sser_yes;
@@ -680,9 +832,11 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
680 else if (arg & SYNC_OFF) 832 else if (arg & SYNC_OFF)
681 frm_cfg.frame_pin_use = regk_sser_gio0; 833 frm_cfg.frame_pin_use = regk_sser_gio0;
682 834
683 if (arg & WORD_SIZE_8) 835 dma_w_size = regk_dma_set_w_size2;
836 if (arg & WORD_SIZE_8) {
684 rec_cfg.sample_size = tr_cfg.sample_size = 7; 837 rec_cfg.sample_size = tr_cfg.sample_size = 7;
685 else if (arg & WORD_SIZE_12) 838 dma_w_size = regk_dma_set_w_size1;
839 } else if (arg & WORD_SIZE_12)
686 rec_cfg.sample_size = tr_cfg.sample_size = 11; 840 rec_cfg.sample_size = tr_cfg.sample_size = 11;
687 else if (arg & WORD_SIZE_16) 841 else if (arg & WORD_SIZE_16)
688 rec_cfg.sample_size = tr_cfg.sample_size = 15; 842 rec_cfg.sample_size = tr_cfg.sample_size = 15;
@@ -696,10 +850,13 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
696 else if (arg & BIT_ORDER_LSB) 850 else if (arg & BIT_ORDER_LSB)
697 rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst; 851 rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst;
698 852
699 if (arg & FLOW_CONTROL_ENABLE) 853 if (arg & FLOW_CONTROL_ENABLE) {
854 frm_cfg.status_pin_use = regk_sser_frm;
700 rec_cfg.fifo_thr = regk_sser_thr16; 855 rec_cfg.fifo_thr = regk_sser_thr16;
701 else if (arg & FLOW_CONTROL_DISABLE) 856 } else if (arg & FLOW_CONTROL_DISABLE) {
857 frm_cfg.status_pin_use = regk_sser_gio0;
702 rec_cfg.fifo_thr = regk_sser_inf; 858 rec_cfg.fifo_thr = regk_sser_inf;
859 }
703 860
704 if (arg & CLOCK_NOT_GATED) 861 if (arg & CLOCK_NOT_GATED)
705 gen_cfg.gate_clk = regk_sser_no; 862 gen_cfg.gate_clk = regk_sser_no;
@@ -726,9 +883,9 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
726 break; 883 break;
727 case SSP_OPOLARITY: 884 case SSP_OPOLARITY:
728 if (arg & CLOCK_NORMAL) 885 if (arg & CLOCK_NORMAL)
729 gen_cfg.out_clk_pol = regk_sser_neg;
730 else if (arg & CLOCK_INVERT)
731 gen_cfg.out_clk_pol = regk_sser_pos; 886 gen_cfg.out_clk_pol = regk_sser_pos;
887 else if (arg & CLOCK_INVERT)
888 gen_cfg.out_clk_pol = regk_sser_neg;
732 889
733 if (arg & FRAME_NORMAL) 890 if (arg & FRAME_NORMAL)
734 frm_cfg.level = regk_sser_pos_hi; 891 frm_cfg.level = regk_sser_pos_hi;
@@ -770,10 +927,9 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
770 } 927 }
771 928
772 929
773 if (port->started) 930 if (port->started) {
774 {
775 tr_cfg.tr_en = port->output;
776 rec_cfg.rec_en = port->input; 931 rec_cfg.rec_en = port->input;
932 gen_cfg.en = (port->output | port->input);
777 } 933 }
778 934
779 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); 935 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
@@ -782,138 +938,145 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
782 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); 938 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
783 REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg); 939 REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
784 940
941
942 if (cmd == SSP_FRAME_SYNC && (arg & (WORD_SIZE_8 | WORD_SIZE_12 |
943 WORD_SIZE_16 | WORD_SIZE_24 | WORD_SIZE_32))) {
944 int en = gen_cfg.en;
945 gen_cfg.en = 0;
946 REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
947 /* ##### Should DMA be stoped before we change dma size? */
948 DMA_WR_CMD(port->regi_dmain, dma_w_size);
949 DMA_WR_CMD(port->regi_dmaout, dma_w_size);
950 gen_cfg.en = en;
951 REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
952 }
953
785 spin_unlock_irq(&port->lock); 954 spin_unlock_irq(&port->lock);
786 return return_val; 955 return return_val;
787} 956}
788 957
789static ssize_t sync_serial_write(struct file * file, const char * buf, 958/* NOTE: sync_serial_write does not support concurrency */
790 size_t count, loff_t *ppos) 959static ssize_t sync_serial_write(struct file *file, const char *buf,
960 size_t count, loff_t *ppos)
791{ 961{
792 int dev = iminor(file->f_path.dentry->d_inode); 962 int dev = iminor(file->f_path.dentry->d_inode);
793 DECLARE_WAITQUEUE(wait, current); 963 DECLARE_WAITQUEUE(wait, current);
794 sync_port *port; 964 struct sync_port *port;
795 unsigned long c, c1; 965 int trunc_count;
796 unsigned long free_outp;
797 unsigned long outp;
798 unsigned long out_buffer;
799 unsigned long flags; 966 unsigned long flags;
967 int bytes_free;
968 int out_buf_count;
800 969
801 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) 970 unsigned char *rd_ptr; /* First allocated byte in the buffer */
802 { 971 unsigned char *wr_ptr; /* First free byte in the buffer */
972 unsigned char *buf_stop_ptr; /* Last byte + 1 */
973
974 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
803 DEBUG(printk("Invalid minor %d\n", dev)); 975 DEBUG(printk("Invalid minor %d\n", dev));
804 return -ENODEV; 976 return -ENODEV;
805 } 977 }
806 port = &ports[dev]; 978 port = &ports[dev];
807 979
808 DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); 980 /* |<- OUT_BUFFER_SIZE ->|
809 /* Space to end of buffer */ 981 * |<- out_buf_count ->|
810 /* 982 * |<- trunc_count ->| ...->|
811 * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE 983 * ______________________________________________________
812 * outp^ +out_count 984 * | free | data | free |
813 ^free_outp 985 * |_________|___________________|________________________|
814 * out_buffer 45<- c ->0123OUT_BUFFER_SIZE 986 * ^ rd_ptr ^ wr_ptr
815 * +out_count outp^
816 * free_outp
817 *
818 */ 987 */
988 DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu a: %p c: %p\n",
989 port->port_nbr, count, port->active_tr_descr,
990 port->catch_tr_descr));
819 991
820 /* Read variables that may be updated by interrupts */ 992 /* Read variables that may be updated by interrupts */
821 spin_lock_irqsave(&port->lock, flags); 993 spin_lock_irqsave(&port->lock, flags);
822 count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count; 994 rd_ptr = port->out_rd_ptr;
823 outp = (unsigned long)port->outp; 995 out_buf_count = port->out_buf_count;
824 free_outp = outp + port->out_count;
825 spin_unlock_irqrestore(&port->lock, flags); 996 spin_unlock_irqrestore(&port->lock, flags);
826 out_buffer = (unsigned long)port->out_buffer;
827 997
828 /* Find out where and how much to write */ 998 /* Check if resources are available */
829 if (free_outp >= out_buffer + OUT_BUFFER_SIZE) 999 if (port->tr_running &&
830 free_outp -= OUT_BUFFER_SIZE; 1000 ((port->use_dma && port->active_tr_descr == port->catch_tr_descr) ||
831 if (free_outp >= outp) 1001 out_buf_count >= OUT_BUFFER_SIZE)) {
832 c = out_buffer + OUT_BUFFER_SIZE - free_outp; 1002 DEBUGWRITE(printk(KERN_DEBUG "sser%d full\n", dev));
833 else 1003 return -EAGAIN;
834 c = outp - free_outp; 1004 }
835 if (c > count) 1005
836 c = count; 1006 buf_stop_ptr = port->out_buffer + OUT_BUFFER_SIZE;
1007
1008 /* Determine pointer to the first free byte, before copying. */
1009 wr_ptr = rd_ptr + out_buf_count;
1010 if (wr_ptr >= buf_stop_ptr)
1011 wr_ptr -= OUT_BUFFER_SIZE;
837 1012
838// DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c)); 1013 /* If we wrap the ring buffer, let the user space program handle it by
839 if (copy_from_user((void*)free_outp, buf, c)) 1014 * truncating the data. This could be more elegant, small buffer
1015 * fragments may occur.
1016 */
1017 bytes_free = OUT_BUFFER_SIZE - out_buf_count;
1018 if (wr_ptr + bytes_free > buf_stop_ptr)
1019 bytes_free = buf_stop_ptr - wr_ptr;
1020 trunc_count = (count < bytes_free) ? count : bytes_free;
1021
1022 if (copy_from_user(wr_ptr, buf, trunc_count))
840 return -EFAULT; 1023 return -EFAULT;
841 1024
842 if (c != count) { 1025 DEBUGOUTBUF(printk(KERN_DEBUG "%-4d + %-4d = %-4d %p %p %p\n",
843 buf += c; 1026 out_buf_count, trunc_count,
844 c1 = count - c; 1027 port->out_buf_count, port->out_buffer,
845 DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1)); 1028 wr_ptr, buf_stop_ptr));
846 if (copy_from_user((void*)out_buffer, buf, c1))
847 return -EFAULT;
848 }
849 spin_lock_irqsave(&port->lock, flags);
850 port->out_count += count;
851 spin_unlock_irqrestore(&port->lock, flags);
852 1029
853 /* Make sure transmitter/receiver is running */ 1030 /* Make sure transmitter/receiver is running */
854 if (!port->started) 1031 if (!port->started) {
855 {
856 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); 1032 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
857 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
858 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg); 1033 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
859 cfg.en = regk_sser_yes; 1034 cfg.en = regk_sser_yes;
860 tr_cfg.tr_en = port->output;
861 rec_cfg.rec_en = port->input; 1035 rec_cfg.rec_en = port->input;
862 REG_WR(sser, port->regi_sser, rw_cfg, cfg); 1036 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
863 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
864 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); 1037 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
865 port->started = 1; 1038 port->started = 1;
866 } 1039 }
867 1040
868 if (file->f_flags & O_NONBLOCK) { 1041 /* Setup wait if blocking */
869 spin_lock_irqsave(&port->lock, flags); 1042 if (!(file->f_flags & O_NONBLOCK)) {
870 if (!port->tr_running) { 1043 add_wait_queue(&port->out_wait_q, &wait);
871 if (!port->use_dma) { 1044 set_current_state(TASK_INTERRUPTIBLE);
872 reg_sser_rw_intr_mask intr_mask;
873 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
874 /* Start sender by writing data */
875 send_word(port);
876 /* and enable transmitter ready IRQ */
877 intr_mask.trdy = 1;
878 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
879 } else {
880 start_dma(port, (unsigned char* volatile )port->outp, c);
881 }
882 }
883 spin_unlock_irqrestore(&port->lock, flags);
884 DEBUGWRITE(printk("w d%d c %lu NB\n",
885 port->port_nbr, count));
886 return count;
887 } 1045 }
888 1046
889 /* Sleep until all sent */
890
891 add_wait_queue(&port->out_wait_q, &wait);
892 set_current_state(TASK_INTERRUPTIBLE);
893 spin_lock_irqsave(&port->lock, flags); 1047 spin_lock_irqsave(&port->lock, flags);
894 if (!port->tr_running) { 1048 port->out_buf_count += trunc_count;
895 if (!port->use_dma) { 1049 if (port->use_dma) {
896 reg_sser_rw_intr_mask intr_mask; 1050 start_dma_out(port, wr_ptr, trunc_count);
897 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); 1051 } else if (!port->tr_running) {
898 /* Start sender by writing data */ 1052 reg_sser_rw_intr_mask intr_mask;
899 send_word(port); 1053 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
900 /* and enable transmitter ready IRQ */ 1054 /* Start sender by writing data */
901 intr_mask.trdy = 1; 1055 send_word(port);
902 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); 1056 /* and enable transmitter ready IRQ */
903 } else { 1057 intr_mask.trdy = 1;
904 start_dma(port, port->outp, c); 1058 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
905 }
906 } 1059 }
907 spin_unlock_irqrestore(&port->lock, flags); 1060 spin_unlock_irqrestore(&port->lock, flags);
1061
1062 /* Exit if non blocking */
1063 if (file->f_flags & O_NONBLOCK) {
1064 DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu %08x\n",
1065 port->port_nbr, trunc_count,
1066 REG_RD_INT(dma, port->regi_dmaout, r_intr)));
1067 return trunc_count;
1068 }
1069
908 schedule(); 1070 schedule();
909 set_current_state(TASK_RUNNING); 1071 set_current_state(TASK_RUNNING);
910 remove_wait_queue(&port->out_wait_q, &wait); 1072 remove_wait_queue(&port->out_wait_q, &wait);
1073
911 if (signal_pending(current)) 1074 if (signal_pending(current))
912 {
913 return -EINTR; 1075 return -EINTR;
914 } 1076
915 DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count)); 1077 DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n",
916 return count; 1078 port->port_nbr, trunc_count));
1079 return trunc_count;
917} 1080}
918 1081
919static ssize_t sync_serial_read(struct file * file, char * buf, 1082static ssize_t sync_serial_read(struct file * file, char * buf,
@@ -926,7 +1089,7 @@ static ssize_t sync_serial_read(struct file * file, char * buf,
926 unsigned char* end; 1089 unsigned char* end;
927 unsigned long flags; 1090 unsigned long flags;
928 1091
929 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) 1092 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
930 { 1093 {
931 DEBUG(printk("Invalid minor %d\n", dev)); 1094 DEBUG(printk("Invalid minor %d\n", dev));
932 return -ENODEV; 1095 return -ENODEV;
@@ -949,7 +1112,6 @@ static ssize_t sync_serial_read(struct file * file, char * buf,
949 port->started = 1; 1112 port->started = 1;
950 } 1113 }
951 1114
952
953 /* Calculate number of available bytes */ 1115 /* Calculate number of available bytes */
954 /* Save pointers to avoid that they are modified by interrupt */ 1116 /* Save pointers to avoid that they are modified by interrupt */
955 spin_lock_irqsave(&port->lock, flags); 1117 spin_lock_irqsave(&port->lock, flags);
@@ -958,16 +1120,14 @@ static ssize_t sync_serial_read(struct file * file, char * buf,
958 spin_unlock_irqrestore(&port->lock, flags); 1120 spin_unlock_irqrestore(&port->lock, flags);
959 while ((start == end) && !port->full) /* No data */ 1121 while ((start == end) && !port->full) /* No data */
960 { 1122 {
1123 DEBUGREAD(printk(KERN_DEBUG "&"));
961 if (file->f_flags & O_NONBLOCK) 1124 if (file->f_flags & O_NONBLOCK)
962 {
963 return -EAGAIN; 1125 return -EAGAIN;
964 }
965 1126
966 interruptible_sleep_on(&port->in_wait_q); 1127 interruptible_sleep_on(&port->in_wait_q);
967 if (signal_pending(current)) 1128 if (signal_pending(current))
968 {
969 return -EINTR; 1129 return -EINTR;
970 } 1130
971 spin_lock_irqsave(&port->lock, flags); 1131 spin_lock_irqsave(&port->lock, flags);
972 start = (unsigned char*)port->readp; /* cast away volatile */ 1132 start = (unsigned char*)port->readp; /* cast away volatile */
973 end = (unsigned char*)port->writep; /* cast away volatile */ 1133 end = (unsigned char*)port->writep; /* cast away volatile */
@@ -1004,83 +1164,105 @@ static void send_word(sync_port* port)
1004 switch(tr_cfg.sample_size) 1164 switch(tr_cfg.sample_size)
1005 { 1165 {
1006 case 8: 1166 case 8:
1007 port->out_count--; 1167 port->out_buf_count--;
1008 tr_data.data = *port->outp++; 1168 tr_data.data = *port->out_rd_ptr++;
1009 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1169 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1010 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1170 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1011 port->outp = port->out_buffer; 1171 port->out_rd_ptr = port->out_buffer;
1012 break; 1172 break;
1013 case 12: 1173 case 12:
1014 { 1174 {
1015 int data = (*port->outp++) << 8; 1175 int data = (*port->out_rd_ptr++) << 8;
1016 data |= *port->outp++; 1176 data |= *port->out_rd_ptr++;
1017 port->out_count-=2; 1177 port->out_buf_count -= 2;
1018 tr_data.data = data; 1178 tr_data.data = data;
1019 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1179 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1020 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1180 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1021 port->outp = port->out_buffer; 1181 port->out_rd_ptr = port->out_buffer;
1022 } 1182 }
1023 break; 1183 break;
1024 case 16: 1184 case 16:
1025 port->out_count-=2; 1185 port->out_buf_count -= 2;
1026 tr_data.data = *(unsigned short *)port->outp; 1186 tr_data.data = *(unsigned short *)port->out_rd_ptr;
1027 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1187 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1028 port->outp+=2; 1188 port->out_rd_ptr += 2;
1029 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1189 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1030 port->outp = port->out_buffer; 1190 port->out_rd_ptr = port->out_buffer;
1031 break; 1191 break;
1032 case 24: 1192 case 24:
1033 port->out_count-=3; 1193 port->out_buf_count -= 3;
1034 tr_data.data = *(unsigned short *)port->outp; 1194 tr_data.data = *(unsigned short *)port->out_rd_ptr;
1035 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1195 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1036 port->outp+=2; 1196 port->out_rd_ptr += 2;
1037 tr_data.data = *port->outp++; 1197 tr_data.data = *port->out_rd_ptr++;
1038 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1198 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1039 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1199 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1040 port->outp = port->out_buffer; 1200 port->out_rd_ptr = port->out_buffer;
1041 break; 1201 break;
1042 case 32: 1202 case 32:
1043 port->out_count-=4; 1203 port->out_buf_count -= 4;
1044 tr_data.data = *(unsigned short *)port->outp; 1204 tr_data.data = *(unsigned short *)port->out_rd_ptr;
1045 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1205 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1046 port->outp+=2; 1206 port->out_rd_ptr += 2;
1047 tr_data.data = *(unsigned short *)port->outp; 1207 tr_data.data = *(unsigned short *)port->out_rd_ptr;
1048 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1208 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1049 port->outp+=2; 1209 port->out_rd_ptr += 2;
1050 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1210 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1051 port->outp = port->out_buffer; 1211 port->out_rd_ptr = port->out_buffer;
1052 break; 1212 break;
1053 } 1213 }
1054} 1214}
1055 1215
1056 1216static void start_dma_out(struct sync_port *port,
1057static void start_dma(struct sync_port* port, const char* data, int count) 1217 const char *data, int count)
1058{ 1218{
1059 port->tr_running = 1; 1219 port->active_tr_descr->buf = (char *) virt_to_phys((char *) data);
1060 port->out_descr.buf = (char*)virt_to_phys((char*)data); 1220 port->active_tr_descr->after = port->active_tr_descr->buf + count;
1061 port->out_descr.after = port->out_descr.buf + count; 1221 port->active_tr_descr->intr = 1;
1062 port->out_descr.eol = port->out_descr.intr = 1; 1222
1223 port->active_tr_descr->eol = 1;
1224 port->prev_tr_descr->eol = 0;
1225
1226 DEBUGTRDMA(printk(KERN_DEBUG "Inserting eolr:%p eol@:%p\n",
1227 port->prev_tr_descr, port->active_tr_descr));
1228 port->prev_tr_descr = port->active_tr_descr;
1229 port->active_tr_descr = phys_to_virt((int) port->active_tr_descr->next);
1230
1231 if (!port->tr_running) {
1232 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser,
1233 rw_tr_cfg);
1063 1234
1064 port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr); 1235 port->out_context.next = 0;
1065 port->out_context.saved_data_buf = port->out_descr.buf; 1236 port->out_context.saved_data =
1237 (dma_descr_data *)virt_to_phys(port->prev_tr_descr);
1238 port->out_context.saved_data_buf = port->prev_tr_descr->buf;
1239
1240 DMA_START_CONTEXT(port->regi_dmaout,
1241 virt_to_phys((char *)&port->out_context));
1242
1243 tr_cfg.tr_en = regk_sser_yes;
1244 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
1245 DEBUGTRDMA(printk(KERN_DEBUG "dma s\n"););
1246 } else {
1247 DMA_CONTINUE_DATA(port->regi_dmaout);
1248 DEBUGTRDMA(printk(KERN_DEBUG "dma c\n"););
1249 }
1066 1250
1067 DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context)); 1251 port->tr_running = 1;
1068 DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
1069} 1252}
1070 1253
1071static void start_dma_in(sync_port* port) 1254static void start_dma_in(sync_port *port)
1072{ 1255{
1073 int i; 1256 int i;
1074 char* buf; 1257 char *buf;
1075 port->writep = port->flip; 1258 port->writep = port->flip;
1076 1259
1077 if (port->writep > port->flip + port->in_buffer_size) 1260 if (port->writep > port->flip + port->in_buffer_size) {
1078 {
1079 panic("Offset too large in sync serial driver\n"); 1261 panic("Offset too large in sync serial driver\n");
1080 return; 1262 return;
1081 } 1263 }
1082 buf = (char*)virt_to_phys(port->in_buffer); 1264 buf = (char*)virt_to_phys(port->in_buffer);
1083 for (i = 0; i < NUM_IN_DESCR; i++) { 1265 for (i = 0; i < NBR_IN_DESCR; i++) {
1084 port->in_descr[i].buf = buf; 1266 port->in_descr[i].buf = buf;
1085 port->in_descr[i].after = buf + port->inbufchunk; 1267 port->in_descr[i].after = buf + port->inbufchunk;
1086 port->in_descr[i].intr = 1; 1268 port->in_descr[i].intr = 1;
@@ -1092,59 +1274,126 @@ static void start_dma_in(sync_port* port)
1092 port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); 1274 port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]);
1093 port->in_descr[i-1].eol = regk_sser_yes; 1275 port->in_descr[i-1].eol = regk_sser_yes;
1094 port->next_rx_desc = &port->in_descr[0]; 1276 port->next_rx_desc = &port->in_descr[0];
1095 port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1]; 1277 port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR - 1];
1096 port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); 1278 port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]);
1097 port->in_context.saved_data_buf = port->in_descr[0].buf; 1279 port->in_context.saved_data_buf = port->in_descr[0].buf;
1098 DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context)); 1280 DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context));
1099} 1281}
1100 1282
1101#ifdef SYNC_SER_DMA 1283#ifdef SYNC_SER_DMA
1102static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) 1284static irqreturn_t tr_interrupt(int irq, void *dev_id)
1103{ 1285{
1104 reg_dma_r_masked_intr masked; 1286 reg_dma_r_masked_intr masked;
1105 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; 1287 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
1288 reg_dma_rw_stat stat;
1106 int i; 1289 int i;
1107 struct dma_descr_data *descr;
1108 unsigned int sentl;
1109 int found = 0; 1290 int found = 0;
1291 int stop_sser = 0;
1110 1292
1111 for (i = 0; i < NUMBER_OF_PORTS; i++) 1293 for (i = 0; i < NBR_PORTS; i++) {
1112 {
1113 sync_port *port = &ports[i]; 1294 sync_port *port = &ports[i];
1114 if (!port->enabled || !port->use_dma ) 1295 if (!port->enabled || !port->use_dma)
1115 continue; 1296 continue;
1116 1297
1298 /* IRQ active for the port? */
1117 masked = REG_RD(dma, port->regi_dmaout, r_masked_intr); 1299 masked = REG_RD(dma, port->regi_dmaout, r_masked_intr);
1300 if (!masked.data)
1301 continue;
1118 1302
1119 if (masked.data) /* IRQ active for the port? */ 1303 found = 1;
1120 { 1304
1121 found = 1; 1305 /* Check if we should stop the DMA transfer */
1122 /* Clear IRQ */ 1306 stat = REG_RD(dma, port->regi_dmaout, rw_stat);
1123 REG_WR(dma, port->regi_dmaout, rw_ack_intr, ack_intr); 1307 if (stat.list_state == regk_dma_data_at_eol)
1124 descr = &port->out_descr; 1308 stop_sser = 1;
1125 sentl = descr->after - descr->buf; 1309
1126 port->out_count -= sentl; 1310 /* Clear IRQ */
1127 port->outp += sentl; 1311 REG_WR(dma, port->regi_dmaout, rw_ack_intr, ack_intr);
1128 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) 1312
1129 port->outp = port->out_buffer; 1313 if (!stop_sser) {
1130 if (port->out_count) { 1314 /* The DMA has completed a descriptor, EOL was not
1131 int c; 1315 * encountered, so step relevant descriptor and
1132 c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; 1316 * datapointers forward. */
1133 if (c > port->out_count) 1317 int sent;
1134 c = port->out_count; 1318 sent = port->catch_tr_descr->after -
1135 DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c)); 1319 port->catch_tr_descr->buf;
1136 start_dma(port, port->outp, c); 1320 DEBUGTXINT(printk(KERN_DEBUG "%-4d - %-4d = %-4d\t"
1137 } else { 1321 "in descr %p (ac: %p)\n",
1138 DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl)); 1322 port->out_buf_count, sent,
1139 port->tr_running = 0; 1323 port->out_buf_count - sent,
1324 port->catch_tr_descr,
1325 port->active_tr_descr););
1326 port->out_buf_count -= sent;
1327 port->catch_tr_descr =
1328 phys_to_virt((int) port->catch_tr_descr->next);
1329 port->out_rd_ptr =
1330 phys_to_virt((int) port->catch_tr_descr->buf);
1331 } else {
1332 int i, sent;
1333 /* EOL handler.
1334 * Note that if an EOL was encountered during the irq
1335 * locked section of sync_ser_write the DMA will be
1336 * restarted and the eol flag will be cleared.
1337 * The remaining descriptors will be traversed by
1338 * the descriptor interrupts as usual.
1339 */
1340 i = 0;
1341 while (!port->catch_tr_descr->eol) {
1342 sent = port->catch_tr_descr->after -
1343 port->catch_tr_descr->buf;
1344 DEBUGOUTBUF(printk(KERN_DEBUG
1345 "traversing descr %p -%d (%d)\n",
1346 port->catch_tr_descr,
1347 sent,
1348 port->out_buf_count));
1349 port->out_buf_count -= sent;
1350 port->catch_tr_descr = phys_to_virt(
1351 (int)port->catch_tr_descr->next);
1352 i++;
1353 if (i >= NBR_OUT_DESCR) {
1354 /* TODO: Reset and recover */
1355 panic("sync_serial: missing eol");
1356 }
1140 } 1357 }
1141 wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */ 1358 sent = port->catch_tr_descr->after -
1359 port->catch_tr_descr->buf;
1360 DEBUGOUTBUF(printk(KERN_DEBUG
1361 "eol at descr %p -%d (%d)\n",
1362 port->catch_tr_descr,
1363 sent,
1364 port->out_buf_count));
1365
1366 port->out_buf_count -= sent;
1367
1368 /* Update read pointer to first free byte, we
1369 * may already be writing data there. */
1370 port->out_rd_ptr =
1371 phys_to_virt((int) port->catch_tr_descr->after);
1372 if (port->out_rd_ptr > port->out_buffer +
1373 OUT_BUFFER_SIZE)
1374 port->out_rd_ptr = port->out_buffer;
1375
1376 reg_sser_rw_tr_cfg tr_cfg =
1377 REG_RD(sser, port->regi_sser, rw_tr_cfg);
1378 DEBUGTXINT(printk(KERN_DEBUG
1379 "tr_int DMA stop %d, set catch @ %p\n",
1380 port->out_buf_count,
1381 port->active_tr_descr));
1382 if (port->out_buf_count != 0)
1383 printk(KERN_CRIT "sync_ser: buffer not "
1384 "empty after eol.\n");
1385 port->catch_tr_descr = port->active_tr_descr;
1386 port->tr_running = 0;
1387 tr_cfg.tr_en = regk_sser_no;
1388 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
1142 } 1389 }
1390 /* wake up the waiting process */
1391 wake_up_interruptible(&port->out_wait_q);
1143 } 1392 }
1144 return IRQ_RETVAL(found); 1393 return IRQ_RETVAL(found);
1145} /* tr_interrupt */ 1394} /* tr_interrupt */
1146 1395
1147static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) 1396static irqreturn_t rx_interrupt(int irq, void *dev_id)
1148{ 1397{
1149 reg_dma_r_masked_intr masked; 1398 reg_dma_r_masked_intr masked;
1150 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; 1399 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
@@ -1152,7 +1401,7 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1152 int i; 1401 int i;
1153 int found = 0; 1402 int found = 0;
1154 1403
1155 for (i = 0; i < NUMBER_OF_PORTS; i++) 1404 for (i = 0; i < NBR_PORTS; i++)
1156 { 1405 {
1157 sync_port *port = &ports[i]; 1406 sync_port *port = &ports[i];
1158 1407
@@ -1166,7 +1415,7 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1166 found = 1; 1415 found = 1;
1167 while (REG_RD(dma, port->regi_dmain, rw_data) != 1416 while (REG_RD(dma, port->regi_dmain, rw_data) !=
1168 virt_to_phys(port->next_rx_desc)) { 1417 virt_to_phys(port->next_rx_desc)) {
1169 1418 DEBUGRXINT(printk(KERN_DEBUG "!"));
1170 if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) { 1419 if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
1171 int first_size = port->flip + port->in_buffer_size - port->writep; 1420 int first_size = port->flip + port->in_buffer_size - port->writep;
1172 memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size); 1421 memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size);
@@ -1185,11 +1434,16 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1185 port->full = 1; 1434 port->full = 1;
1186 } 1435 }
1187 1436
1188 port->next_rx_desc->eol = 0; 1437 port->next_rx_desc->eol = 1;
1189 port->prev_rx_desc->eol = 1; 1438 port->prev_rx_desc->eol = 0;
1190 port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc); 1439 /* Cache bug workaround */
1440 flush_dma_descr(port->prev_rx_desc, 0);
1441 port->prev_rx_desc = port->next_rx_desc;
1191 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next); 1442 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
1192 wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */ 1443 /* Cache bug workaround */
1444 flush_dma_descr(port->prev_rx_desc, 1);
1445 /* wake up the waiting process */
1446 wake_up_interruptible(&port->in_wait_q);
1193 DMA_CONTINUE(port->regi_dmain); 1447 DMA_CONTINUE(port->regi_dmain);
1194 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr); 1448 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
1195 1449
@@ -1201,15 +1455,15 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1201#endif /* SYNC_SER_DMA */ 1455#endif /* SYNC_SER_DMA */
1202 1456
1203#ifdef SYNC_SER_MANUAL 1457#ifdef SYNC_SER_MANUAL
1204static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs) 1458static irqreturn_t manual_interrupt(int irq, void *dev_id)
1205{ 1459{
1206 int i; 1460 int i;
1207 int found = 0; 1461 int found = 0;
1208 reg_sser_r_masked_intr masked; 1462 reg_sser_r_masked_intr masked;
1209 1463
1210 for (i = 0; i < NUMBER_OF_PORTS; i++) 1464 for (i = 0; i < NBR_PORTS; i++)
1211 { 1465 {
1212 sync_port* port = &ports[i]; 1466 sync_port *port = &ports[i];
1213 1467
1214 if (!port->enabled || port->use_dma) 1468 if (!port->enabled || port->use_dma)
1215 { 1469 {
@@ -1263,7 +1517,7 @@ static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs
1263 if (masked.trdy) /* Transmitter ready? */ 1517 if (masked.trdy) /* Transmitter ready? */
1264 { 1518 {
1265 found = 1; 1519 found = 1;
1266 if (port->out_count > 0) /* More data to send */ 1520 if (port->out_buf_count > 0) /* More data to send */
1267 send_word(port); 1521 send_word(port);
1268 else /* transmission finished */ 1522 else /* transmission finished */
1269 { 1523 {
diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile
index 5d5b613cde8c..993d987b0078 100644
--- a/arch/cris/arch-v32/kernel/Makefile
+++ b/arch/cris/arch-v32/kernel/Makefile
@@ -1,4 +1,3 @@
1# $Id: Makefile,v 1.11 2004/12/17 10:16:13 starvik Exp $
2# 1#
3# Makefile for the linux kernel. 2# Makefile for the linux kernel.
4# 3#
@@ -6,9 +5,9 @@
6extra-y := head.o 5extra-y := head.o
7 6
8 7
9obj-y := entry.o traps.o irq.o debugport.o dma.o pinmux.o \ 8obj-y := entry.o traps.o irq.o debugport.o \
10 process.o ptrace.o setup.o signal.o traps.o time.o \ 9 process.o ptrace.o setup.o signal.o traps.o time.o \
11 arbiter.o io.o 10 cache.o cacheflush.o
12 11
13obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o 12obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
14 13
diff --git a/arch/cris/arch-v32/kernel/arbiter.c b/arch/cris/arch-v32/kernel/arbiter.c
deleted file mode 100644
index 420a5312ed03..000000000000
--- a/arch/cris/arch-v32/kernel/arbiter.c
+++ /dev/null
@@ -1,296 +0,0 @@
1/*
2 * Memory arbiter functions. Allocates bandwidth through the
3 * arbiter and sets up arbiter breakpoints.
4 *
5 * The algorithm first assigns slots to the clients that has specified
6 * bandwidth (e.g. ethernet) and then the remaining slots are divided
7 * on all the active clients.
8 *
9 * Copyright (c) 2004, 2005 Axis Communications AB.
10 */
11
12#include <asm/arch/hwregs/reg_map.h>
13#include <asm/arch/hwregs/reg_rdwr.h>
14#include <asm/arch/hwregs/marb_defs.h>
15#include <asm/arch/arbiter.h>
16#include <asm/arch/hwregs/intr_vect.h>
17#include <linux/interrupt.h>
18#include <linux/signal.h>
19#include <linux/errno.h>
20#include <linux/spinlock.h>
21#include <asm/io.h>
22
23struct crisv32_watch_entry
24{
25 unsigned long instance;
26 watch_callback* cb;
27 unsigned long start;
28 unsigned long end;
29 int used;
30};
31
32#define NUMBER_OF_BP 4
33#define NBR_OF_CLIENTS 14
34#define NBR_OF_SLOTS 64
35#define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */
36#define INTMEM_BANDWIDTH 400000000
37#define NBR_OF_REGIONS 2
38
39static struct crisv32_watch_entry watches[NUMBER_OF_BP] =
40{
41 {regi_marb_bp0},
42 {regi_marb_bp1},
43 {regi_marb_bp2},
44 {regi_marb_bp3}
45};
46
47static int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
48static int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
49static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH};
50
51DEFINE_SPINLOCK(arbiter_lock);
52
53static irqreturn_t
54crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs);
55
56static void crisv32_arbiter_config(int region)
57{
58 int slot;
59 int client;
60 int interval = 0;
61 int val[NBR_OF_SLOTS];
62
63 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
64 val[slot] = NBR_OF_CLIENTS + 1;
65
66 for (client = 0; client < NBR_OF_CLIENTS; client++)
67 {
68 int pos;
69 if (!requested_slots[region][client])
70 continue;
71 interval = NBR_OF_SLOTS / requested_slots[region][client];
72 pos = 0;
73 while (pos < NBR_OF_SLOTS)
74 {
75 if (val[pos] != NBR_OF_CLIENTS + 1)
76 pos++;
77 else
78 {
79 val[pos] = client;
80 pos += interval;
81 }
82 }
83 }
84
85 client = 0;
86 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
87 {
88 if (val[slot] == NBR_OF_CLIENTS + 1)
89 {
90 int first = client;
91 while(!active_clients[region][client]) {
92 client = (client + 1) % NBR_OF_CLIENTS;
93 if (client == first)
94 break;
95 }
96 val[slot] = client;
97 client = (client + 1) % NBR_OF_CLIENTS;
98 }
99 if (region == EXT_REGION)
100 REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, val[slot]);
101 else if (region == INT_REGION)
102 REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, val[slot]);
103 }
104}
105
106extern char _stext, _etext;
107
108static void crisv32_arbiter_init(void)
109{
110 static int initialized = 0;
111
112 if (initialized)
113 return;
114
115 initialized = 1;
116
117 /* CPU caches are active. */
118 active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
119 crisv32_arbiter_config(EXT_REGION);
120 crisv32_arbiter_config(INT_REGION);
121
122 if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
123 "arbiter", NULL))
124 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
125
126#ifndef CONFIG_ETRAX_KGDB
127 /* Global watch for writes to kernel text segment. */
128 crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
129 arbiter_all_clients, arbiter_all_write, NULL);
130#endif
131}
132
133
134
135int crisv32_arbiter_allocate_bandwidth(int client, int region,
136 unsigned long bandwidth)
137{
138 int i;
139 int total_assigned = 0;
140 int total_clients = 0;
141 int req;
142
143 crisv32_arbiter_init();
144
145 for (i = 0; i < NBR_OF_CLIENTS; i++)
146 {
147 total_assigned += requested_slots[region][i];
148 total_clients += active_clients[region][i];
149 }
150 req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
151
152 if (total_assigned + total_clients + req + 1 > NBR_OF_SLOTS)
153 return -ENOMEM;
154
155 active_clients[region][client] = 1;
156 requested_slots[region][client] = req;
157 crisv32_arbiter_config(region);
158
159 return 0;
160}
161
162int crisv32_arbiter_watch(unsigned long start, unsigned long size,
163 unsigned long clients, unsigned long accesses,
164 watch_callback* cb)
165{
166 int i;
167
168 crisv32_arbiter_init();
169
170 if (start > 0x80000000) {
171 printk("Arbiter: %lX doesn't look like a physical address", start);
172 return -EFAULT;
173 }
174
175 spin_lock(&arbiter_lock);
176
177 for (i = 0; i < NUMBER_OF_BP; i++) {
178 if (!watches[i].used) {
179 reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
180
181 watches[i].used = 1;
182 watches[i].start = start;
183 watches[i].end = start + size;
184 watches[i].cb = cb;
185
186 REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr, watches[i].start);
187 REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr, watches[i].end);
188 REG_WR_INT(marb_bp, watches[i].instance, rw_op, accesses);
189 REG_WR_INT(marb_bp, watches[i].instance, rw_clients, clients);
190
191 if (i == 0)
192 intr_mask.bp0 = regk_marb_yes;
193 else if (i == 1)
194 intr_mask.bp1 = regk_marb_yes;
195 else if (i == 2)
196 intr_mask.bp2 = regk_marb_yes;
197 else if (i == 3)
198 intr_mask.bp3 = regk_marb_yes;
199
200 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
201 spin_unlock(&arbiter_lock);
202
203 return i;
204 }
205 }
206 spin_unlock(&arbiter_lock);
207 return -ENOMEM;
208}
209
210int crisv32_arbiter_unwatch(int id)
211{
212 reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
213
214 crisv32_arbiter_init();
215
216 spin_lock(&arbiter_lock);
217
218 if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
219 spin_unlock(&arbiter_lock);
220 return -EINVAL;
221 }
222
223 memset(&watches[id], 0, sizeof(struct crisv32_watch_entry));
224
225 if (id == 0)
226 intr_mask.bp0 = regk_marb_no;
227 else if (id == 1)
228 intr_mask.bp2 = regk_marb_no;
229 else if (id == 2)
230 intr_mask.bp2 = regk_marb_no;
231 else if (id == 3)
232 intr_mask.bp3 = regk_marb_no;
233
234 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
235
236 spin_unlock(&arbiter_lock);
237 return 0;
238}
239
240extern void show_registers(struct pt_regs *regs);
241
242static irqreturn_t
243crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs)
244{
245 reg_marb_r_masked_intr masked_intr = REG_RD(marb, regi_marb, r_masked_intr);
246 reg_marb_bp_r_brk_clients r_clients;
247 reg_marb_bp_r_brk_addr r_addr;
248 reg_marb_bp_r_brk_op r_op;
249 reg_marb_bp_r_brk_first_client r_first;
250 reg_marb_bp_r_brk_size r_size;
251 reg_marb_bp_rw_ack ack = {0};
252 reg_marb_rw_ack_intr ack_intr = {.bp0=1,.bp1=1,.bp2=1,.bp3=1};
253 struct crisv32_watch_entry* watch;
254
255 if (masked_intr.bp0) {
256 watch = &watches[0];
257 ack_intr.bp0 = regk_marb_yes;
258 } else if (masked_intr.bp1) {
259 watch = &watches[1];
260 ack_intr.bp1 = regk_marb_yes;
261 } else if (masked_intr.bp2) {
262 watch = &watches[2];
263 ack_intr.bp2 = regk_marb_yes;
264 } else if (masked_intr.bp3) {
265 watch = &watches[3];
266 ack_intr.bp3 = regk_marb_yes;
267 } else {
268 return IRQ_NONE;
269 }
270
271 /* Retrieve all useful information and print it. */
272 r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients);
273 r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr);
274 r_op = REG_RD(marb_bp, watch->instance, r_brk_op);
275 r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client);
276 r_size = REG_RD(marb_bp, watch->instance, r_brk_size);
277
278 printk("Arbiter IRQ\n");
279 printk("Clients %X addr %X op %X first %X size %X\n",
280 REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients),
281 REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr),
282 REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op),
283 REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first),
284 REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size));
285
286 REG_WR(marb_bp, watch->instance, rw_ack, ack);
287 REG_WR(marb, regi_marb, rw_ack_intr, ack_intr);
288
289 printk("IRQ occured at %lX\n", regs->erp);
290
291 if (watch->cb)
292 watch->cb();
293
294
295 return IRQ_HANDLED;
296}
diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c
index e513da711245..77d02c15a7fc 100644
--- a/arch/cris/arch-v32/kernel/crisksyms.c
+++ b/arch/cris/arch-v32/kernel/crisksyms.c
@@ -2,7 +2,8 @@
2#include <linux/irq.h> 2#include <linux/irq.h>
3#include <asm/arch/dma.h> 3#include <asm/arch/dma.h>
4#include <asm/arch/intmem.h> 4#include <asm/arch/intmem.h>
5#include <asm/arch/pinmux.h> 5#include <asm/arch/mach/pinmux.h>
6#include <asm/arch/io.h>
6 7
7/* Functions for allocating DMA channels */ 8/* Functions for allocating DMA channels */
8EXPORT_SYMBOL(crisv32_request_dma); 9EXPORT_SYMBOL(crisv32_request_dma);
@@ -16,7 +17,11 @@ EXPORT_SYMBOL(crisv32_intmem_virt_to_phys);
16 17
17/* Functions for handling pinmux */ 18/* Functions for handling pinmux */
18EXPORT_SYMBOL(crisv32_pinmux_alloc); 19EXPORT_SYMBOL(crisv32_pinmux_alloc);
20EXPORT_SYMBOL(crisv32_pinmux_alloc_fixed);
19EXPORT_SYMBOL(crisv32_pinmux_dealloc); 21EXPORT_SYMBOL(crisv32_pinmux_dealloc);
22EXPORT_SYMBOL(crisv32_pinmux_dealloc_fixed);
23EXPORT_SYMBOL(crisv32_io_get_name);
24EXPORT_SYMBOL(crisv32_io_get);
20 25
21/* Functions masking/unmasking interrupts */ 26/* Functions masking/unmasking interrupts */
22EXPORT_SYMBOL(mask_irq); 27EXPORT_SYMBOL(mask_irq);
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
index d1272ad92153..15af4c293157 100644
--- a/arch/cris/arch-v32/kernel/debugport.c
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -4,17 +4,12 @@
4 4
5#include <linux/console.h> 5#include <linux/console.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/major.h>
8#include <linux/delay.h>
9#include <linux/tty.h>
10#include <asm/system.h> 7#include <asm/system.h>
11#include <asm/io.h> 8#include <hwregs/reg_rdwr.h>
12#include <asm/arch/hwregs/ser_defs.h> 9#include <hwregs/reg_map.h>
13#include <asm/arch/hwregs/dma_defs.h> 10#include <hwregs/ser_defs.h>
14#include <asm/arch/pinmux.h> 11#include <hwregs/dma_defs.h>
15 12#include <asm/arch/mach/pinmux.h>
16#include <asm/irq.h>
17#include <asm/arch/hwregs/intr_vect_defs.h>
18 13
19struct dbg_port 14struct dbg_port
20{ 15{
@@ -59,45 +54,50 @@ struct dbg_port ports[] =
59 115200, 54 115200,
60 'N', 55 'N',
61 8 56 8
62 } 57 },
58#if CONFIG_ETRAX_SERIAL_PORTS == 5
59 {
60 4,
61 regi_ser4,
62 0,
63 115200,
64 'N',
65 8
66 },
67#endif
63}; 68};
64static struct dbg_port *port = 69static struct dbg_port *port =
65#if defined(CONFIG_ETRAX_DEBUG_PORT0) 70#if defined(CONFIG_ETRAX_DEBUG_PORT0)
66&ports[0]; 71 &ports[0];
67#elif defined(CONFIG_ETRAX_DEBUG_PORT1) 72#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
68&ports[1]; 73 &ports[1];
69#elif defined(CONFIG_ETRAX_DEBUG_PORT2) 74#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
70&ports[2]; 75 &ports[2];
71#elif defined(CONFIG_ETRAX_DEBUG_PORT3) 76#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
72&ports[3]; 77 &ports[3];
78#elif defined(CONFIG_ETRAX_DEBUG_PORT4)
79 &ports[4];
73#else 80#else
74NULL; 81 NULL;
75#endif 82#endif
76 83
77#ifdef CONFIG_ETRAX_KGDB 84#ifdef CONFIG_ETRAX_KGDB
78static struct dbg_port *kgdb_port = 85static struct dbg_port *kgdb_port =
79#if defined(CONFIG_ETRAX_KGDB_PORT0) 86#if defined(CONFIG_ETRAX_KGDB_PORT0)
80&ports[0]; 87 &ports[0];
81#elif defined(CONFIG_ETRAX_KGDB_PORT1) 88#elif defined(CONFIG_ETRAX_KGDB_PORT1)
82&ports[1]; 89 &ports[1];
83#elif defined(CONFIG_ETRAX_KGDB_PORT2) 90#elif defined(CONFIG_ETRAX_KGDB_PORT2)
84&ports[2]; 91 &ports[2];
85#elif defined(CONFIG_ETRAX_KGDB_PORT3) 92#elif defined(CONFIG_ETRAX_KGDB_PORT3)
86&ports[3]; 93 &ports[3];
94#elif defined(CONFIG_ETRAX_KGDB_PORT4)
95 &ports[4];
87#else 96#else
88NULL; 97 NULL;
89#endif 98#endif
90#endif 99#endif
91 100
92#ifdef CONFIG_ETRAXFS_SIM
93extern void print_str( const char *str );
94static char buffer[1024];
95static char msg[] = "Debug: ";
96static int buffer_pos = sizeof(msg) - 1;
97#endif
98
99extern struct tty_driver *serial_driver;
100
101static void 101static void
102start_port(struct dbg_port* p) 102start_port(struct dbg_port* p)
103{ 103{
@@ -114,6 +114,10 @@ start_port(struct dbg_port* p)
114 crisv32_pinmux_alloc_fixed(pinmux_ser2); 114 crisv32_pinmux_alloc_fixed(pinmux_ser2);
115 else if (p->nbr == 3) 115 else if (p->nbr == 3)
116 crisv32_pinmux_alloc_fixed(pinmux_ser3); 116 crisv32_pinmux_alloc_fixed(pinmux_ser3);
117#if CONFIG_ETRAX_SERIAL_PORTS == 5
118 else if (p->nbr == 4)
119 crisv32_pinmux_alloc_fixed(pinmux_ser4);
120#endif
117 121
118 /* Set up serial port registers */ 122 /* Set up serial port registers */
119 reg_ser_rw_tr_ctrl tr_ctrl = {0}; 123 reg_ser_rw_tr_ctrl tr_ctrl = {0};
@@ -156,124 +160,21 @@ start_port(struct dbg_port* p)
156 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); 160 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
157} 161}
158 162
159/* No debug */
160#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
161
162static void
163console_write(struct console *co, const char *buf, unsigned int len)
164{
165 return;
166}
167
168/* Target debug */
169#elif !defined(CONFIG_ETRAXFS_SIM)
170
171static void
172console_write_direct(struct console *co, const char *buf, unsigned int len)
173{
174 int i;
175 reg_ser_r_stat_din stat;
176 reg_ser_rw_tr_dma_en tr_dma_en, old;
177
178 /* Switch to manual mode */
179 tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
180 if (tr_dma_en.en == regk_ser_yes) {
181 tr_dma_en.en = regk_ser_no;
182 REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
183 }
184
185 /* Send data */
186 for (i = 0; i < len; i++) {
187 /* LF -> CRLF */
188 if (buf[i] == '\n') {
189 do {
190 stat = REG_RD (ser, port->instance, r_stat_din);
191 } while (!stat.tr_rdy);
192 REG_WR_INT (ser, port->instance, rw_dout, '\r');
193 }
194 /* Wait until transmitter is ready and send.*/
195 do {
196 stat = REG_RD (ser, port->instance, r_stat_din);
197 } while (!stat.tr_rdy);
198 REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
199 }
200
201 /* Restore mode */
202 if (tr_dma_en.en != old.en)
203 REG_WR(ser, port->instance, rw_tr_dma_en, old);
204}
205
206static void
207console_write(struct console *co, const char *buf, unsigned int len)
208{
209 if (!port)
210 return;
211 console_write_direct(co, buf, len);
212}
213
214
215
216#else
217
218/* VCS debug */
219
220static void
221console_write(struct console *co, const char *buf, unsigned int len)
222{
223 char* pos;
224 pos = memchr(buf, '\n', len);
225 if (pos) {
226 int l = ++pos - buf;
227 memcpy(buffer + buffer_pos, buf, l);
228 memcpy(buffer, msg, sizeof(msg) - 1);
229 buffer[buffer_pos + l] = '\0';
230 print_str(buffer);
231 buffer_pos = sizeof(msg) - 1;
232 if (pos - buf != len) {
233 memcpy(buffer + buffer_pos, pos, len - l);
234 buffer_pos += len - l;
235 }
236 } else {
237 memcpy(buffer + buffer_pos, buf, len);
238 buffer_pos += len;
239 }
240}
241
242#endif
243
244int raw_printk(const char *fmt, ...)
245{
246 static char buf[1024];
247 int printed_len;
248 va_list args;
249 va_start(args, fmt);
250 printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
251 va_end(args);
252 console_write(NULL, buf, strlen(buf));
253 return printed_len;
254}
255
256void
257stupid_debug(char* buf)
258{
259 console_write(NULL, buf, strlen(buf));
260}
261
262#ifdef CONFIG_ETRAX_KGDB 163#ifdef CONFIG_ETRAX_KGDB
263/* Use polling to get a single character from the kernel debug port */ 164/* Use polling to get a single character from the kernel debug port */
264int 165int
265getDebugChar(void) 166getDebugChar(void)
266{ 167{
267 reg_ser_rs_status_data stat; 168 reg_ser_rs_stat_din stat;
268 reg_ser_rw_ack_intr ack_intr = { 0 }; 169 reg_ser_rw_ack_intr ack_intr = { 0 };
269 170
270 do { 171 do {
271 stat = REG_RD(ser, kgdb_instance, rs_status_data); 172 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
272 } while (!stat.data_avail); 173 } while (!stat.dav);
273 174
274 /* Ack the data_avail interrupt. */ 175 /* Ack the data_avail interrupt. */
275 ack_intr.data_avail = 1; 176 ack_intr.dav = 1;
276 REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr); 177 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
277 178
278 return stat.data; 179 return stat.data;
279} 180}
@@ -282,173 +183,18 @@ getDebugChar(void)
282void 183void
283putDebugChar(int val) 184putDebugChar(int val)
284{ 185{
285 reg_ser_r_status_data stat; 186 reg_ser_r_stat_din stat;
286 do { 187 do {
287 stat = REG_RD (ser, kgdb_instance, r_status_data); 188 stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
288 } while (!stat.tr_ready); 189 } while (!stat.tr_rdy);
289 REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val)); 190 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
290} 191}
291#endif /* CONFIG_ETRAX_KGDB */ 192#endif /* CONFIG_ETRAX_KGDB */
292 193
293static int __init
294console_setup(struct console *co, char *options)
295{
296 char* s;
297
298 if (options) {
299 port = &ports[co->index];
300 port->baudrate = 115200;
301 port->parity = 'N';
302 port->bits = 8;
303 port->baudrate = simple_strtoul(options, NULL, 10);
304 s = options;
305 while(*s >= '0' && *s <= '9')
306 s++;
307 if (*s) port->parity = *s++;
308 if (*s) port->bits = *s++ - '0';
309 port->started = 0;
310 start_port(port);
311 }
312 return 0;
313}
314
315/* This is a dummy serial device that throws away anything written to it.
316 * This is used when no debug output is wanted.
317 */
318static struct tty_driver dummy_driver;
319
320static int dummy_open(struct tty_struct *tty, struct file * filp)
321{
322 return 0;
323}
324
325static void dummy_close(struct tty_struct *tty, struct file * filp)
326{
327}
328
329static int dummy_write(struct tty_struct * tty,
330 const unsigned char *buf, int count)
331{
332 return count;
333}
334
335static int
336dummy_write_room(struct tty_struct *tty)
337{
338 return 8192;
339}
340
341void __init
342init_dummy_console(void)
343{
344 memset(&dummy_driver, 0, sizeof(struct tty_driver));
345 dummy_driver.driver_name = "serial";
346 dummy_driver.name = "ttyS";
347 dummy_driver.major = TTY_MAJOR;
348 dummy_driver.minor_start = 68;
349 dummy_driver.num = 1; /* etrax100 has 4 serial ports */
350 dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
351 dummy_driver.subtype = SERIAL_TYPE_NORMAL;
352 dummy_driver.init_termios = tty_std_termios;
353 dummy_driver.init_termios.c_cflag =
354 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
355 dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
356
357 dummy_driver.open = dummy_open;
358 dummy_driver.close = dummy_close;
359 dummy_driver.write = dummy_write;
360 dummy_driver.write_room = dummy_write_room;
361 if (tty_register_driver(&dummy_driver))
362 panic("Couldn't register dummy serial driver\n");
363}
364
365static struct tty_driver*
366crisv32_console_device(struct console* co, int *index)
367{
368 if (port)
369 *index = port->nbr;
370 return port ? serial_driver : &dummy_driver;
371}
372
373static struct console sercons = {
374 name : "ttyS",
375 write: console_write,
376 read : NULL,
377 device : crisv32_console_device,
378 unblank : NULL,
379 setup : console_setup,
380 flags : CON_PRINTBUFFER,
381 index : -1,
382 cflag : 0,
383 next : NULL
384};
385static struct console sercons0 = {
386 name : "ttyS",
387 write: console_write,
388 read : NULL,
389 device : crisv32_console_device,
390 unblank : NULL,
391 setup : console_setup,
392 flags : CON_PRINTBUFFER,
393 index : 0,
394 cflag : 0,
395 next : NULL
396};
397
398static struct console sercons1 = {
399 name : "ttyS",
400 write: console_write,
401 read : NULL,
402 device : crisv32_console_device,
403 unblank : NULL,
404 setup : console_setup,
405 flags : CON_PRINTBUFFER,
406 index : 1,
407 cflag : 0,
408 next : NULL
409};
410static struct console sercons2 = {
411 name : "ttyS",
412 write: console_write,
413 read : NULL,
414 device : crisv32_console_device,
415 unblank : NULL,
416 setup : console_setup,
417 flags : CON_PRINTBUFFER,
418 index : 2,
419 cflag : 0,
420 next : NULL
421};
422static struct console sercons3 = {
423 name : "ttyS",
424 write: console_write,
425 read : NULL,
426 device : crisv32_console_device,
427 unblank : NULL,
428 setup : console_setup,
429 flags : CON_PRINTBUFFER,
430 index : 3,
431 cflag : 0,
432 next : NULL
433};
434
435/* Register console for printk's, etc. */ 194/* Register console for printk's, etc. */
436int __init 195int __init
437init_etrax_debug(void) 196init_etrax_debug(void)
438{ 197{
439 static int first = 1;
440
441 if (!first) {
442 unregister_console(&sercons);
443 register_console(&sercons0);
444 register_console(&sercons1);
445 register_console(&sercons2);
446 register_console(&sercons3);
447 init_dummy_console();
448 return 0;
449 }
450 first = 0;
451 register_console(&sercons);
452 start_port(port); 198 start_port(port);
453 199
454#ifdef CONFIG_ETRAX_KGDB 200#ifdef CONFIG_ETRAX_KGDB
@@ -456,5 +202,3 @@ init_etrax_debug(void)
456#endif /* CONFIG_ETRAX_KGDB */ 202#endif /* CONFIG_ETRAX_KGDB */
457 return 0; 203 return 0;
458} 204}
459
460__initcall(init_etrax_debug);
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S
index f9d27807b914..eebbaba45430 100644
--- a/arch/cris/arch-v32/kernel/entry.S
+++ b/arch/cris/arch-v32/kernel/entry.S
@@ -10,7 +10,7 @@
10 * after a timer-interrupt and after each system call. 10 * after a timer-interrupt and after each system call.
11 * 11 *
12 * Stack layout in 'ret_from_system_call': 12 * Stack layout in 'ret_from_system_call':
13 * ptrace needs to have all regs on the stack. 13 * ptrace needs to have all regs on the stack.
14 * if the order here is changed, it needs to be 14 * if the order here is changed, it needs to be
15 * updated in fork.c:copy_process, signal.c:do_signal, 15 * updated in fork.c:copy_process, signal.c:do_signal,
16 * ptrace.c and ptrace.h 16 * ptrace.c and ptrace.h
@@ -281,12 +281,10 @@ _work_notifysig:
281 ;; Deal with pending signals and notify-resume requests. 281 ;; Deal with pending signals and notify-resume requests.
282 282
283 addoq +TI_flags, $r0, $acr 283 addoq +TI_flags, $r0, $acr
284 move.d [$acr], $r13 ; The thread_info_flags parameter. 284 move.d [$acr], $r12 ; The thread_info_flags parameter.
285 move.d $r9, $r10 ; do_notify_resume syscall/irq param. 285 move.d $sp, $r11 ; The regs param.
286 moveq 0, $r11 ; oldset param - 0 in this case.
287 move.d $sp, $r12 ; The regs param.
288 jsr do_notify_resume 286 jsr do_notify_resume
289 nop 287 move.d $r9, $r10 ; do_notify_resume syscall/irq param.
290 288
291 ba _Rexit 289 ba _Rexit
292 nop 290 nop
@@ -396,7 +394,7 @@ nmi_interrupt:
396 btstq REG_BIT(intr_vect, r_nmi, watchdog), $r0 394 btstq REG_BIT(intr_vect, r_nmi, watchdog), $r0
397 bpl 1f 395 bpl 1f
398 nop 396 nop
399 jsr handle_watchdog_bite ; In time.c. 397 jsr handle_watchdog_bite ; In time.c.
400 move.d $sp, $r10 ; Pointer to registers 398 move.d $sp, $r10 ; Pointer to registers
4011: btstq REG_BIT(intr_vect, r_nmi, ext), $r0 3991: btstq REG_BIT(intr_vect, r_nmi, ext), $r0
402 bpl 1f 400 bpl 1f
@@ -515,6 +513,13 @@ _ugdb_handle_exception:
515 ba do_sigtrap ; SIGTRAP the offending process. 513 ba do_sigtrap ; SIGTRAP the offending process.
516 move.d [$sp+], $r0 ; Restore R0 in delay slot. 514 move.d [$sp+], $r0 ; Restore R0 in delay slot.
517 515
516 .global kernel_execve
517kernel_execve:
518 move.d __NR_execve, $r9
519 break 13
520 ret
521 nop
522
518 .data 523 .data
519 524
520 .section .rodata,"a" 525 .section .rodata,"a"
@@ -778,21 +783,21 @@ sys_call_table:
778 .long sys_epoll_ctl /* 255 */ 783 .long sys_epoll_ctl /* 255 */
779 .long sys_epoll_wait 784 .long sys_epoll_wait
780 .long sys_remap_file_pages 785 .long sys_remap_file_pages
781 .long sys_set_tid_address 786 .long sys_set_tid_address
782 .long sys_timer_create 787 .long sys_timer_create
783 .long sys_timer_settime /* 260 */ 788 .long sys_timer_settime /* 260 */
784 .long sys_timer_gettime 789 .long sys_timer_gettime
785 .long sys_timer_getoverrun 790 .long sys_timer_getoverrun
786 .long sys_timer_delete 791 .long sys_timer_delete
787 .long sys_clock_settime 792 .long sys_clock_settime
788 .long sys_clock_gettime /* 265 */ 793 .long sys_clock_gettime /* 265 */
789 .long sys_clock_getres 794 .long sys_clock_getres
790 .long sys_clock_nanosleep 795 .long sys_clock_nanosleep
791 .long sys_statfs64 796 .long sys_statfs64
792 .long sys_fstatfs64 797 .long sys_fstatfs64
793 .long sys_tgkill /* 270 */ 798 .long sys_tgkill /* 270 */
794 .long sys_utimes 799 .long sys_utimes
795 .long sys_fadvise64_64 800 .long sys_fadvise64_64
796 .long sys_ni_syscall /* sys_vserver */ 801 .long sys_ni_syscall /* sys_vserver */
797 .long sys_ni_syscall /* sys_mbind */ 802 .long sys_ni_syscall /* sys_mbind */
798 .long sys_ni_syscall /* 275 sys_get_mempolicy */ 803 .long sys_ni_syscall /* 275 sys_get_mempolicy */
@@ -805,6 +810,48 @@ sys_call_table:
805 .long sys_mq_getsetattr 810 .long sys_mq_getsetattr
806 .long sys_ni_syscall /* reserved for kexec */ 811 .long sys_ni_syscall /* reserved for kexec */
807 .long sys_waitid 812 .long sys_waitid
813 .long sys_ni_syscall /* 285 */ /* available */
814 .long sys_add_key
815 .long sys_request_key
816 .long sys_keyctl
817 .long sys_ioprio_set
818 .long sys_ioprio_get /* 290 */
819 .long sys_inotify_init
820 .long sys_inotify_add_watch
821 .long sys_inotify_rm_watch
822 .long sys_migrate_pages
823 .long sys_openat /* 295 */
824 .long sys_mkdirat
825 .long sys_mknodat
826 .long sys_fchownat
827 .long sys_futimesat
828 .long sys_fstatat64 /* 300 */
829 .long sys_unlinkat
830 .long sys_renameat
831 .long sys_linkat
832 .long sys_symlinkat
833 .long sys_readlinkat /* 305 */
834 .long sys_fchmodat
835 .long sys_faccessat
836 .long sys_pselect6
837 .long sys_ppoll
838 .long sys_unshare /* 310 */
839 .long sys_set_robust_list
840 .long sys_get_robust_list
841 .long sys_splice
842 .long sys_sync_file_range
843 .long sys_tee /* 315 */
844 .long sys_vmsplice
845 .long sys_move_pages
846 .long sys_getcpu
847 .long sys_epoll_pwait
848 .long sys_utimensat /* 320 */
849 .long sys_signalfd
850 .long sys_timerfd_create
851 .long sys_eventfd
852 .long sys_fallocate
853 .long sys_timerfd_settime /* 325 */
854 .long sys_timerfd_gettime
808 855
809 /* 856 /*
810 * NOTE!! This doesn't have to be exact - we just have 857 * NOTE!! This doesn't have to be exact - we just have
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index b40551f9f40d..2de9d5849ef0 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -1,110 +1,9 @@
1/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $ 1/*
2 * linux/arch/cris/kernel/fasttimer.c 2 * linux/arch/cris/kernel/fasttimer.c
3 * 3 *
4 * Fast timers for ETRAX FS 4 * Fast timers for ETRAX FS
5 * This may be useful in other OS than Linux so use 2 space indentation...
6 *
7 * $Log: fasttimer.c,v $
8 * Revision 1.11 2005/01/04 11:15:46 starvik
9 * Don't share timer IRQ.
10 *
11 * Revision 1.10 2004/12/07 09:19:38 starvik
12 * Corrected includes.
13 * Use correct interrupt macros.
14 *
15 * Revision 1.9 2004/05/14 10:18:58 starvik
16 * Export fast_timer_list
17 *
18 * Revision 1.8 2004/05/14 07:58:03 starvik
19 * Merge of changes from 2.4
20 *
21 * Revision 1.7 2003/07/10 12:06:14 starvik
22 * Return IRQ_NONE if irq wasn't handled
23 *
24 * Revision 1.6 2003/07/04 08:27:49 starvik
25 * Merge of Linux 2.5.74
26 *
27 * Revision 1.5 2003/06/05 10:16:22 johana
28 * New INTR_VECT macros.
29 *
30 * Revision 1.4 2003/06/03 08:49:45 johana
31 * Fixed typo.
32 *
33 * Revision 1.3 2003/06/02 12:51:27 johana
34 * Now compiles.
35 * Commented some include files that probably can be removed.
36 *
37 * Revision 1.2 2003/06/02 12:09:41 johana
38 * Ported to ETRAX FS using the trig interrupt instead of timer1.
39 *
40 * Revision 1.3 2002/12/12 08:26:32 starvik
41 * Don't use C-comments inside CVS comments
42 *
43 * Revision 1.2 2002/12/11 15:42:02 starvik
44 * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
45 *
46 * Revision 1.1 2002/11/18 07:58:06 starvik
47 * Fast timers (from Linux 2.4)
48 *
49 * Revision 1.5 2002/10/15 06:21:39 starvik
50 * Added call to init_waitqueue_head
51 * 5 *
52 * Revision 1.4 2002/05/28 17:47:59 johana 6 * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
53 * Added del_fast_timer()
54 *
55 * Revision 1.3 2002/05/28 16:16:07 johana
56 * Handle empty fast_timer_list
57 *
58 * Revision 1.2 2002/05/27 15:38:42 johana
59 * Made it compile without warnings on Linux 2.4.
60 * (includes, wait_queue, PROC_FS and snprintf)
61 *
62 * Revision 1.1 2002/05/27 15:32:25 johana
63 * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
64 *
65 * Revision 1.8 2001/11/27 13:50:40 pkj
66 * Disable interrupts while stopping the timer and while modifying the
67 * list of active timers in timer1_handler() as it may be interrupted
68 * by other interrupts (e.g., the serial interrupt) which may add fast
69 * timers.
70 *
71 * Revision 1.7 2001/11/22 11:50:32 pkj
72 * * Only store information about the last 16 timers.
73 * * proc_fasttimer_read() now uses an allocated buffer, since it
74 * requires more space than just a page even for only writing the
75 * last 16 timers. The buffer is only allocated on request, so
76 * unless /proc/fasttimer is read, it is never allocated.
77 * * Renamed fast_timer_started to fast_timers_started to match
78 * fast_timers_added and fast_timers_expired.
79 * * Some clean-up.
80 *
81 * Revision 1.6 2000/12/13 14:02:08 johana
82 * Removed volatile for fast_timer_list
83 *
84 * Revision 1.5 2000/12/13 13:55:35 johana
85 * Added DEBUG_LOG, added som cli() and cleanup
86 *
87 * Revision 1.4 2000/12/05 13:48:50 johana
88 * Added range check when writing proc file, modified timer int handling
89 *
90 * Revision 1.3 2000/11/23 10:10:20 johana
91 * More debug/logging possibilities.
92 * Moved GET_JIFFIES_USEC() to timex.h and time.c
93 *
94 * Revision 1.2 2000/11/01 13:41:04 johana
95 * Clean up and bugfixes.
96 * Created new do_gettimeofday_fast() that gets a timeval struct
97 * with time based on jiffies and *R_TIMER0_DATA, uses a table
98 * for fast conversion of timer value to microseconds.
99 * (Much faster the standard do_gettimeofday() and we don't really
100 * want to use the true time - we want the "uptime" so timers don't screw up
101 * when we change the time.
102 * TODO: Add efficient support for continuous timers as well.
103 *
104 * Revision 1.1 2000/10/26 15:49:16 johana
105 * Added fasttimer, highresolution timers.
106 *
107 * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
108 */ 7 */
109 8
110#include <linux/errno.h> 9#include <linux/errno.h>
@@ -122,9 +21,9 @@
122 21
123#include <linux/version.h> 22#include <linux/version.h>
124 23
125#include <asm/arch/hwregs/reg_map.h> 24#include <hwregs/reg_map.h>
126#include <asm/arch/hwregs/reg_rdwr.h> 25#include <hwregs/reg_rdwr.h>
127#include <asm/arch/hwregs/timer_defs.h> 26#include <hwregs/timer_defs.h>
128#include <asm/fasttimer.h> 27#include <asm/fasttimer.h>
129#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
130 29
@@ -140,30 +39,25 @@
140 39
141#define DEBUG_LOG_INCLUDED 40#define DEBUG_LOG_INCLUDED
142#define FAST_TIMER_LOG 41#define FAST_TIMER_LOG
143//#define FAST_TIMER_TEST 42/* #define FAST_TIMER_TEST */
144 43
145#define FAST_TIMER_SANITY_CHECKS 44#define FAST_TIMER_SANITY_CHECKS
146 45
147#ifdef FAST_TIMER_SANITY_CHECKS 46#ifdef FAST_TIMER_SANITY_CHECKS
148#define SANITYCHECK(x) x 47static int sanity_failed;
149static int sanity_failed = 0;
150#else
151#define SANITYCHECK(x)
152#endif 48#endif
153 49
154#define D1(x) 50#define D1(x)
155#define D2(x) 51#define D2(x)
156#define DP(x) 52#define DP(x)
157 53
158#define __INLINE__ inline 54static unsigned int fast_timer_running;
159 55static unsigned int fast_timers_added;
160static int fast_timer_running = 0; 56static unsigned int fast_timers_started;
161static int fast_timers_added = 0; 57static unsigned int fast_timers_expired;
162static int fast_timers_started = 0; 58static unsigned int fast_timers_deleted;
163static int fast_timers_expired = 0; 59static unsigned int fast_timer_is_init;
164static int fast_timers_deleted = 0; 60static unsigned int fast_timer_ints;
165static int fast_timer_is_init = 0;
166static int fast_timer_ints = 0;
167 61
168struct fast_timer *fast_timer_list = NULL; 62struct fast_timer *fast_timer_list = NULL;
169 63
@@ -171,8 +65,8 @@ struct fast_timer *fast_timer_list = NULL;
171#define DEBUG_LOG_MAX 128 65#define DEBUG_LOG_MAX 128
172static const char * debug_log_string[DEBUG_LOG_MAX]; 66static const char * debug_log_string[DEBUG_LOG_MAX];
173static unsigned long debug_log_value[DEBUG_LOG_MAX]; 67static unsigned long debug_log_value[DEBUG_LOG_MAX];
174static int debug_log_cnt = 0; 68static unsigned int debug_log_cnt;
175static int debug_log_cnt_wrapped = 0; 69static unsigned int debug_log_cnt_wrapped;
176 70
177#define DEBUG_LOG(string, value) \ 71#define DEBUG_LOG(string, value) \
178{ \ 72{ \
@@ -202,103 +96,92 @@ struct fast_timer timer_expired_log[NUM_TIMER_STATS];
202int timer_div_settings[NUM_TIMER_STATS]; 96int timer_div_settings[NUM_TIMER_STATS];
203int timer_delay_settings[NUM_TIMER_STATS]; 97int timer_delay_settings[NUM_TIMER_STATS];
204 98
99struct work_struct fast_work;
205 100
206static void 101static void
207timer_trig_handler(void); 102timer_trig_handler(struct work_struct *work);
208 103
209 104
210 105
211/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ 106/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
212void __INLINE__ do_gettimeofday_fast(struct timeval *tv) 107inline void do_gettimeofday_fast(struct fasttime_t *tv)
213{ 108{
214 unsigned long sec = jiffies; 109 tv->tv_jiff = jiffies;
215 unsigned long usec = GET_JIFFIES_USEC(); 110 tv->tv_usec = GET_JIFFIES_USEC();
216
217 usec += (sec % HZ) * (1000000 / HZ);
218 sec = sec / HZ;
219
220 if (usec > 1000000)
221 {
222 usec -= 1000000;
223 sec++;
224 }
225 tv->tv_sec = sec;
226 tv->tv_usec = usec;
227} 111}
228 112
229int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1) 113inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
230{ 114{
231 if (t0->tv_sec < t1->tv_sec) 115 /* Compare jiffies. Takes care of wrapping */
232 { 116 if (time_before(t0->tv_jiff, t1->tv_jiff))
233 return -1; 117 return -1;
234 } 118 else if (time_after(t0->tv_jiff, t1->tv_jiff))
235 else if (t0->tv_sec > t1->tv_sec) 119 return 1;
236 { 120
237 return 1; 121 /* Compare us */
238 } 122 if (t0->tv_usec < t1->tv_usec)
239 if (t0->tv_usec < t1->tv_usec) 123 return -1;
240 { 124 else if (t0->tv_usec > t1->tv_usec)
241 return -1; 125 return 1;
242 } 126 return 0;
243 else if (t0->tv_usec > t1->tv_usec)
244 {
245 return 1;
246 }
247 return 0;
248} 127}
249 128
250/* Called with ints off */ 129/* Called with ints off */
251void __INLINE__ start_timer_trig(unsigned long delay_us) 130inline void start_timer_trig(unsigned long delay_us)
252{ 131{
253 reg_timer_rw_ack_intr ack_intr = { 0 }; 132 reg_timer_rw_ack_intr ack_intr = { 0 };
254 reg_timer_rw_intr_mask intr_mask; 133 reg_timer_rw_intr_mask intr_mask;
255 reg_timer_rw_trig trig; 134 reg_timer_rw_trig trig;
256 reg_timer_rw_trig_cfg trig_cfg = { 0 }; 135 reg_timer_rw_trig_cfg trig_cfg = { 0 };
257 reg_timer_r_time r_time; 136 reg_timer_r_time r_time0;
137 reg_timer_r_time r_time1;
138 unsigned char trig_wrap;
139 unsigned char time_wrap;
258 140
259 r_time = REG_RD(timer, regi_timer, r_time); 141 r_time0 = REG_RD(timer, regi_timer0, r_time);
260 142
261 D1(printk("start_timer_trig : %d us freq: %i div: %i\n", 143 D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
262 delay_us, freq_index, div)); 144 delay_us, freq_index, div));
263 /* Clear trig irq */ 145 /* Clear trig irq */
264 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 146 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
265 intr_mask.trig = 0; 147 intr_mask.trig = 0;
266 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 148 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
267 149
268 /* Set timer values */ 150 /* Set timer values and check if trigger wraps. */
269 /* r_time is 100MHz (10 ns resolution) */ 151 /* r_time is 100MHz (10 ns resolution) */
270 trig = r_time + delay_us*(1000/10); 152 trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;
271 153
272 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig; 154 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
273 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; 155 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
274 156
275 /* Ack interrupt */ 157 /* Ack interrupt */
276 ack_intr.trig = 1; 158 ack_intr.trig = 1;
277 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 159 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
278 160
279 /* Start timer */ 161 /* Start timer */
280 REG_WR(timer, regi_timer, rw_trig, trig); 162 REG_WR(timer, regi_timer0, rw_trig, trig);
281 trig_cfg.tmr = regk_timer_time; 163 trig_cfg.tmr = regk_timer_time;
282 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 164 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
283 165
284 /* Check if we have already passed the trig time */ 166 /* Check if we have already passed the trig time */
285 r_time = REG_RD(timer, regi_timer, r_time); 167 r_time1 = REG_RD(timer, regi_timer0, r_time);
286 if (r_time < trig) { 168 time_wrap = r_time1 < r_time0;
169
170 if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
287 /* No, Enable trig irq */ 171 /* No, Enable trig irq */
288 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 172 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
289 intr_mask.trig = 1; 173 intr_mask.trig = 1;
290 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 174 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
291 fast_timers_started++; 175 fast_timers_started++;
292 fast_timer_running = 1; 176 fast_timer_running = 1;
293 } 177 } else {
294 else
295 {
296 /* We have passed the time, disable trig point, ack intr */ 178 /* We have passed the time, disable trig point, ack intr */
297 trig_cfg.tmr = regk_timer_off; 179 trig_cfg.tmr = regk_timer_off;
298 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 180 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
299 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 181 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
300 /* call the int routine directly */ 182 /* call the int routine */
301 timer_trig_handler(); 183 INIT_WORK(&fast_work, timer_trig_handler);
184 schedule_work(&fast_work);
302 } 185 }
303 186
304} 187}
@@ -320,22 +203,20 @@ void start_one_shot_timer(struct fast_timer *t,
320 do_gettimeofday_fast(&t->tv_set); 203 do_gettimeofday_fast(&t->tv_set);
321 tmp = fast_timer_list; 204 tmp = fast_timer_list;
322 205
323 SANITYCHECK({ /* Check so this is not in the list already... */ 206#ifdef FAST_TIMER_SANITY_CHECKS
324 while (tmp != NULL) 207 /* Check so this is not in the list already... */
325 { 208 while (tmp != NULL) {
326 if (tmp == t) 209 if (tmp == t) {
327 { 210 printk(KERN_DEBUG
328 printk("timer name: %s data: 0x%08lX already in list!\n", name, data); 211 "timer name: %s data: 0x%08lX already "
329 sanity_failed++; 212 "in list!\n", name, data);
330 return; 213 sanity_failed++;
331 } 214 goto done;
332 else 215 } else
333 { 216 tmp = tmp->next;
334 tmp = tmp->next; 217 }
335 } 218 tmp = fast_timer_list;
336 } 219#endif
337 tmp = fast_timer_list;
338 });
339 220
340 t->delay_us = delay_us; 221 t->delay_us = delay_us;
341 t->function = function; 222 t->function = function;
@@ -343,11 +224,10 @@ void start_one_shot_timer(struct fast_timer *t,
343 t->name = name; 224 t->name = name;
344 225
345 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; 226 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
346 t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000; 227 t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
347 if (t->tv_expires.tv_usec > 1000000) 228 if (t->tv_expires.tv_usec > 1000000) {
348 {
349 t->tv_expires.tv_usec -= 1000000; 229 t->tv_expires.tv_usec -= 1000000;
350 t->tv_expires.tv_sec++; 230 t->tv_expires.tv_jiff += HZ;
351 } 231 }
352#ifdef FAST_TIMER_LOG 232#ifdef FAST_TIMER_LOG
353 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; 233 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
@@ -355,15 +235,12 @@ void start_one_shot_timer(struct fast_timer *t,
355 fast_timers_added++; 235 fast_timers_added++;
356 236
357 /* Check if this should timeout before anything else */ 237 /* Check if this should timeout before anything else */
358 if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0) 238 if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) {
359 {
360 /* Put first in list and modify the timer value */ 239 /* Put first in list and modify the timer value */
361 t->prev = NULL; 240 t->prev = NULL;
362 t->next = fast_timer_list; 241 t->next = fast_timer_list;
363 if (fast_timer_list) 242 if (fast_timer_list)
364 {
365 fast_timer_list->prev = t; 243 fast_timer_list->prev = t;
366 }
367 fast_timer_list = t; 244 fast_timer_list = t;
368#ifdef FAST_TIMER_LOG 245#ifdef FAST_TIMER_LOG
369 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; 246 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
@@ -372,10 +249,8 @@ void start_one_shot_timer(struct fast_timer *t,
372 } else { 249 } else {
373 /* Put in correct place in list */ 250 /* Put in correct place in list */
374 while (tmp->next && 251 while (tmp->next &&
375 timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) 252 fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
376 {
377 tmp = tmp->next; 253 tmp = tmp->next;
378 }
379 /* Insert t after tmp */ 254 /* Insert t after tmp */
380 t->prev = tmp; 255 t->prev = tmp;
381 t->next = tmp->next; 256 t->next = tmp->next;
@@ -388,6 +263,7 @@ void start_one_shot_timer(struct fast_timer *t,
388 263
389 D2(printk("start_one_shot_timer: %d us done\n", delay_us)); 264 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
390 265
266done:
391 local_irq_restore(flags); 267 local_irq_restore(flags);
392} /* start_one_shot_timer */ 268} /* start_one_shot_timer */
393 269
@@ -431,19 +307,18 @@ int del_fast_timer(struct fast_timer * t)
431/* Timer interrupt handler for trig interrupts */ 307/* Timer interrupt handler for trig interrupts */
432 308
433static irqreturn_t 309static irqreturn_t
434timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs) 310timer_trig_interrupt(int irq, void *dev_id)
435{ 311{
436 reg_timer_r_masked_intr masked_intr; 312 reg_timer_r_masked_intr masked_intr;
437
438 /* Check if the timer interrupt is for us (a trig int) */ 313 /* Check if the timer interrupt is for us (a trig int) */
439 masked_intr = REG_RD(timer, regi_timer, r_masked_intr); 314 masked_intr = REG_RD(timer, regi_timer0, r_masked_intr);
440 if (!masked_intr.trig) 315 if (!masked_intr.trig)
441 return IRQ_NONE; 316 return IRQ_NONE;
442 timer_trig_handler(); 317 timer_trig_handler(NULL);
443 return IRQ_HANDLED; 318 return IRQ_HANDLED;
444} 319}
445 320
446static void timer_trig_handler(void) 321static void timer_trig_handler(struct work_struct *work)
447{ 322{
448 reg_timer_rw_ack_intr ack_intr = { 0 }; 323 reg_timer_rw_ack_intr ack_intr = { 0 };
449 reg_timer_rw_intr_mask intr_mask; 324 reg_timer_rw_intr_mask intr_mask;
@@ -451,38 +326,45 @@ static void timer_trig_handler(void)
451 struct fast_timer *t; 326 struct fast_timer *t;
452 unsigned long flags; 327 unsigned long flags;
453 328
329 /* We keep interrupts disabled not only when we modify the
330 * fast timer list, but any time we hold a reference to a
331 * timer in the list, since del_fast_timer may be called
332 * from (another) interrupt context. Thus, the only time
333 * when interrupts are enabled is when calling the timer
334 * callback function.
335 */
454 local_irq_save(flags); 336 local_irq_save(flags);
455 337
456 /* Clear timer trig interrupt */ 338 /* Clear timer trig interrupt */
457 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 339 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
458 intr_mask.trig = 0; 340 intr_mask.trig = 0;
459 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 341 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
460 342
461 /* First stop timer, then ack interrupt */ 343 /* First stop timer, then ack interrupt */
462 /* Stop timer */ 344 /* Stop timer */
463 trig_cfg.tmr = regk_timer_off; 345 trig_cfg.tmr = regk_timer_off;
464 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 346 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
465 347
466 /* Ack interrupt */ 348 /* Ack interrupt */
467 ack_intr.trig = 1; 349 ack_intr.trig = 1;
468 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 350 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
469 351
470 fast_timer_running = 0; 352 fast_timer_running = 0;
471 fast_timer_ints++; 353 fast_timer_ints++;
472 354
473 local_irq_restore(flags); 355 fast_timer_function_type *f;
356 unsigned long d;
474 357
475 t = fast_timer_list; 358 t = fast_timer_list;
476 while (t) 359 while (t) {
477 { 360 struct fasttime_t tv;
478 struct timeval tv;
479 361
480 /* Has it really expired? */ 362 /* Has it really expired? */
481 do_gettimeofday_fast(&tv); 363 do_gettimeofday_fast(&tv);
482 D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec)); 364 D1(printk(KERN_DEBUG
365 "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
483 366
484 if (timeval_cmp(&t->tv_expires, &tv) <= 0) 367 if (fasttime_cmp(&t->tv_expires, &tv) <= 0) {
485 {
486 /* Yes it has expired */ 368 /* Yes it has expired */
487#ifdef FAST_TIMER_LOG 369#ifdef FAST_TIMER_LOG
488 timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; 370 timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
@@ -490,84 +372,77 @@ static void timer_trig_handler(void)
490 fast_timers_expired++; 372 fast_timers_expired++;
491 373
492 /* Remove this timer before call, since it may reuse the timer */ 374 /* Remove this timer before call, since it may reuse the timer */
493 local_irq_save(flags);
494 if (t->prev) 375 if (t->prev)
495 {
496 t->prev->next = t->next; 376 t->prev->next = t->next;
497 }
498 else 377 else
499 {
500 fast_timer_list = t->next; 378 fast_timer_list = t->next;
501 }
502 if (t->next) 379 if (t->next)
503 {
504 t->next->prev = t->prev; 380 t->next->prev = t->prev;
505 }
506 t->prev = NULL; 381 t->prev = NULL;
507 t->next = NULL; 382 t->next = NULL;
508 local_irq_restore(flags);
509 383
510 if (t->function != NULL) 384 /* Save function callback data before enabling
511 { 385 * interrupts, since the timer may be removed and we
512 t->function(t->data); 386 * don't know how it was allocated (e.g. ->function
513 } 387 * and ->data may become overwritten after deletion
514 else 388 * if the timer was stack-allocated).
515 { 389 */
390 f = t->function;
391 d = t->data;
392
393 if (f != NULL) {
394 /* Run the callback function with interrupts
395 * enabled. */
396 local_irq_restore(flags);
397 f(d);
398 local_irq_save(flags);
399 } else
516 DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints); 400 DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints);
517 } 401 } else {
518 }
519 else
520 {
521 /* Timer is to early, let's set it again using the normal routines */ 402 /* Timer is to early, let's set it again using the normal routines */
522 D1(printk(".\n")); 403 D1(printk(".\n"));
523 } 404 }
524 405
525 local_irq_save(flags); 406 t = fast_timer_list;
526 if ((t = fast_timer_list) != NULL) 407 if (t != NULL) {
527 {
528 /* Start next timer.. */ 408 /* Start next timer.. */
529 long us; 409 long us = 0;
530 struct timeval tv; 410 struct fasttime_t tv;
531 411
532 do_gettimeofday_fast(&tv); 412 do_gettimeofday_fast(&tv);
533 us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 + 413
534 t->tv_expires.tv_usec - tv.tv_usec); 414 /* time_after_eq takes care of wrapping */
535 if (us > 0) 415 if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
536 { 416 us = ((t->tv_expires.tv_jiff - tv.tv_jiff) *
537 if (!fast_timer_running) 417 1000000 / HZ + t->tv_expires.tv_usec -
538 { 418 tv.tv_usec);
419
420 if (us > 0) {
421 if (!fast_timer_running) {
539#ifdef FAST_TIMER_LOG 422#ifdef FAST_TIMER_LOG
540 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; 423 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
541#endif 424#endif
542 start_timer_trig(us); 425 start_timer_trig(us);
543 } 426 }
544 local_irq_restore(flags);
545 break; 427 break;
546 } 428 } else {
547 else
548 {
549 /* Timer already expired, let's handle it better late than never. 429 /* Timer already expired, let's handle it better late than never.
550 * The normal loop handles it 430 * The normal loop handles it
551 */ 431 */
552 D1(printk("e! %d\n", us)); 432 D1(printk("e! %d\n", us));
553 } 433 }
554 } 434 }
555 local_irq_restore(flags);
556 } 435 }
557 436
558 if (!t) 437 local_irq_restore(flags);
559 { 438
439 if (!t)
560 D1(printk("ttrig stop!\n")); 440 D1(printk("ttrig stop!\n"));
561 }
562} 441}
563 442
564static void wake_up_func(unsigned long data) 443static void wake_up_func(unsigned long data)
565{ 444{
566#ifdef DECLARE_WAITQUEUE
567 wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data; 445 wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data;
568#else
569 struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
570#endif
571 wake_up(sleep_wait_p); 446 wake_up(sleep_wait_p);
572} 447}
573 448
@@ -577,28 +452,17 @@ static void wake_up_func(unsigned long data)
577void schedule_usleep(unsigned long us) 452void schedule_usleep(unsigned long us)
578{ 453{
579 struct fast_timer t; 454 struct fast_timer t;
580#ifdef DECLARE_WAITQUEUE
581 wait_queue_head_t sleep_wait; 455 wait_queue_head_t sleep_wait;
582 init_waitqueue_head(&sleep_wait); 456 init_waitqueue_head(&sleep_wait);
583 {
584 DECLARE_WAITQUEUE(wait, current);
585#else
586 struct wait_queue *sleep_wait = NULL;
587 struct wait_queue wait = { current, NULL };
588#endif
589 457
590 D1(printk("schedule_usleep(%d)\n", us)); 458 D1(printk("schedule_usleep(%d)\n", us));
591 add_wait_queue(&sleep_wait, &wait);
592 set_current_state(TASK_INTERRUPTIBLE);
593 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, 459 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
594 "usleep"); 460 "usleep");
595 schedule(); 461 /* Uninterruptible sleep on the fast timer. (The condition is
596 set_current_state(TASK_RUNNING); 462 * somewhat redundant since the timer is what wakes us up.) */
597 remove_wait_queue(&sleep_wait, &wait); 463 wait_event(sleep_wait, !fast_timer_pending(&t));
464
598 D1(printk("done schedule_usleep(%d)\n", us)); 465 D1(printk("done schedule_usleep(%d)\n", us));
599#ifdef DECLARE_WAITQUEUE
600 }
601#endif
602} 466}
603 467
604#ifdef CONFIG_PROC_FS 468#ifdef CONFIG_PROC_FS
@@ -618,20 +482,22 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
618 unsigned long flags; 482 unsigned long flags;
619 int i = 0; 483 int i = 0;
620 int num_to_show; 484 int num_to_show;
621 struct timeval tv; 485 struct fasttime_t tv;
622 struct fast_timer *t, *nextt; 486 struct fast_timer *t, *nextt;
623 static char *bigbuf = NULL; 487 static char *bigbuf = NULL;
624 static unsigned long used; 488 static unsigned long used;
625 489
626 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) 490 if (!bigbuf) {
627 { 491 bigbuf = vmalloc(BIG_BUF_SIZE);
628 used = 0; 492 if (!bigbuf) {
629 bigbuf[0] = '\0'; 493 used = 0;
630 return 0; 494 if (buf)
631 } 495 buf[0] = '\0';
632 496 return 0;
633 if (!offset || !used) 497 }
634 { 498 }
499
500 if (!offset || !used) {
635 do_gettimeofday_fast(&tv); 501 do_gettimeofday_fast(&tv);
636 502
637 used = 0; 503 used = 0;
@@ -648,7 +514,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
648 used += sprintf(bigbuf + used, "Fast timer running: %s\n", 514 used += sprintf(bigbuf + used, "Fast timer running: %s\n",
649 fast_timer_running ? "yes" : "no"); 515 fast_timer_running ? "yes" : "no");
650 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", 516 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n",
651 (unsigned long)tv.tv_sec, 517 (unsigned long)tv.tv_jiff,
652 (unsigned long)tv.tv_usec); 518 (unsigned long)tv.tv_usec);
653#ifdef FAST_TIMER_SANITY_CHECKS 519#ifdef FAST_TIMER_SANITY_CHECKS
654 used += sprintf(bigbuf + used, "Sanity failed: %i\n", 520 used += sprintf(bigbuf + used, "Sanity failed: %i\n",
@@ -661,10 +527,8 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
661 int end_i = debug_log_cnt; 527 int end_i = debug_log_cnt;
662 i = 0; 528 i = 0;
663 529
664 if (debug_log_cnt_wrapped) 530 if (debug_log_cnt_wrapped)
665 {
666 i = debug_log_cnt; 531 i = debug_log_cnt;
667 }
668 532
669 while ((i != end_i || (debug_log_cnt_wrapped && !used)) && 533 while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
670 used+100 < BIG_BUF_SIZE) 534 used+100 < BIG_BUF_SIZE)
@@ -697,9 +561,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
697 "d: %6li us data: 0x%08lX" 561 "d: %6li us data: 0x%08lX"
698 "\n", 562 "\n",
699 t->name, 563 t->name,
700 (unsigned long)t->tv_set.tv_sec, 564 (unsigned long)t->tv_set.tv_jiff,
701 (unsigned long)t->tv_set.tv_usec, 565 (unsigned long)t->tv_set.tv_usec,
702 (unsigned long)t->tv_expires.tv_sec, 566 (unsigned long)t->tv_expires.tv_jiff,
703 (unsigned long)t->tv_expires.tv_usec, 567 (unsigned long)t->tv_expires.tv_usec,
704 t->delay_us, 568 t->delay_us,
705 t->data 569 t->data
@@ -719,9 +583,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
719 "d: %6li us data: 0x%08lX" 583 "d: %6li us data: 0x%08lX"
720 "\n", 584 "\n",
721 t->name, 585 t->name,
722 (unsigned long)t->tv_set.tv_sec, 586 (unsigned long)t->tv_set.tv_jiff,
723 (unsigned long)t->tv_set.tv_usec, 587 (unsigned long)t->tv_set.tv_usec,
724 (unsigned long)t->tv_expires.tv_sec, 588 (unsigned long)t->tv_expires.tv_jiff,
725 (unsigned long)t->tv_expires.tv_usec, 589 (unsigned long)t->tv_expires.tv_usec,
726 t->delay_us, 590 t->delay_us,
727 t->data 591 t->data
@@ -739,9 +603,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
739 "d: %6li us data: 0x%08lX" 603 "d: %6li us data: 0x%08lX"
740 "\n", 604 "\n",
741 t->name, 605 t->name,
742 (unsigned long)t->tv_set.tv_sec, 606 (unsigned long)t->tv_set.tv_jiff,
743 (unsigned long)t->tv_set.tv_usec, 607 (unsigned long)t->tv_set.tv_usec,
744 (unsigned long)t->tv_expires.tv_sec, 608 (unsigned long)t->tv_expires.tv_jiff,
745 (unsigned long)t->tv_expires.tv_usec, 609 (unsigned long)t->tv_expires.tv_usec,
746 t->delay_us, 610 t->delay_us,
747 t->data 611 t->data
@@ -752,26 +616,25 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
752 616
753 used += sprintf(bigbuf + used, "Active timers:\n"); 617 used += sprintf(bigbuf + used, "Active timers:\n");
754 local_irq_save(flags); 618 local_irq_save(flags);
755 local_irq_save(flags);
756 t = fast_timer_list; 619 t = fast_timer_list;
757 while (t != NULL && (used+100 < BIG_BUF_SIZE)) 620 while (t != NULL && (used+100 < BIG_BUF_SIZE))
758 { 621 {
759 nextt = t->next; 622 nextt = t->next;
760 local_irq_restore(flags); 623 local_irq_restore(flags);
761 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " 624 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
762 "d: %6li us data: 0x%08lX" 625 "d: %6li us data: 0x%08lX"
763/* " func: 0x%08lX" */ 626/* " func: 0x%08lX" */
764 "\n", 627 "\n",
765 t->name, 628 t->name,
766 (unsigned long)t->tv_set.tv_sec, 629 (unsigned long)t->tv_set.tv_jiff,
767 (unsigned long)t->tv_set.tv_usec, 630 (unsigned long)t->tv_set.tv_usec,
768 (unsigned long)t->tv_expires.tv_sec, 631 (unsigned long)t->tv_expires.tv_jiff,
769 (unsigned long)t->tv_expires.tv_usec, 632 (unsigned long)t->tv_expires.tv_usec,
770 t->delay_us, 633 t->delay_us,
771 t->data 634 t->data
772/* , t->function */ 635/* , t->function */
773 ); 636 );
774 local_irq_disable(); 637 local_irq_save(flags);
775 if (t->next != nextt) 638 if (t->next != nextt)
776 { 639 {
777 printk("timer removed!\n"); 640 printk("timer removed!\n");
@@ -800,7 +663,7 @@ static volatile int num_test_timeout = 0;
800static struct fast_timer tr[10]; 663static struct fast_timer tr[10];
801static int exp_num[10]; 664static int exp_num[10];
802 665
803static struct timeval tv_exp[100]; 666static struct fasttime_t tv_exp[100];
804 667
805static void test_timeout(unsigned long data) 668static void test_timeout(unsigned long data)
806{ 669{
@@ -838,7 +701,7 @@ static void fast_timer_test(void)
838 int prev_num; 701 int prev_num;
839 int j; 702 int j;
840 703
841 struct timeval tv, tv0, tv1, tv2; 704 struct fasttime_t tv, tv0, tv1, tv2;
842 705
843 printk("fast_timer_test() start\n"); 706 printk("fast_timer_test() start\n");
844 do_gettimeofday_fast(&tv); 707 do_gettimeofday_fast(&tv);
@@ -851,21 +714,22 @@ static void fast_timer_test(void)
851 { 714 {
852 do_gettimeofday_fast(&tv_exp[j]); 715 do_gettimeofday_fast(&tv_exp[j]);
853 } 716 }
854 printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec); 717 printk(KERN_DEBUG "fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
855 718
856 for (j = 0; j < 1000; j++) 719 for (j = 0; j < 1000; j++)
857 { 720 {
858 printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]); 721 printk(KERN_DEBUG "%i %i %i %i %i\n",
722 j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
859 j += 4; 723 j += 4;
860 } 724 }
861 for (j = 0; j < 100; j++) 725 for (j = 0; j < 100; j++)
862 { 726 {
863 printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n", 727 printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n",
864 tv_exp[j].tv_sec,tv_exp[j].tv_usec, 728 tv_exp[j].tv_jiff, tv_exp[j].tv_usec,
865 tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec, 729 tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec,
866 tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec, 730 tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec,
867 tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec, 731 tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec,
868 tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec); 732 tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec);
869 j += 4; 733 j += 4;
870 } 734 }
871 do_gettimeofday_fast(&tv0); 735 do_gettimeofday_fast(&tv0);
@@ -892,14 +756,15 @@ static void fast_timer_test(void)
892 while (num_test_timeout < i) 756 while (num_test_timeout < i)
893 { 757 {
894 if (num_test_timeout != prev_num) 758 if (num_test_timeout != prev_num)
895 {
896 prev_num = num_test_timeout; 759 prev_num = num_test_timeout;
897 }
898 } 760 }
899 do_gettimeofday_fast(&tv2); 761 do_gettimeofday_fast(&tv2);
900 printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec); 762 printk(KERN_INFO "Timers started %is %06i\n",
901 printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec); 763 tv0.tv_jiff, tv0.tv_usec);
902 printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec); 764 printk(KERN_INFO "Timers started at %is %06i\n",
765 tv1.tv_jiff, tv1.tv_usec);
766 printk(KERN_INFO "Timers done %is %06i\n",
767 tv2.tv_jiff, tv2.tv_usec);
903 DP(printk("buf0:\n"); 768 DP(printk("buf0:\n");
904 printk(buf0); 769 printk(buf0);
905 printk("buf1:\n"); 770 printk("buf1:\n");
@@ -921,9 +786,9 @@ static void fast_timer_test(void)
921 printk("%-10s set: %6is %06ius exp: %6is %06ius " 786 printk("%-10s set: %6is %06ius exp: %6is %06ius "
922 "data: 0x%08X func: 0x%08X\n", 787 "data: 0x%08X func: 0x%08X\n",
923 t->name, 788 t->name,
924 t->tv_set.tv_sec, 789 t->tv_set.tv_jiff,
925 t->tv_set.tv_usec, 790 t->tv_set.tv_usec,
926 t->tv_expires.tv_sec, 791 t->tv_expires.tv_jiff,
927 t->tv_expires.tv_usec, 792 t->tv_expires.tv_usec,
928 t->data, 793 t->data,
929 t->function 794 t->function
@@ -931,10 +796,12 @@ static void fast_timer_test(void)
931 796
932 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", 797 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
933 t->delay_us, 798 t->delay_us,
934 tv_exp[j].tv_sec, 799 tv_exp[j].tv_jiff,
935 tv_exp[j].tv_usec, 800 tv_exp[j].tv_usec,
936 exp_num[j], 801 exp_num[j],
937 (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec); 802 (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) *
803 1000000 + tv_exp[j].tv_usec -
804 t->tv_expires.tv_usec);
938 } 805 }
939 proc_fasttimer_read(buf5, NULL, 0, 0, 0); 806 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
940 printk("buf5 after all done:\n"); 807 printk("buf5 after all done:\n");
@@ -944,7 +811,7 @@ static void fast_timer_test(void)
944#endif 811#endif
945 812
946 813
947void fast_timer_init(void) 814int fast_timer_init(void)
948{ 815{
949 /* For some reason, request_irq() hangs when called froom time_init() */ 816 /* For some reason, request_irq() hangs when called froom time_init() */
950 if (!fast_timer_is_init) 817 if (!fast_timer_is_init)
@@ -952,18 +819,20 @@ void fast_timer_init(void)
952 printk("fast_timer_init()\n"); 819 printk("fast_timer_init()\n");
953 820
954#ifdef CONFIG_PROC_FS 821#ifdef CONFIG_PROC_FS
955 if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) 822 fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0);
956 fasttimer_proc_entry->read_proc = proc_fasttimer_read; 823 if (fasttimer_proc_entry)
824 fasttimer_proc_entry->read_proc = proc_fasttimer_read;
957#endif /* PROC_FS */ 825#endif /* PROC_FS */
958 if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED, 826 if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt,
959 "fast timer int", NULL)) 827 IRQF_SHARED | IRQF_DISABLED,
960 { 828 "fast timer int", &fast_timer_list))
961 printk("err: timer1 irq\n"); 829 printk(KERN_ERR "err: fasttimer irq\n");
962 }
963 fast_timer_is_init = 1; 830 fast_timer_is_init = 1;
964#ifdef FAST_TIMER_TEST 831#ifdef FAST_TIMER_TEST
965 printk("do test\n"); 832 printk("do test\n");
966 fast_timer_test(); 833 fast_timer_test();
967#endif 834#endif
968 } 835 }
836 return 0;
969} 837}
838__initcall(fast_timer_init);
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S
index 20bd80a84e48..2d66a7c320e1 100644
--- a/arch/cris/arch-v32/kernel/head.S
+++ b/arch/cris/arch-v32/kernel/head.S
@@ -4,22 +4,25 @@
4 * Copyright (C) 2003, Axis Communications AB 4 * Copyright (C) 2003, Axis Communications AB
5 */ 5 */
6 6
7
8#define ASSEMBLER_MACROS_ONLY 7#define ASSEMBLER_MACROS_ONLY
9 8
10/* 9/*
11 * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so 10 * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so
12 * -traditional must not be used when assembling this file. 11 * -traditional must not be used when assembling this file.
13 */ 12 */
14#include <asm/arch/hwregs/reg_rdwr.h> 13#include <hwregs/reg_rdwr.h>
15#include <asm/arch/hwregs/asm/mmu_defs_asm.h> 14#include <asm/arch/memmap.h>
16#include <asm/arch/hwregs/asm/reg_map_asm.h> 15#include <hwregs/intr_vect.h>
17#include <asm/arch/hwregs/asm/config_defs_asm.h> 16#include <hwregs/asm/mmu_defs_asm.h>
18#include <asm/arch/hwregs/asm/bif_core_defs_asm.h> 17#include <hwregs/asm/reg_map_asm.h>
18#include <asm/arch/mach/startup.inc>
19 19
20#define CRAMFS_MAGIC 0x28cd3d45 20#define CRAMFS_MAGIC 0x28cd3d45
21#define JHEAD_MAGIC 0x1FF528A6
22#define JHEAD_SIZE 8
21#define RAM_INIT_MAGIC 0x56902387 23#define RAM_INIT_MAGIC 0x56902387
22#define COMMAND_LINE_MAGIC 0x87109563 24#define COMMAND_LINE_MAGIC 0x87109563
25#define NAND_BOOT_MAGIC 0x9a9db001
23 26
24 ;; NOTE: R8 and R9 carry information from the decompressor (if the 27 ;; NOTE: R8 and R9 carry information from the decompressor (if the
25 ;; kernel was compressed). They must not be used in the code below 28 ;; kernel was compressed). They must not be used in the code below
@@ -30,12 +33,11 @@
30 .global romfs_start 33 .global romfs_start
31 .global romfs_length 34 .global romfs_length
32 .global romfs_in_flash 35 .global romfs_in_flash
36 .global nand_boot
33 .global swapper_pg_dir 37 .global swapper_pg_dir
34 .global crisv32_nand_boot
35 .global crisv32_nand_cramfs_offset
36 38
37 ;; Dummy section to make it bootable with current VCS simulator 39 ;; Dummy section to make it bootable with current VCS simulator
38#ifdef CONFIG_ETRAXFS_SIM 40#ifdef CONFIG_ETRAX_VCS_SIM
39 .section ".boot", "ax" 41 .section ".boot", "ax"
40 ba tstart 42 ba tstart
41 nop 43 nop
@@ -51,33 +53,15 @@ tstart:
51 ;; 53 ;;
52 di 54 di
53 55
54 ;; Start clocks for used blocks. 56 START_CLOCKS
55 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 57
56 move.d [$r1], $r0 58 SETUP_WAIT_STATES
57 or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ 59
58 REG_STATE(config, rw_clk_ctrl, bif, yes) | \ 60 GIO_INIT
59 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0 61
60 move.d $r0, [$r1] 62#ifdef CONFIG_SMP
61 63secondary_cpu_entry: /* Entry point for secondary CPUs */
62 ;; Set up waitstates etc 64 di
63 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r0
64 move.d CONFIG_ETRAX_MEM_GRP1_CONFIG, $r1
65 move.d $r1, [$r0]
66 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg), $r0
67 move.d CONFIG_ETRAX_MEM_GRP2_CONFIG, $r1
68 move.d $r1, [$r0]
69 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r0
70 move.d CONFIG_ETRAX_MEM_GRP3_CONFIG, $r1
71 move.d $r1, [$r0]
72 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
73 move.d CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
74 move.d $r1, [$r0]
75
76#ifdef CONFIG_ETRAXFS_SIM
77 ;; Set up minimal flash waitstates
78 move.d 0, $r10
79 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
80 move.d $r10, [$r11]
81#endif 65#endif
82 66
83 ;; Setup and enable the MMU. Use same configuration for both the data 67 ;; Setup and enable the MMU. Use same configuration for both the data
@@ -85,7 +69,7 @@ tstart:
85 ;; 69 ;;
86 ;; Note; 3 cycles is needed for a bank-select to take effect. Further; 70 ;; Note; 3 cycles is needed for a bank-select to take effect. Further;
87 ;; bank 1 is the instruction MMU, bank 2 is the data MMU. 71 ;; bank 1 is the instruction MMU, bank 2 is the data MMU.
88#ifndef CONFIG_ETRAXFS_SIM 72#ifndef CONFIG_ETRAX_VCS_SIM
89 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ 73 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
90 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ 74 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
91 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 75 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
@@ -93,7 +77,7 @@ tstart:
93 ;; Map the virtual DRAM to the RW eprom area at address 0. 77 ;; Map the virtual DRAM to the RW eprom area at address 0.
94 ;; Also map 0xa for the hook calls, 78 ;; Also map 0xa for the hook calls,
95 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ 79 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
96 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0) \ 80 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
97 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \ 81 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \
98 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0 82 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
99#endif 83#endif
@@ -104,7 +88,7 @@ tstart:
104 88
105 ;; Enable certain page protections and setup linear mapping 89 ;; Enable certain page protections and setup linear mapping
106 ;; for f,e,c,b,4,0. 90 ;; for f,e,c,b,4,0.
107#ifndef CONFIG_ETRAXFS_SIM 91#ifndef CONFIG_ETRAX_VCS_SIM
108 move.d REG_STATE(mmu, rw_mm_cfg, we, on) \ 92 move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
109 | REG_STATE(mmu, rw_mm_cfg, acc, on) \ 93 | REG_STATE(mmu, rw_mm_cfg, acc, on) \
110 | REG_STATE(mmu, rw_mm_cfg, ex, on) \ 94 | REG_STATE(mmu, rw_mm_cfg, ex, on) \
@@ -183,17 +167,11 @@ tstart:
183 nop 167 nop
184 nop 168 nop
185 nop 169 nop
186 move $s10, $r0 170 move $s12, $r0
187 cmpq 0, $r0 171 cmpq 0, $r0
188 beq master_cpu 172 beq master_cpu
189 nop 173 nop
190slave_cpu: 174slave_cpu:
191 ; A slave waits for cpu_now_booting to be equal to CPU ID.
192 move.d cpu_now_booting, $r1
193slave_wait:
194 cmp.d [$r1], $r0
195 bne slave_wait
196 nop
197 ; Time to boot-up. Get stack location provided by master CPU. 175 ; Time to boot-up. Get stack location provided by master CPU.
198 move.d smp_init_current_idle_thread, $r1 176 move.d smp_init_current_idle_thread, $r1
199 move.d [$r1], $sp 177 move.d [$r1], $sp
@@ -203,9 +181,16 @@ slave_wait:
203 jsr smp_callin 181 jsr smp_callin
204 nop 182 nop
205master_cpu: 183master_cpu:
184 /* Set up entry point for secondary CPUs. The boot ROM has set up
185 * EBP at start of internal memory. The CPU will get there
186 * later when we issue an IPI to them... */
187 move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0
188 move.d secondary_cpu_entry, $r1
189 move.d $r1, [$r0]
206#endif 190#endif
207#ifndef CONFIG_ETRAXFS_SIM 191#ifndef CONFIG_ETRAX_VCS_SIM
208 ;; Check if starting from DRAM or flash. 192 ; Check if starting from DRAM (network->RAM boot or unpacked
193 ; compressed kernel), or directly from flash.
209 lapcq ., $r0 194 lapcq ., $r0
210 and.d 0x7fffffff, $r0 ; Mask off the non-cache bit. 195 and.d 0x7fffffff, $r0 ; Mask off the non-cache bit.
211 cmp.d 0x10000, $r0 ; Arbitrary, something above this code. 196 cmp.d 0x10000, $r0 ; Arbitrary, something above this code.
@@ -232,12 +217,13 @@ _inflash:
232 beq _dram_initialized 217 beq _dram_initialized
233 nop 218 nop
234 219
235#include "../lib/dram_init.S" 220#include "../mach/dram_init.S"
236 221
237_dram_initialized: 222_dram_initialized:
238 ;; Copy the text and data section to DRAM. This depends on that the 223 ;; Copy the text and data section to DRAM. This depends on that the
239 ;; variables used below are correctly set up by the linker script. 224 ;; variables used below are correctly set up by the linker script.
240 ;; The calculated value stored in R4 is used below. 225 ;; The calculated value stored in R4 is used below.
226 ;; Leave the cramfs file system (piggybacked after the kernel) in flash.
241 moveq 0, $r0 ; Source. 227 moveq 0, $r0 ; Source.
242 move.d text_start, $r1 ; Destination. 228 move.d text_start, $r1 ; Destination.
243 move.d __vmlinux_end, $r2 229 move.d __vmlinux_end, $r2
@@ -249,7 +235,7 @@ _dram_initialized:
249 blo 1b 235 blo 1b
250 nop 236 nop
251 237
252 ;; Keep CRAMFS in flash. 238 ;; Check for cramfs.
253 moveq 0, $r0 239 moveq 0, $r0
254 move.d romfs_length, $r1 240 move.d romfs_length, $r1
255 move.d $r0, [$r1] 241 move.d $r0, [$r1]
@@ -258,6 +244,7 @@ _dram_initialized:
258 bne 1f 244 bne 1f
259 nop 245 nop
260 246
247 ;; Set length and start of cramfs, set romfs_in_flash flag
261 addoq +4, $r4, $acr 248 addoq +4, $r4, $acr
262 move.d [$acr], $r0 249 move.d [$acr], $r0
263 move.d romfs_length, $r1 250 move.d romfs_length, $r1
@@ -273,35 +260,32 @@ _dram_initialized:
273 nop 260 nop
274 261
275_inram: 262_inram:
276 ;; Check if booting from NAND flash (in that case we just remember the offset 263 ;; Check if booting from NAND flash; if so, set appropriate flags
277 ;; into the flash where cramfs should be). 264 ;; and move on.
278 move.d REG_ADDR(config, regi_config, r_bootsel), $r0 265 cmp.d NAND_BOOT_MAGIC, $r12
279 move.d [$r0], $r0 266 bne move_cramfs ; not nand, jump
280 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
281 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
282 bne move_cramfs
283 moveq 1,$r0
284 move.d crisv32_nand_boot, $r1
285 move.d $r0, [$r1]
286 move.d crisv32_nand_cramfs_offset, $r1
287 move.d $r9, [$r1]
288 moveq 1, $r0 267 moveq 1, $r0
289 move.d romfs_in_flash, $r1 268 move.d nand_boot, $r1 ; tell axisflashmap we're booting from NAND
269 move.d $r0, [$r1]
270 moveq 0, $r0 ; tell axisflashmap romfs is not in
271 move.d romfs_in_flash, $r1 ; (directly accessed) flash
290 move.d $r0, [$r1] 272 move.d $r0, [$r1]
291 jump _start_it 273 jump _start_it ; continue with boot
292 nop 274 nop
293 275
294move_cramfs: 276move_cramfs:
295 ;; Move the cramfs after BSS. 277 ;; kernel is in DRAM.
278 ;; Must figure out if there is a piggybacked rootfs image or not.
279 ;; Set romfs_length to 0 => no rootfs image available by default.
296 moveq 0, $r0 280 moveq 0, $r0
297 move.d romfs_length, $r1 281 move.d romfs_length, $r1
298 move.d $r0, [$r1] 282 move.d $r0, [$r1]
299 283
300#ifndef CONFIG_ETRAXFS_SIM 284#ifndef CONFIG_ETRAX_VCS_SIM
301 ;; The kernel could have been unpacked to DRAM by the loader, but 285 ;; The kernel could have been unpacked to DRAM by the loader, but
302 ;; the cramfs image could still be inte the flash immediately 286 ;; the cramfs image could still be in the flash immediately
303 ;; following the compressed kernel image. The loaded passes the address 287 ;; following the compressed kernel image. The loader passes the address
304 ;; of the bute succeeding the last compressed byte in the flash in 288 ;; of the byte succeeding the last compressed byte in the flash in
305 ;; register R9 when starting the kernel. 289 ;; register R9 when starting the kernel.
306 cmp.d 0x0ffffff8, $r9 290 cmp.d 0x0ffffff8, $r9
307 bhs _no_romfs_in_flash ; R9 points outside the flash area. 291 bhs _no_romfs_in_flash ; R9 points outside the flash area.
@@ -310,11 +294,13 @@ move_cramfs:
310 ba _no_romfs_in_flash 294 ba _no_romfs_in_flash
311 nop 295 nop
312#endif 296#endif
297 ;; cramfs rootfs might to be in flash. Check for it.
313 move.d [$r9], $r0 ; cramfs_super.magic 298 move.d [$r9], $r0 ; cramfs_super.magic
314 cmp.d CRAMFS_MAGIC, $r0 299 cmp.d CRAMFS_MAGIC, $r0
315 bne _no_romfs_in_flash 300 bne _no_romfs_in_flash
316 nop 301 nop
317 302
303 ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
318 addoq +4, $r9, $acr 304 addoq +4, $r9, $acr
319 move.d [$acr], $r0 305 move.d [$acr], $r0
320 move.d romfs_length, $r1 306 move.d romfs_length, $r1
@@ -330,27 +316,43 @@ move_cramfs:
330 nop 316 nop
331 317
332_no_romfs_in_flash: 318_no_romfs_in_flash:
333 ;; Look for cramfs. 319 ;; No romfs in flash, so look for cramfs, or jffs2 with jhead,
320 ;; after kernel in RAM, as is the case with network->RAM boot.
321 ;; For cramfs, partition starts with magic and length.
322 ;; For jffs2, a jhead is prepended which contains with magic and length.
323 ;; The jhead is not part of the jffs2 partition however.
334#ifndef CONFIG_ETRAXFS_SIM 324#ifndef CONFIG_ETRAXFS_SIM
335 move.d __vmlinux_end, $r0 325 move.d __vmlinux_end, $r0
336#else 326#else
337 move.d __end, $r0 327 move.d __end, $r0
338#endif 328#endif
339 move.d [$r0], $r1 329 move.d [$r0], $r1
340 cmp.d CRAMFS_MAGIC, $r1 330 cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
341 bne 2f 331 beq 2f ; yes, jump
332 nop
333 cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
334 bne 4f ; no, skip copy
342 nop 335 nop
336 addq 4, $r0 ; location of jffs2 size
337 move.d [$r0+], $r2 ; fetch jffs2 size -> r2
338 ; r0 now points to start of jffs2
339 ba 3f
340 nop
3412:
342 addoq +4, $r0, $acr ; location of cramfs size
343 move.d [$acr], $r2 ; fetch cramfs size -> r2
344 ; r0 still points to start of cramfs
3453:
346 ;; Now, move the root fs to after kernel's BSS
343 347
344 addoq +4, $r0, $acr 348 move.d _end, $r1 ; start of cramfs -> r1
345 move.d [$acr], $r2
346 move.d _end, $r1
347 move.d romfs_start, $r3 349 move.d romfs_start, $r3
348 move.d $r1, [$r3] 350 move.d $r1, [$r3] ; store at romfs_start (for axisflashmap)
349 move.d romfs_length, $r3 351 move.d romfs_length, $r3
350 move.d $r2, [$r3] 352 move.d $r2, [$r3] ; store size at romfs_length
351 353
352#ifndef CONFIG_ETRAXFS_SIM 354#ifndef CONFIG_ETRAX_VCS_SIM
353 add.d $r2, $r0 355 add.d $r2, $r0 ; copy from end and downwards
354 add.d $r2, $r1 356 add.d $r2, $r1
355 357
356 lsrq 1, $r2 ; Size is in bytes, we copy words. 358 lsrq 1, $r2 ; Size is in bytes, we copy words.
@@ -365,10 +367,17 @@ _no_romfs_in_flash:
365 nop 367 nop
366#endif 368#endif
367 369
3682: 3704:
371 ;; BSS move done.
372 ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM
373 ;; Also clear nand_boot flag; if we got here, we know we've not
374 ;; booted from NAND flash.
369 moveq 0, $r0 375 moveq 0, $r0
370 move.d romfs_in_flash, $r1 376 move.d romfs_in_flash, $r1
371 move.d $r0, [$r1] 377 move.d $r0, [$r1]
378 moveq 0, $r0
379 move.d nand_boot, $r1
380 move.d $r0, [$r1]
372 381
373 jump _start_it ; Jump to cached code. 382 jump _start_it ; Jump to cached code.
374 nop 383 nop
@@ -384,8 +393,8 @@ _start_it:
384 move.d cris_command_line, $r10 393 move.d cris_command_line, $r10
385 or.d 0x80000000, $r11 ; Make it virtual 394 or.d 0x80000000, $r11 ; Make it virtual
3861: 3951:
387 move.b [$r11+], $r12 396 move.b [$r11+], $r1
388 move.b $r12, [$r10+] 397 move.b $r1, [$r10+]
389 subq 1, $r13 398 subq 1, $r13
390 bne 1b 399 bne 1b
391 nop 400 nop
@@ -401,7 +410,7 @@ no_command_line:
401 move.d etrax_irv, $r1 ; Set the exception base register and pointer. 410 move.d etrax_irv, $r1 ; Set the exception base register and pointer.
402 move.d $r0, [$r1] 411 move.d $r0, [$r1]
403 412
404#ifndef CONFIG_ETRAXFS_SIM 413#ifndef CONFIG_ETRAX_VCS_SIM
405 ;; Clear the BSS region from _bss_start to _end. 414 ;; Clear the BSS region from _bss_start to _end.
406 move.d __bss_start, $r0 415 move.d __bss_start, $r0
407 move.d _end, $r1 416 move.d _end, $r1
@@ -411,7 +420,7 @@ no_command_line:
411 nop 420 nop
412#endif 421#endif
413 422
414#ifdef CONFIG_ETRAXFS_SIM 423#ifdef CONFIG_ETRAX_VCS_SIM
415 /* Set the watchdog timeout to something big. Will be removed when */ 424 /* Set the watchdog timeout to something big. Will be removed when */
416 /* watchdog can be disabled with command line option */ 425 /* watchdog can be disabled with command line option */
417 move.d 0x7fffffff, $r10 426 move.d 0x7fffffff, $r10
@@ -423,25 +432,44 @@ no_command_line:
423 move.d __bss_start, $r0 432 move.d __bss_start, $r0
424 movem [$r0], $r13 433 movem [$r0], $r13
425 434
435#ifdef CONFIG_ETRAX_L2CACHE
436 jsr l2cache_init
437 nop
438#endif
439
426 jump start_kernel ; Jump to start_kernel() in init/main.c. 440 jump start_kernel ; Jump to start_kernel() in init/main.c.
427 nop 441 nop
428 442
429 .data 443 .data
430etrax_irv: 444etrax_irv:
431 .dword 0 445 .dword 0
446
447; Variables for communication with the Axis flash map driver (axisflashmap),
448; and for setting up memory in arch/cris/kernel/setup.c .
449
450; romfs_start is set to the start of the root file system, if it exists
451; in directly accessible memory (i.e. NOR Flash when booting from Flash,
452; or RAM when booting directly from a network-downloaded RAM image)
432romfs_start: 453romfs_start:
433 .dword 0 454 .dword 0
455
456; romfs_length is set to the size of the root file system image, if it exists
457; in directly accessible memory (see romfs_start). Otherwise it is set to 0.
434romfs_length: 458romfs_length:
435 .dword 0 459 .dword 0
460
461; romfs_in_flash is set to 1 if the root file system resides in directly
462; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot
463; or NAND flash boot.
436romfs_in_flash: 464romfs_in_flash:
437 .dword 0 465 .dword 0
438crisv32_nand_boot: 466
439 .dword 0 467; nand_boot is set to 1 when the kernel has been booted from NAND flash
440crisv32_nand_cramfs_offset: 468nand_boot:
441 .dword 0 469 .dword 0
442 470
443swapper_pg_dir = 0xc0002000 471swapper_pg_dir = 0xc0002000
444 472
445 .section ".init.data", "aw" 473 .section ".init.data", "aw"
446 474
447#include "../lib/hw_settings.S" 475#include "../mach/hw_settings.S"
diff --git a/arch/cris/arch-v32/kernel/io.c b/arch/cris/arch-v32/kernel/io.c
deleted file mode 100644
index a22a9e02e093..000000000000
--- a/arch/cris/arch-v32/kernel/io.c
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Helper functions for I/O pins.
3 *
4 * Copyright (c) 2004 Axis Communications AB.
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9#include <linux/init.h>
10#include <linux/string.h>
11#include <linux/ctype.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/io.h>
15#include <asm/arch/pinmux.h>
16#include <asm/arch/hwregs/gio_defs.h>
17
18struct crisv32_ioport crisv32_ioports[] =
19{
20 {
21 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_oe),
22 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_dout),
23 (unsigned long*)REG_ADDR(gio, regi_gio, r_pa_din),
24 8
25 },
26 {
27 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_oe),
28 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_dout),
29 (unsigned long*)REG_ADDR(gio, regi_gio, r_pb_din),
30 18
31 },
32 {
33 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_oe),
34 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_dout),
35 (unsigned long*)REG_ADDR(gio, regi_gio, r_pc_din),
36 18
37 },
38 {
39 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_oe),
40 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_dout),
41 (unsigned long*)REG_ADDR(gio, regi_gio, r_pd_din),
42 18
43 },
44 {
45 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_oe),
46 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout),
47 (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din),
48 18
49 }
50};
51
52#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports)
53
54struct crisv32_iopin crisv32_led1_green;
55struct crisv32_iopin crisv32_led1_red;
56struct crisv32_iopin crisv32_led2_green;
57struct crisv32_iopin crisv32_led2_red;
58struct crisv32_iopin crisv32_led3_green;
59struct crisv32_iopin crisv32_led3_red;
60
61/* Dummy port used when green LED and red LED is on the same bit */
62static unsigned long io_dummy;
63static struct crisv32_ioport dummy_port =
64{
65 &io_dummy,
66 &io_dummy,
67 &io_dummy,
68 18
69};
70static struct crisv32_iopin dummy_led =
71{
72 &dummy_port,
73 0
74};
75
76static int __init crisv32_io_init(void)
77{
78 int ret = 0;
79 /* Initialize LEDs */
80 ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G);
81 ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R);
82 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G);
83 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R);
84 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G);
85 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R);
86 crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out);
87 crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out);
88 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
89 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
90 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
91 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
92
93 if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R))
94 crisv32_led1_red = dummy_led;
95 if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R))
96 crisv32_led2_red = dummy_led;
97
98 return ret;
99}
100
101__initcall(crisv32_io_init);
102
103int crisv32_io_get(struct crisv32_iopin* iopin,
104 unsigned int port, unsigned int pin)
105{
106 if (port > NBR_OF_PORTS)
107 return -EINVAL;
108 if (port > crisv32_ioports[port].pin_count)
109 return -EINVAL;
110
111 iopin->bit = 1 << pin;
112 iopin->port = &crisv32_ioports[port];
113
114 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
115 return -EIO;
116
117 return 0;
118}
119
120int crisv32_io_get_name(struct crisv32_iopin* iopin,
121 char* name)
122{
123 int port;
124 int pin;
125
126 if (toupper(*name) == 'P')
127 name++;
128
129 if (toupper(*name) < 'A' || toupper(*name) > 'E')
130 return -EINVAL;
131
132 port = toupper(*name) - 'A';
133 name++;
134 pin = simple_strtoul(name, NULL, 10);
135
136 if (pin < 0 || pin > crisv32_ioports[port].pin_count)
137 return -EINVAL;
138
139 iopin->bit = 1 << pin;
140 iopin->port = &crisv32_ioports[port];
141
142 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
143 return -EIO;
144
145 return 0;
146}
147
148#ifdef CONFIG_PCI
149/* PCI I/O access stuff */
150struct cris_io_operations* cris_iops = NULL;
151EXPORT_SYMBOL(cris_iops);
152#endif
153
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index a9acaa270243..173c141ac9ba 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -15,15 +15,21 @@
15#include <linux/threads.h> 15#include <linux/threads.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <asm/arch/hwregs/reg_map.h> 18#include <hwregs/reg_map.h>
19#include <asm/arch/hwregs/reg_rdwr.h> 19#include <hwregs/reg_rdwr.h>
20#include <asm/arch/hwregs/intr_vect.h> 20#include <hwregs/intr_vect.h>
21#include <asm/arch/hwregs/intr_vect_defs.h> 21#include <hwregs/intr_vect_defs.h>
22 22
23#define CPU_FIXED -1 23#define CPU_FIXED -1
24 24
25/* IRQ masks (refer to comment for crisv32_do_multiple) */ 25/* IRQ masks (refer to comment for crisv32_do_multiple) */
26#define TIMER_MASK (1 << (TIMER_INTR_VECT - FIRST_IRQ)) 26#if TIMER0_INTR_VECT - FIRST_IRQ < 32
27#define TIMER_MASK (1 << (TIMER0_INTR_VECT - FIRST_IRQ))
28#undef TIMER_VECT1
29#else
30#define TIMER_MASK (1 << (TIMER0_INTR_VECT - FIRST_IRQ - 32))
31#define TIMER_VECT1
32#endif
27#ifdef CONFIG_ETRAX_KGDB 33#ifdef CONFIG_ETRAX_KGDB
28#if defined(CONFIG_ETRAX_KGDB_PORT0) 34#if defined(CONFIG_ETRAX_KGDB_PORT0)
29#define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ)) 35#define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ))
@@ -44,8 +50,8 @@ struct cris_irq_allocation
44 cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */ 50 cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */
45}; 51};
46 52
47struct cris_irq_allocation irq_allocations[NR_IRQS] = 53struct cris_irq_allocation irq_allocations[NR_REAL_IRQS] =
48 {[0 ... NR_IRQS - 1] = {0, CPU_MASK_ALL}}; 54 { [0 ... NR_REAL_IRQS - 1] = {0, CPU_MASK_ALL} };
49 55
50static unsigned long irq_regs[NR_CPUS] = 56static unsigned long irq_regs[NR_CPUS] =
51{ 57{
@@ -55,6 +61,12 @@ static unsigned long irq_regs[NR_CPUS] =
55#endif 61#endif
56}; 62};
57 63
64#if NR_REAL_IRQS > 32
65#define NBR_REGS 2
66#else
67#define NBR_REGS 1
68#endif
69
58unsigned long cpu_irq_counters[NR_CPUS]; 70unsigned long cpu_irq_counters[NR_CPUS];
59unsigned long irq_counters[NR_REAL_IRQS]; 71unsigned long irq_counters[NR_REAL_IRQS];
60 72
@@ -79,45 +91,81 @@ extern void d_mmu_write(void);
79extern void kgdb_init(void); 91extern void kgdb_init(void);
80extern void breakpoint(void); 92extern void breakpoint(void);
81 93
94/* From traps.c. */
95extern void breakh_BUG(void);
96
82/* 97/*
83 * Build the IRQ handler stubs using macros from irq.h. First argument is the 98 * Build the IRQ handler stubs using macros from irq.h.
84 * IRQ number, the second argument is the corresponding bit in
85 * intr_rw_vect_mask found in asm/arch/hwregs/intr_vect_defs.h.
86 */ 99 */
87BUILD_IRQ(0x31, (1 << 0)) /* memarb */ 100BUILD_IRQ(0x31)
88BUILD_IRQ(0x32, (1 << 1)) /* gen_io */ 101BUILD_IRQ(0x32)
89BUILD_IRQ(0x33, (1 << 2)) /* iop0 */ 102BUILD_IRQ(0x33)
90BUILD_IRQ(0x34, (1 << 3)) /* iop1 */ 103BUILD_IRQ(0x34)
91BUILD_IRQ(0x35, (1 << 4)) /* iop2 */ 104BUILD_IRQ(0x35)
92BUILD_IRQ(0x36, (1 << 5)) /* iop3 */ 105BUILD_IRQ(0x36)
93BUILD_IRQ(0x37, (1 << 6)) /* dma0 */ 106BUILD_IRQ(0x37)
94BUILD_IRQ(0x38, (1 << 7)) /* dma1 */ 107BUILD_IRQ(0x38)
95BUILD_IRQ(0x39, (1 << 8)) /* dma2 */ 108BUILD_IRQ(0x39)
96BUILD_IRQ(0x3a, (1 << 9)) /* dma3 */ 109BUILD_IRQ(0x3a)
97BUILD_IRQ(0x3b, (1 << 10)) /* dma4 */ 110BUILD_IRQ(0x3b)
98BUILD_IRQ(0x3c, (1 << 11)) /* dma5 */ 111BUILD_IRQ(0x3c)
99BUILD_IRQ(0x3d, (1 << 12)) /* dma6 */ 112BUILD_IRQ(0x3d)
100BUILD_IRQ(0x3e, (1 << 13)) /* dma7 */ 113BUILD_IRQ(0x3e)
101BUILD_IRQ(0x3f, (1 << 14)) /* dma8 */ 114BUILD_IRQ(0x3f)
102BUILD_IRQ(0x40, (1 << 15)) /* dma9 */ 115BUILD_IRQ(0x40)
103BUILD_IRQ(0x41, (1 << 16)) /* ata */ 116BUILD_IRQ(0x41)
104BUILD_IRQ(0x42, (1 << 17)) /* sser0 */ 117BUILD_IRQ(0x42)
105BUILD_IRQ(0x43, (1 << 18)) /* sser1 */ 118BUILD_IRQ(0x43)
106BUILD_IRQ(0x44, (1 << 19)) /* ser0 */ 119BUILD_IRQ(0x44)
107BUILD_IRQ(0x45, (1 << 20)) /* ser1 */ 120BUILD_IRQ(0x45)
108BUILD_IRQ(0x46, (1 << 21)) /* ser2 */ 121BUILD_IRQ(0x46)
109BUILD_IRQ(0x47, (1 << 22)) /* ser3 */ 122BUILD_IRQ(0x47)
110BUILD_IRQ(0x48, (1 << 23)) 123BUILD_IRQ(0x48)
111BUILD_IRQ(0x49, (1 << 24)) /* eth0 */ 124BUILD_IRQ(0x49)
112BUILD_IRQ(0x4a, (1 << 25)) /* eth1 */ 125BUILD_IRQ(0x4a)
113BUILD_TIMER_IRQ(0x4b, (1 << 26))/* timer */ 126BUILD_IRQ(0x4b)
114BUILD_IRQ(0x4c, (1 << 27)) /* bif_arb */ 127BUILD_IRQ(0x4c)
115BUILD_IRQ(0x4d, (1 << 28)) /* bif_dma */ 128BUILD_IRQ(0x4d)
116BUILD_IRQ(0x4e, (1 << 29)) /* ext */ 129BUILD_IRQ(0x4e)
117BUILD_IRQ(0x4f, (1 << 29)) /* ipi */ 130BUILD_IRQ(0x4f)
131BUILD_IRQ(0x50)
132#if MACH_IRQS > 32
133BUILD_IRQ(0x51)
134BUILD_IRQ(0x52)
135BUILD_IRQ(0x53)
136BUILD_IRQ(0x54)
137BUILD_IRQ(0x55)
138BUILD_IRQ(0x56)
139BUILD_IRQ(0x57)
140BUILD_IRQ(0x58)
141BUILD_IRQ(0x59)
142BUILD_IRQ(0x5a)
143BUILD_IRQ(0x5b)
144BUILD_IRQ(0x5c)
145BUILD_IRQ(0x5d)
146BUILD_IRQ(0x5e)
147BUILD_IRQ(0x5f)
148BUILD_IRQ(0x60)
149BUILD_IRQ(0x61)
150BUILD_IRQ(0x62)
151BUILD_IRQ(0x63)
152BUILD_IRQ(0x64)
153BUILD_IRQ(0x65)
154BUILD_IRQ(0x66)
155BUILD_IRQ(0x67)
156BUILD_IRQ(0x68)
157BUILD_IRQ(0x69)
158BUILD_IRQ(0x6a)
159BUILD_IRQ(0x6b)
160BUILD_IRQ(0x6c)
161BUILD_IRQ(0x6d)
162BUILD_IRQ(0x6e)
163BUILD_IRQ(0x6f)
164BUILD_IRQ(0x70)
165#endif
118 166
119/* Pointers to the low-level handlers. */ 167/* Pointers to the low-level handlers. */
120static void (*interrupt[NR_IRQS])(void) = { 168static void (*interrupt[MACH_IRQS])(void) = {
121 IRQ0x31_interrupt, IRQ0x32_interrupt, IRQ0x33_interrupt, 169 IRQ0x31_interrupt, IRQ0x32_interrupt, IRQ0x33_interrupt,
122 IRQ0x34_interrupt, IRQ0x35_interrupt, IRQ0x36_interrupt, 170 IRQ0x34_interrupt, IRQ0x35_interrupt, IRQ0x36_interrupt,
123 IRQ0x37_interrupt, IRQ0x38_interrupt, IRQ0x39_interrupt, 171 IRQ0x37_interrupt, IRQ0x38_interrupt, IRQ0x39_interrupt,
@@ -128,7 +176,20 @@ static void (*interrupt[NR_IRQS])(void) = {
128 IRQ0x46_interrupt, IRQ0x47_interrupt, IRQ0x48_interrupt, 176 IRQ0x46_interrupt, IRQ0x47_interrupt, IRQ0x48_interrupt,
129 IRQ0x49_interrupt, IRQ0x4a_interrupt, IRQ0x4b_interrupt, 177 IRQ0x49_interrupt, IRQ0x4a_interrupt, IRQ0x4b_interrupt,
130 IRQ0x4c_interrupt, IRQ0x4d_interrupt, IRQ0x4e_interrupt, 178 IRQ0x4c_interrupt, IRQ0x4d_interrupt, IRQ0x4e_interrupt,
131 IRQ0x4f_interrupt 179 IRQ0x4f_interrupt, IRQ0x50_interrupt,
180#if MACH_IRQS > 32
181 IRQ0x51_interrupt, IRQ0x52_interrupt, IRQ0x53_interrupt,
182 IRQ0x54_interrupt, IRQ0x55_interrupt, IRQ0x56_interrupt,
183 IRQ0x57_interrupt, IRQ0x58_interrupt, IRQ0x59_interrupt,
184 IRQ0x5a_interrupt, IRQ0x5b_interrupt, IRQ0x5c_interrupt,
185 IRQ0x5d_interrupt, IRQ0x5e_interrupt, IRQ0x5f_interrupt,
186 IRQ0x60_interrupt, IRQ0x61_interrupt, IRQ0x62_interrupt,
187 IRQ0x63_interrupt, IRQ0x64_interrupt, IRQ0x65_interrupt,
188 IRQ0x66_interrupt, IRQ0x67_interrupt, IRQ0x68_interrupt,
189 IRQ0x69_interrupt, IRQ0x6a_interrupt, IRQ0x6b_interrupt,
190 IRQ0x6c_interrupt, IRQ0x6d_interrupt, IRQ0x6e_interrupt,
191 IRQ0x6f_interrupt, IRQ0x70_interrupt,
192#endif
132}; 193};
133 194
134void 195void
@@ -137,13 +198,26 @@ block_irq(int irq, int cpu)
137 int intr_mask; 198 int intr_mask;
138 unsigned long flags; 199 unsigned long flags;
139 200
140 spin_lock_irqsave(&irq_lock, flags); 201 spin_lock_irqsave(&irq_lock, flags);
141 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); 202 if (irq - FIRST_IRQ < 32)
142 203 intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
143 /* Remember; 1 let through, 0 block. */ 204 rw_mask, 0);
144 intr_mask &= ~(1 << (irq - FIRST_IRQ)); 205 else
145 206 intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
146 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask); 207 rw_mask, 1);
208
209 /* Remember; 1 let thru, 0 block. */
210 if (irq - FIRST_IRQ < 32)
211 intr_mask &= ~(1 << (irq - FIRST_IRQ));
212 else
213 intr_mask &= ~(1 << (irq - FIRST_IRQ - 32));
214
215 if (irq - FIRST_IRQ < 32)
216 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
217 0, intr_mask);
218 else
219 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
220 1, intr_mask);
147 spin_unlock_irqrestore(&irq_lock, flags); 221 spin_unlock_irqrestore(&irq_lock, flags);
148} 222}
149 223
@@ -154,12 +228,26 @@ unblock_irq(int irq, int cpu)
154 unsigned long flags; 228 unsigned long flags;
155 229
156 spin_lock_irqsave(&irq_lock, flags); 230 spin_lock_irqsave(&irq_lock, flags);
157 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); 231 if (irq - FIRST_IRQ < 32)
158 232 intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
159 /* Remember; 1 let through, 0 block. */ 233 rw_mask, 0);
160 intr_mask |= (1 << (irq - FIRST_IRQ)); 234 else
235 intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
236 rw_mask, 1);
237
238 /* Remember; 1 let thru, 0 block. */
239 if (irq - FIRST_IRQ < 32)
240 intr_mask |= (1 << (irq - FIRST_IRQ));
241 else
242 intr_mask |= (1 << (irq - FIRST_IRQ - 32));
243
244 if (irq - FIRST_IRQ < 32)
245 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
246 0, intr_mask);
247 else
248 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
249 1, intr_mask);
161 250
162 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
163 spin_unlock_irqrestore(&irq_lock, flags); 251 spin_unlock_irqrestore(&irq_lock, flags);
164} 252}
165 253
@@ -298,8 +386,9 @@ crisv32_do_multiple(struct pt_regs* regs)
298{ 386{
299 int cpu; 387 int cpu;
300 int mask; 388 int mask;
301 int masked; 389 int masked[NBR_REGS];
302 int bit; 390 int bit;
391 int i;
303 392
304 cpu = smp_processor_id(); 393 cpu = smp_processor_id();
305 394
@@ -308,42 +397,59 @@ crisv32_do_multiple(struct pt_regs* regs)
308 */ 397 */
309 irq_enter(); 398 irq_enter();
310 399
311 /* Get which IRQs that happened. */ 400 for (i = 0; i < NBR_REGS; i++) {
312 masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect); 401 /* Get which IRQs that happend. */
402 masked[i] = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
403 r_masked_vect, i);
313 404
314 /* Calculate new IRQ mask with these IRQs disabled. */ 405 /* Calculate new IRQ mask with these IRQs disabled. */
315 mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); 406 mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i);
316 mask &= ~masked; 407 mask &= ~masked[i];
317 408
318 /* Timer IRQ is never masked */ 409 /* Timer IRQ is never masked */
319 if (masked & TIMER_MASK) 410#ifdef TIMER_VECT1
320 mask |= TIMER_MASK; 411 if ((i == 1) && (masked[0] & TIMER_MASK))
321 412 mask |= TIMER_MASK;
322 /* Block all the IRQs */ 413#else
323 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask); 414 if ((i == 0) && (masked[0] & TIMER_MASK))
415 mask |= TIMER_MASK;
416#endif
417 /* Block all the IRQs */
418 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i, mask);
324 419
325 /* Check for timer IRQ and handle it special. */ 420 /* Check for timer IRQ and handle it special. */
326 if (masked & TIMER_MASK) { 421#ifdef TIMER_VECT1
327 masked &= ~TIMER_MASK; 422 if ((i == 1) && (masked[i] & TIMER_MASK)) {
328 do_IRQ(TIMER_INTR_VECT, regs); 423 masked[i] &= ~TIMER_MASK;
424 do_IRQ(TIMER0_INTR_VECT, regs);
425 }
426#else
427 if ((i == 0) && (masked[i] & TIMER_MASK)) {
428 masked[i] &= ~TIMER_MASK;
429 do_IRQ(TIMER0_INTR_VECT, regs);
430 }
329 } 431 }
432#endif
330 433
331#ifdef IGNORE_MASK 434#ifdef IGNORE_MASK
332 /* Remove IRQs that can't be handled as multiple. */ 435 /* Remove IRQs that can't be handled as multiple. */
333 masked &= ~IGNORE_MASK; 436 masked[0] &= ~IGNORE_MASK;
334#endif 437#endif
335 438
336 /* Handle the rest of the IRQs. */ 439 /* Handle the rest of the IRQs. */
337 for (bit = 0; bit < 32; bit++) 440 for (i = 0; i < NBR_REGS; i++) {
338 { 441 for (bit = 0; bit < 32; bit++) {
339 if (masked & (1 << bit)) 442 if (masked[i] & (1 << bit))
340 do_IRQ(bit + FIRST_IRQ, regs); 443 do_IRQ(bit + FIRST_IRQ + i*32, regs);
444 }
341 } 445 }
342 446
343 /* Unblock all the IRQs. */ 447 /* Unblock all the IRQs. */
344 mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); 448 for (i = 0; i < NBR_REGS; i++) {
345 mask |= masked; 449 mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i);
346 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask); 450 mask |= masked[i];
451 REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i, mask);
452 }
347 453
348 /* This irq_exit() will trigger the soft IRQs. */ 454 /* This irq_exit() will trigger the soft IRQs. */
349 irq_exit(); 455 irq_exit();
@@ -361,20 +467,21 @@ init_IRQ(void)
361 reg_intr_vect_rw_mask vect_mask = {0}; 467 reg_intr_vect_rw_mask vect_mask = {0};
362 468
363 /* Clear all interrupts masks. */ 469 /* Clear all interrupts masks. */
364 REG_WR(intr_vect, regi_irq, rw_mask, vect_mask); 470 for (i = 0; i < NBR_REGS; i++)
471 REG_WR_VECT(intr_vect, regi_irq, rw_mask, i, vect_mask);
365 472
366 for (i = 0; i < 256; i++) 473 for (i = 0; i < 256; i++)
367 etrax_irv->v[i] = weird_irq; 474 etrax_irv->v[i] = weird_irq;
368 475
369 /* Point all IRQs to bad handlers. */ 476 /* Point all IRQ's to bad handlers. */
370 for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { 477 for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
371 irq_desc[j].chip = &crisv32_irq_type; 478 irq_desc[j].chip = &crisv32_irq_type;
372 set_exception_vector(i, interrupt[j]); 479 set_exception_vector(i, interrupt[j]);
373 } 480 }
374 481
375 /* Mark Timer and IPI IRQs as CPU local */ 482 /* Mark Timer and IPI IRQs as CPU local */
376 irq_allocations[TIMER_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; 483 irq_allocations[TIMER0_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
377 irq_desc[TIMER_INTR_VECT].status |= IRQ_PER_CPU; 484 irq_desc[TIMER0_INTR_VECT].status |= IRQ_PER_CPU;
378 irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; 485 irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
379 irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU; 486 irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU;
380 487
@@ -391,6 +498,11 @@ init_IRQ(void)
391 set_exception_vector(0x0a, d_mmu_access); 498 set_exception_vector(0x0a, d_mmu_access);
392 set_exception_vector(0x0b, d_mmu_write); 499 set_exception_vector(0x0b, d_mmu_write);
393 500
501#ifdef CONFIG_BUG
502 /* Break 14 handler, used to implement cheap BUG(). */
503 set_exception_vector(0x1e, breakh_BUG);
504#endif
505
394 /* The system-call trap is reached by "break 13". */ 506 /* The system-call trap is reached by "break 13". */
395 set_exception_vector(0x1d, system_call); 507 set_exception_vector(0x1d, system_call);
396 508
diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c
index 480e56348be2..4e2e2e271efb 100644
--- a/arch/cris/arch-v32/kernel/kgdb.c
+++ b/arch/cris/arch-v32/kernel/kgdb.c
@@ -381,7 +381,7 @@ static int read_register(char regno, unsigned int *valptr);
381/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */ 381/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */
382int getDebugChar(void); 382int getDebugChar(void);
383 383
384#ifdef CONFIG_ETRAXFS_SIM 384#ifdef CONFIG_ETRAX_VCS_SIM
385int getDebugChar(void) 385int getDebugChar(void)
386{ 386{
387 return socketread(); 387 return socketread();
@@ -391,7 +391,7 @@ int getDebugChar(void)
391/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */ 391/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */
392void putDebugChar(int val); 392void putDebugChar(int val);
393 393
394#ifdef CONFIG_ETRAXFS_SIM 394#ifdef CONFIG_ETRAX_VCS_SIM
395void putDebugChar(int val) 395void putDebugChar(int val)
396{ 396{
397 socketwrite((char *)&val, 1); 397 socketwrite((char *)&val, 1);
@@ -1599,7 +1599,7 @@ kgdb_init(void)
1599 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); 1599 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
1600 1600
1601 ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask); 1601 ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask);
1602 ser_intr_mask.data_avail = regk_ser_yes; 1602 ser_intr_mask.dav = regk_ser_yes;
1603 REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask); 1603 REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask);
1604#elif defined(CONFIG_ETRAX_KGDB_PORT1) 1604#elif defined(CONFIG_ETRAX_KGDB_PORT1)
1605 /* Note: no shortcut registered (not handled by multiple_interrupt). 1605 /* Note: no shortcut registered (not handled by multiple_interrupt).
@@ -1611,7 +1611,7 @@ kgdb_init(void)
1611 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); 1611 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
1612 1612
1613 ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask); 1613 ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask);
1614 ser_intr_mask.data_avail = regk_ser_yes; 1614 ser_intr_mask.dav = regk_ser_yes;
1615 REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask); 1615 REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask);
1616#elif defined(CONFIG_ETRAX_KGDB_PORT2) 1616#elif defined(CONFIG_ETRAX_KGDB_PORT2)
1617 /* Note: no shortcut registered (not handled by multiple_interrupt). 1617 /* Note: no shortcut registered (not handled by multiple_interrupt).
@@ -1623,7 +1623,7 @@ kgdb_init(void)
1623 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); 1623 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
1624 1624
1625 ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask); 1625 ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask);
1626 ser_intr_mask.data_avail = regk_ser_yes; 1626 ser_intr_mask.dav = regk_ser_yes;
1627 REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask); 1627 REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask);
1628#elif defined(CONFIG_ETRAX_KGDB_PORT3) 1628#elif defined(CONFIG_ETRAX_KGDB_PORT3)
1629 /* Note: no shortcut registered (not handled by multiple_interrupt). 1629 /* Note: no shortcut registered (not handled by multiple_interrupt).
@@ -1635,7 +1635,7 @@ kgdb_init(void)
1635 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); 1635 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
1636 1636
1637 ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask); 1637 ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask);
1638 ser_intr_mask.data_avail = regk_ser_yes; 1638 ser_intr_mask.dav = regk_ser_yes;
1639 REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask); 1639 REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask);
1640#endif 1640#endif
1641 1641
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index b72a15580dc7..ced5b725d9bd 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -12,17 +12,13 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <asm/arch/hwregs/reg_rdwr.h> 15#include <hwregs/reg_rdwr.h>
16#include <asm/arch/hwregs/reg_map.h> 16#include <hwregs/reg_map.h>
17#include <asm/arch/hwregs/timer_defs.h> 17#include <hwregs/timer_defs.h>
18#include <asm/arch/hwregs/intr_vect_defs.h> 18#include <hwregs/intr_vect_defs.h>
19 19
20extern void stop_watchdog(void); 20extern void stop_watchdog(void);
21 21
22#ifdef CONFIG_ETRAX_GPIO
23extern void etrax_gpio_wake_up_check(void); /* Defined in drivers/gpio.c. */
24#endif
25
26extern int cris_hlt_counter; 22extern int cris_hlt_counter;
27 23
28/* We use this if we don't have any better idle routine. */ 24/* We use this if we don't have any better idle routine. */
@@ -82,7 +78,7 @@ hard_reset_now(void)
82 wd_ctrl.cmd = regk_timer_start; 78 wd_ctrl.cmd = regk_timer_start;
83 79
84 arch_enable_nmi(); 80 arch_enable_nmi();
85 REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); 81 REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl);
86} 82}
87#endif 83#endif
88 84
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 2df60529a8af..e27f4670e88e 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000-2003, Axis Communications AB. 2 * Copyright (C) 2000-2007, Axis Communications AB.
3 */ 3 */
4 4
5#include <linux/kernel.h> 5#include <linux/kernel.h>
@@ -149,7 +149,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
149 ret = generic_ptrace_pokedata(child, addr, data); 149 ret = generic_ptrace_pokedata(child, addr, data);
150 break; 150 break;
151 151
152 /* Write the word at location address in the USER area. */ 152 /* Write the word at location address in the USER area. */
153 case PTRACE_POKEUSR: 153 case PTRACE_POKEUSR:
154 ret = -EIO; 154 ret = -EIO;
155 if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) 155 if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
@@ -201,7 +201,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
201 201
202 break; 202 break;
203 203
204 /* Make the child exit by sending it a sigkill. */ 204 /* Make the child exit by sending it a sigkill. */
205 case PTRACE_KILL: 205 case PTRACE_KILL:
206 ret = 0; 206 ret = 0;
207 207
@@ -245,9 +245,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
245 break; 245 break;
246 246
247 } 247 }
248
248 /* Get all GP registers from the child. */ 249 /* Get all GP registers from the child. */
249 case PTRACE_GETREGS: { 250 case PTRACE_GETREGS: {
250 int i; 251 int i;
251 unsigned long tmp; 252 unsigned long tmp;
252 253
253 for (i = 0; i <= PT_MAX; i++) { 254 for (i = 0; i <= PT_MAX; i++) {
@@ -294,6 +295,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
294 break; 295 break;
295 } 296 }
296 297
298out_tsk:
297 return ret; 299 return ret;
298} 300}
299 301
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 024cc6901974..58c1866804e3 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -50,7 +50,7 @@ struct rt_signal_frame {
50 unsigned char retcode[8]; /* Trampoline code. */ 50 unsigned char retcode[8]; /* Trampoline code. */
51}; 51};
52 52
53int do_signal(int restart, sigset_t *oldset, struct pt_regs *regs); 53void do_signal(int restart, struct pt_regs *regs);
54void keep_debug_flags(unsigned long oldccs, unsigned long oldspc, 54void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
55 struct pt_regs *regs); 55 struct pt_regs *regs);
56/* 56/*
@@ -61,74 +61,16 @@ int
61sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 61sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
62 long srp, struct pt_regs *regs) 62 long srp, struct pt_regs *regs)
63{ 63{
64 sigset_t saveset;
65
66 mask &= _BLOCKABLE; 64 mask &= _BLOCKABLE;
67
68 spin_lock_irq(&current->sighand->siglock); 65 spin_lock_irq(&current->sighand->siglock);
69 66 current->saved_sigmask = current->blocked;
70 saveset = current->blocked;
71
72 siginitset(&current->blocked, mask); 67 siginitset(&current->blocked, mask);
73
74 recalc_sigpending();
75 spin_unlock_irq(&current->sighand->siglock);
76
77 regs->r10 = -EINTR;
78
79 while (1) {
80 current->state = TASK_INTERRUPTIBLE;
81 schedule();
82
83 if (do_signal(0, &saveset, regs)) {
84 /*
85 * This point is reached twice: once to call
86 * the signal handler, then again to return
87 * from the sigsuspend system call. When
88 * calling the signal handler, R10 hold the
89 * signal number as set by do_signal(). The
90 * sigsuspend call will always return with
91 * the restored value above; -EINTR.
92 */
93 return regs->r10;
94 }
95 }
96}
97
98/* Define some dummy arguments to be able to reach the regs argument. */
99int
100sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
101 long mof, long srp, struct pt_regs *regs)
102{
103 sigset_t saveset;
104 sigset_t newset;
105
106 if (sigsetsize != sizeof(sigset_t))
107 return -EINVAL;
108
109 if (copy_from_user(&newset, unewset, sizeof(newset)))
110 return -EFAULT;
111
112 sigdelsetmask(&newset, ~_BLOCKABLE);
113 spin_lock_irq(&current->sighand->siglock);
114
115 saveset = current->blocked;
116 current->blocked = newset;
117
118 recalc_sigpending(); 68 recalc_sigpending();
119 spin_unlock_irq(&current->sighand->siglock); 69 spin_unlock_irq(&current->sighand->siglock);
120 70 current->state = TASK_INTERRUPTIBLE;
121 regs->r10 = -EINTR; 71 schedule();
122 72 set_thread_flag(TIF_RESTORE_SIGMASK);
123 while (1) { 73 return -ERESTARTNOHAND;
124 current->state = TASK_INTERRUPTIBLE;
125 schedule();
126
127 if (do_signal(0, &saveset, regs)) {
128 /* See comment in function above. */
129 return regs->r10;
130 }
131 }
132} 74}
133 75
134int 76int
@@ -290,7 +232,7 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
290 goto badframe; 232 goto badframe;
291 233
292 if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) 234 if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT)
293 goto badframe; 235 goto badframe;
294 236
295 keep_debug_flags(oldccs, oldspc, regs); 237 keep_debug_flags(oldccs, oldspc, regs);
296 238
@@ -347,11 +289,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
347/* Grab and setup a signal frame. 289/* Grab and setup a signal frame.
348 * 290 *
349 * Basically a lot of state-info is stacked, and arranged for the 291 * Basically a lot of state-info is stacked, and arranged for the
350 * user-mode program to return to the kernel using either a trampoline 292 * user-mode program to return to the kernel using either a trampiline
351 * which performs the syscall sigreturn(), or a provided user-mode 293 * which performs the syscall sigreturn(), or a provided user-mode
352 * trampoline. 294 * trampoline.
353 */ 295 */
354static void 296static int
355setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 297setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
356 struct pt_regs * regs) 298 struct pt_regs * regs)
357{ 299{
@@ -417,16 +359,17 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
417 /* Actually move the USP to reflect the stacked frame. */ 359 /* Actually move the USP to reflect the stacked frame. */
418 wrusp((unsigned long)frame); 360 wrusp((unsigned long)frame);
419 361
420 return; 362 return 0;
421 363
422give_sigsegv: 364give_sigsegv:
423 if (sig == SIGSEGV) 365 if (sig == SIGSEGV)
424 ka->sa.sa_handler = SIG_DFL; 366 ka->sa.sa_handler = SIG_DFL;
425 367
426 force_sig(SIGSEGV, current); 368 force_sig(SIGSEGV, current);
369 return -EFAULT;
427} 370}
428 371
429static void 372static int
430setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 373setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
431 sigset_t *set, struct pt_regs * regs) 374 sigset_t *set, struct pt_regs * regs)
432{ 375{
@@ -503,21 +446,24 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
503 /* Actually move the usp to reflect the stacked frame. */ 446 /* Actually move the usp to reflect the stacked frame. */
504 wrusp((unsigned long)frame); 447 wrusp((unsigned long)frame);
505 448
506 return; 449 return 0;
507 450
508give_sigsegv: 451give_sigsegv:
509 if (sig == SIGSEGV) 452 if (sig == SIGSEGV)
510 ka->sa.sa_handler = SIG_DFL; 453 ka->sa.sa_handler = SIG_DFL;
511 454
512 force_sig(SIGSEGV, current); 455 force_sig(SIGSEGV, current);
456 return -EFAULT;
513} 457}
514 458
515/* Invoke a singal handler to, well, handle the signal. */ 459/* Invoke a singal handler to, well, handle the signal. */
516static inline void 460static inline int
517handle_signal(int canrestart, unsigned long sig, 461handle_signal(int canrestart, unsigned long sig,
518 siginfo_t *info, struct k_sigaction *ka, 462 siginfo_t *info, struct k_sigaction *ka,
519 sigset_t *oldset, struct pt_regs * regs) 463 sigset_t *oldset, struct pt_regs * regs)
520{ 464{
465 int ret;
466
521 /* Check if this got called from a system call. */ 467 /* Check if this got called from a system call. */
522 if (canrestart) { 468 if (canrestart) {
523 /* If so, check system call restarting. */ 469 /* If so, check system call restarting. */
@@ -561,19 +507,24 @@ handle_signal(int canrestart, unsigned long sig,
561 507
562 /* Set up the stack frame. */ 508 /* Set up the stack frame. */
563 if (ka->sa.sa_flags & SA_SIGINFO) 509 if (ka->sa.sa_flags & SA_SIGINFO)
564 setup_rt_frame(sig, ka, info, oldset, regs); 510 ret = setup_rt_frame(sig, ka, info, oldset, regs);
565 else 511 else
566 setup_frame(sig, ka, oldset, regs); 512 ret = setup_frame(sig, ka, oldset, regs);
567 513
568 if (ka->sa.sa_flags & SA_ONESHOT) 514 if (ka->sa.sa_flags & SA_ONESHOT)
569 ka->sa.sa_handler = SIG_DFL; 515 ka->sa.sa_handler = SIG_DFL;
570 516
571 spin_lock_irq(&current->sighand->siglock); 517 if (ret == 0) {
572 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 518 spin_lock_irq(&current->sighand->siglock);
573 if (!(ka->sa.sa_flags & SA_NODEFER)) 519 sigorsets(&current->blocked, &current->blocked,
574 sigaddset(&current->blocked,sig); 520 &ka->sa.sa_mask);
575 recalc_sigpending(); 521 if (!(ka->sa.sa_flags & SA_NODEFER))
576 spin_unlock_irq(&current->sighand->siglock); 522 sigaddset(&current->blocked, sig);
523 recalc_sigpending();
524 spin_unlock_irq(&current->sighand->siglock);
525 }
526
527 return ret;
577} 528}
578 529
579/* 530/*
@@ -587,12 +538,13 @@ handle_signal(int canrestart, unsigned long sig,
587 * we can use user_mode(regs) to see if we came directly from kernel or user 538 * we can use user_mode(regs) to see if we came directly from kernel or user
588 * mode below. 539 * mode below.
589 */ 540 */
590int 541void
591do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) 542do_signal(int canrestart, struct pt_regs *regs)
592{ 543{
593 int signr; 544 int signr;
594 siginfo_t info; 545 siginfo_t info;
595 struct k_sigaction ka; 546 struct k_sigaction ka;
547 sigset_t *oldset;
596 548
597 /* 549 /*
598 * The common case should go fast, which is why this point is 550 * The common case should go fast, which is why this point is
@@ -600,17 +552,28 @@ do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
600 * without doing anything. 552 * without doing anything.
601 */ 553 */
602 if (!user_mode(regs)) 554 if (!user_mode(regs))
603 return 1; 555 return;
604 556
605 if (!oldset) 557 if (test_thread_flag(TIF_RESTORE_SIGMASK))
558 oldset = &current->saved_sigmask;
559 else
606 oldset = &current->blocked; 560 oldset = &current->blocked;
607 561
608 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 562 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
609 563
610 if (signr > 0) { 564 if (signr > 0) {
611 /* Deliver the signal. */ 565 /* Whee! Actually deliver the signal. */
612 handle_signal(canrestart, signr, &info, &ka, oldset, regs); 566 if (handle_signal(canrestart, signr, &info, &ka,
613 return 1; 567 oldset, regs)) {
568 /* a signal was successfully delivered; the saved
569 * sigmask will have been stored in the signal frame,
570 * and will be restored by sigreturn, so we can simply
571 * clear the TIF_RESTORE_SIGMASK flag */
572 if (test_thread_flag(TIF_RESTORE_SIGMASK))
573 clear_thread_flag(TIF_RESTORE_SIGMASK);
574 }
575
576 return;
614 } 577 }
615 578
616 /* Got here from a system call? */ 579 /* Got here from a system call? */
@@ -628,7 +591,12 @@ do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
628 } 591 }
629 } 592 }
630 593
631 return 0; 594 /* if there's no signal to deliver, we just put the saved sigmask
595 * back */
596 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
597 clear_thread_flag(TIF_RESTORE_SIGMASK);
598 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
599 }
632} 600}
633 601
634asmlinkage void 602asmlinkage void
@@ -641,7 +609,7 @@ ugdb_trap_user(struct thread_info *ti, int sig)
641 user_regs(ti)->spc = 0; 609 user_regs(ti)->spc = 0;
642 } 610 }
643 /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA 611 /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
644 not within any configured h/w breakpoint range). Synchronize with 612 not withing any configured h/w breakpoint range). Synchronize with
645 what already exists for kernel debugging. */ 613 what already exists for kernel debugging. */
646 if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) { 614 if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
647 /* Break 8: subtract 2 from ERP unless in a delay slot. */ 615 /* Break 8: subtract 2 from ERP unless in a delay slot. */
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 171c96e0a5d3..a9c3334e46c9 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -1,11 +1,12 @@
1#include <linux/types.h>
1#include <asm/delay.h> 2#include <asm/delay.h>
2#include <asm/arch/irq.h> 3#include <irq.h>
3#include <asm/arch/hwregs/intr_vect.h> 4#include <hwregs/intr_vect.h>
4#include <asm/arch/hwregs/intr_vect_defs.h> 5#include <hwregs/intr_vect_defs.h>
5#include <asm/tlbflush.h> 6#include <asm/tlbflush.h>
6#include <asm/mmu_context.h> 7#include <asm/mmu_context.h>
7#include <asm/arch/hwregs/mmu_defs_asm.h> 8#include <hwregs/asm/mmu_defs_asm.h>
8#include <asm/arch/hwregs/supp_reg.h> 9#include <hwregs/supp_reg.h>
9#include <asm/atomic.h> 10#include <asm/atomic.h>
10 11
11#include <linux/err.h> 12#include <linux/err.h>
@@ -20,6 +21,7 @@
20#define IPI_SCHEDULE 1 21#define IPI_SCHEDULE 1
21#define IPI_CALL 2 22#define IPI_CALL 2
22#define IPI_FLUSH_TLB 4 23#define IPI_FLUSH_TLB 4
24#define IPI_BOOT 8
23 25
24#define FLUSH_ALL (void*)0xffffffff 26#define FLUSH_ALL (void*)0xffffffff
25 27
@@ -30,6 +32,8 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
30cpumask_t cpu_online_map = CPU_MASK_NONE; 32cpumask_t cpu_online_map = CPU_MASK_NONE;
31EXPORT_SYMBOL(cpu_online_map); 33EXPORT_SYMBOL(cpu_online_map);
32cpumask_t phys_cpu_present_map = CPU_MASK_NONE; 34cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
35cpumask_t cpu_possible_map;
36EXPORT_SYMBOL(cpu_possible_map);
33EXPORT_SYMBOL(phys_cpu_present_map); 37EXPORT_SYMBOL(phys_cpu_present_map);
34 38
35/* Variables used during SMP boot */ 39/* Variables used during SMP boot */
@@ -55,13 +59,12 @@ static unsigned long flush_addr;
55extern int setup_irq(int, struct irqaction *); 59extern int setup_irq(int, struct irqaction *);
56 60
57/* Mode registers */ 61/* Mode registers */
58static unsigned long irq_regs[NR_CPUS] = 62static unsigned long irq_regs[NR_CPUS] = {
59{
60 regi_irq, 63 regi_irq,
61 regi_irq2 64 regi_irq2
62}; 65};
63 66
64static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); 67static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id);
65static int send_ipi(int vector, int wait, cpumask_t cpu_mask); 68static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
66static struct irqaction irq_ipi = { 69static struct irqaction irq_ipi = {
67 .handler = crisv32_ipi_interrupt, 70 .handler = crisv32_ipi_interrupt,
@@ -101,6 +104,7 @@ void __devinit smp_prepare_boot_cpu(void)
101 104
102 cpu_set(0, cpu_online_map); 105 cpu_set(0, cpu_online_map);
103 cpu_set(0, phys_cpu_present_map); 106 cpu_set(0, phys_cpu_present_map);
107 cpu_set(0, cpu_possible_map);
104} 108}
105 109
106void __init smp_cpus_done(unsigned int max_cpus) 110void __init smp_cpus_done(unsigned int max_cpus)
@@ -113,6 +117,7 @@ smp_boot_one_cpu(int cpuid)
113{ 117{
114 unsigned timeout; 118 unsigned timeout;
115 struct task_struct *idle; 119 struct task_struct *idle;
120 cpumask_t cpu_mask = CPU_MASK_NONE;
116 121
117 idle = fork_idle(cpuid); 122 idle = fork_idle(cpuid);
118 if (IS_ERR(idle)) 123 if (IS_ERR(idle))
@@ -124,6 +129,12 @@ smp_boot_one_cpu(int cpuid)
124 smp_init_current_idle_thread = task_thread_info(idle); 129 smp_init_current_idle_thread = task_thread_info(idle);
125 cpu_now_booting = cpuid; 130 cpu_now_booting = cpuid;
126 131
132 /* Kick it */
133 cpu_set(cpuid, cpu_online_map);
134 cpu_set(cpuid, cpu_mask);
135 send_ipi(IPI_BOOT, 0, cpu_mask);
136 cpu_clear(cpuid, cpu_online_map);
137
127 /* Wait for CPU to come online */ 138 /* Wait for CPU to come online */
128 for (timeout = 0; timeout < 10000; timeout++) { 139 for (timeout = 0; timeout < 10000; timeout++) {
129 if(cpu_online(cpuid)) { 140 if(cpu_online(cpuid)) {
@@ -165,7 +176,7 @@ void __init smp_callin(void)
165 /* Enable IRQ and idle */ 176 /* Enable IRQ and idle */
166 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); 177 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
167 unmask_irq(IPI_INTR_VECT); 178 unmask_irq(IPI_INTR_VECT);
168 unmask_irq(TIMER_INTR_VECT); 179 unmask_irq(TIMER0_INTR_VECT);
169 preempt_disable(); 180 preempt_disable();
170 local_irq_enable(); 181 local_irq_enable();
171 182
@@ -328,7 +339,7 @@ int smp_call_function(void (*func)(void *info), void *info,
328 return ret; 339 return ret;
329} 340}
330 341
331irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) 342irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id)
332{ 343{
333 void (*func) (void *info) = call_data->func; 344 void (*func) (void *info) = call_data->func;
334 void *info = call_data->info; 345 void *info = call_data->info;
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 2f7e8e200f2c..3a13dd6e0a9a 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -1,8 +1,7 @@
1/* $Id: time.c,v 1.19 2005/04/29 05:40:09 starvik Exp $ 1/*
2 *
3 * linux/arch/cris/arch-v32/kernel/time.c 2 * linux/arch/cris/arch-v32/kernel/time.c
4 * 3 *
5 * Copyright (C) 2003 Axis Communications AB 4 * Copyright (C) 2003-2007 Axis Communications AB
6 * 5 *
7 */ 6 */
8 7
@@ -14,28 +13,34 @@
14#include <linux/sched.h> 13#include <linux/sched.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/threads.h> 15#include <linux/threads.h>
16#include <linux/cpufreq.h>
17#include <asm/types.h> 17#include <asm/types.h>
18#include <asm/signal.h> 18#include <asm/signal.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/delay.h> 20#include <asm/delay.h>
21#include <asm/rtc.h> 21#include <asm/rtc.h>
22#include <asm/irq.h> 22#include <asm/irq.h>
23 23#include <asm/irq_regs.h>
24#include <asm/arch/hwregs/reg_map.h> 24
25#include <asm/arch/hwregs/reg_rdwr.h> 25#include <hwregs/reg_map.h>
26#include <asm/arch/hwregs/timer_defs.h> 26#include <hwregs/reg_rdwr.h>
27#include <asm/arch/hwregs/intr_vect_defs.h> 27#include <hwregs/timer_defs.h>
28#include <hwregs/intr_vect_defs.h>
29#ifdef CONFIG_CRIS_MACH_ARTPEC3
30#include <hwregs/clkgen_defs.h>
31#endif
28 32
29/* Watchdog defines */ 33/* Watchdog defines */
30#define ETRAX_WD_KEY_MASK 0x7F /* key is 7 bit */ 34#define ETRAX_WD_KEY_MASK 0x7F /* key is 7 bit */
31#define ETRAX_WD_HZ 763 /* watchdog counts at 763 Hz */ 35#define ETRAX_WD_HZ 763 /* watchdog counts at 763 Hz */
32#define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) /* Number of 763 counts before watchdog bites */ 36/* Number of 763 counts before watchdog bites */
37#define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1)
33 38
34unsigned long timer_regs[NR_CPUS] = 39unsigned long timer_regs[NR_CPUS] =
35{ 40{
36 regi_timer, 41 regi_timer0,
37#ifdef CONFIG_SMP 42#ifdef CONFIG_SMP
38 regi_timer2 43 regi_timer2
39#endif 44#endif
40}; 45};
41 46
@@ -44,12 +49,22 @@ extern int set_rtc_mmss(unsigned long nowtime);
44extern int setup_irq(int, struct irqaction *); 49extern int setup_irq(int, struct irqaction *);
45extern int have_rtc; 50extern int have_rtc;
46 51
52#ifdef CONFIG_CPU_FREQ
53static int
54cris_time_freq_notifier(struct notifier_block *nb, unsigned long val,
55 void *data);
56
57static struct notifier_block cris_time_freq_notifier_block = {
58 .notifier_call = cris_time_freq_notifier,
59};
60#endif
61
47unsigned long get_ns_in_jiffie(void) 62unsigned long get_ns_in_jiffie(void)
48{ 63{
49 reg_timer_r_tmr0_data data; 64 reg_timer_r_tmr0_data data;
50 unsigned long ns; 65 unsigned long ns;
51 66
52 data = REG_RD(timer, regi_timer, r_tmr0_data); 67 data = REG_RD(timer, regi_timer0, r_tmr0_data);
53 ns = (TIMER0_DIV - data) * 10; 68 ns = (TIMER0_DIV - data) * 10;
54 return ns; 69 return ns;
55} 70}
@@ -59,31 +74,27 @@ unsigned long do_slow_gettimeoffset(void)
59 unsigned long count; 74 unsigned long count;
60 unsigned long usec_count = 0; 75 unsigned long usec_count = 0;
61 76
62 static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */ 77 /* For the first call after boot */
78 static unsigned long count_p = TIMER0_DIV;
63 static unsigned long jiffies_p = 0; 79 static unsigned long jiffies_p = 0;
64 80
65 /* 81 /* Cache volatile jiffies temporarily; we have IRQs turned off. */
66 * cache volatile jiffies temporarily; we have IRQs turned off.
67 */
68 unsigned long jiffies_t; 82 unsigned long jiffies_t;
69 83
70 /* The timer interrupt comes from Etrax timer 0. In order to get 84 /* The timer interrupt comes from Etrax timer 0. In order to get
71 * better precision, we check the current value. It might have 85 * better precision, we check the current value. It might have
72 * underflowed already though. 86 * underflowed already though. */
73 */ 87 count = REG_RD(timer, regi_timer0, r_tmr0_data);
88 jiffies_t = jiffies;
74 89
75 count = REG_RD(timer, regi_timer, r_tmr0_data); 90 /* Avoiding timer inconsistencies (they are rare, but they happen)
76 jiffies_t = jiffies; 91 * There is one problem that must be avoided here:
77 92 * 1. the timer counter underflows
78 /*
79 * avoiding timer inconsistencies (they are rare, but they happen)...
80 * there are one problem that must be avoided here:
81 * 1. the timer counter underflows
82 */ 93 */
83 if( jiffies_t == jiffies_p ) { 94 if( jiffies_t == jiffies_p ) {
84 if( count > count_p ) { 95 if( count > count_p ) {
85 /* Timer wrapped, use new count and prescale 96 /* Timer wrapped, use new count and prescale.
86 * increase the time corresponding to one jiffie 97 * Increase the time corresponding to one jiffy.
87 */ 98 */
88 usec_count = 1000000/HZ; 99 usec_count = 1000000/HZ;
89 } 100 }
@@ -106,17 +117,15 @@ unsigned long do_slow_gettimeoffset(void)
106 */ 117 */
107/* This gives us 1.3 ms to do something useful when the NMI comes */ 118/* This gives us 1.3 ms to do something useful when the NMI comes */
108 119
109/* right now, starting the watchdog is the same as resetting it */ 120/* Right now, starting the watchdog is the same as resetting it */
110#define start_watchdog reset_watchdog 121#define start_watchdog reset_watchdog
111 122
112#if defined(CONFIG_ETRAX_WATCHDOG) 123#if defined(CONFIG_ETRAX_WATCHDOG)
113static short int watchdog_key = 42; /* arbitrary 7 bit number */ 124static short int watchdog_key = 42; /* arbitrary 7 bit number */
114#endif 125#endif
115 126
116/* number of pages to consider "out of memory". it is normal that the memory 127/* Number of pages to consider "out of memory". It is normal that the memory
117 * is used though, so put this really low. 128 * is used though, so set this really low. */
118 */
119
120#define WATCHDOG_MIN_FREE_PAGES 8 129#define WATCHDOG_MIN_FREE_PAGES 8
121 130
122void 131void
@@ -125,14 +134,15 @@ reset_watchdog(void)
125#if defined(CONFIG_ETRAX_WATCHDOG) 134#if defined(CONFIG_ETRAX_WATCHDOG)
126 reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; 135 reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
127 136
128 /* only keep watchdog happy as long as we have memory left! */ 137 /* Only keep watchdog happy as long as we have memory left! */
129 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { 138 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
130 /* reset the watchdog with the inverse of the old key */ 139 /* Reset the watchdog with the inverse of the old key */
131 watchdog_key ^= ETRAX_WD_KEY_MASK; /* invert key, which is 7 bits */ 140 /* Invert key, which is 7 bits */
141 watchdog_key ^= ETRAX_WD_KEY_MASK;
132 wd_ctrl.cnt = ETRAX_WD_CNT; 142 wd_ctrl.cnt = ETRAX_WD_CNT;
133 wd_ctrl.cmd = regk_timer_start; 143 wd_ctrl.cmd = regk_timer_start;
134 wd_ctrl.key = watchdog_key; 144 wd_ctrl.key = watchdog_key;
135 REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); 145 REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl);
136 } 146 }
137#endif 147#endif
138} 148}
@@ -148,7 +158,7 @@ stop_watchdog(void)
148 wd_ctrl.cnt = ETRAX_WD_CNT; 158 wd_ctrl.cnt = ETRAX_WD_CNT;
149 wd_ctrl.cmd = regk_timer_stop; 159 wd_ctrl.cmd = regk_timer_stop;
150 wd_ctrl.key = watchdog_key; 160 wd_ctrl.key = watchdog_key;
151 REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); 161 REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl);
152#endif 162#endif
153} 163}
154 164
@@ -160,17 +170,28 @@ handle_watchdog_bite(struct pt_regs* regs)
160#if defined(CONFIG_ETRAX_WATCHDOG) 170#if defined(CONFIG_ETRAX_WATCHDOG)
161 extern int cause_of_death; 171 extern int cause_of_death;
162 172
163 raw_printk("Watchdog bite\n"); 173 oops_in_progress = 1;
174 printk(KERN_WARNING "Watchdog bite\n");
164 175
165 /* Check if forced restart or unexpected watchdog */ 176 /* Check if forced restart or unexpected watchdog */
166 if (cause_of_death == 0xbedead) { 177 if (cause_of_death == 0xbedead) {
178#ifdef CONFIG_CRIS_MACH_ARTPEC3
179 /* There is a bug in Artpec-3 (voodoo TR 78) that requires
180 * us to go to lower frequency for the reset to be reliable
181 */
182 reg_clkgen_rw_clk_ctrl ctrl =
183 REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
184 ctrl.pll = 0;
185 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, ctrl);
186#endif
167 while(1); 187 while(1);
168 } 188 }
169 189
170 /* Unexpected watchdog, stop the watchdog and dump registers*/ 190 /* Unexpected watchdog, stop the watchdog and dump registers. */
171 stop_watchdog(); 191 stop_watchdog();
172 raw_printk("Oops: bitten by watchdog\n"); 192 printk(KERN_WARNING "Oops: bitten by watchdog\n");
173 show_registers(regs); 193 show_registers(regs);
194 oops_in_progress = 0;
174#ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 195#ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
175 reset_watchdog(); 196 reset_watchdog();
176#endif 197#endif
@@ -178,21 +199,19 @@ handle_watchdog_bite(struct pt_regs* regs)
178#endif 199#endif
179} 200}
180 201
181/* last time the cmos clock got updated */ 202/* Last time the cmos clock got updated. */
182static long last_rtc_update = 0; 203static long last_rtc_update = 0;
183 204
184/* 205/*
185 * timer_interrupt() needs to keep up the real-time clock, 206 * timer_interrupt() needs to keep up the real-time clock,
186 * as well as call the "do_timer()" routine every clocktick 207 * as well as call the "do_timer()" routine every clocktick.
187 */ 208 */
188
189//static unsigned short myjiff; /* used by our debug routine print_timestamp */
190
191extern void cris_do_profile(struct pt_regs *regs); 209extern void cris_do_profile(struct pt_regs *regs);
192 210
193static inline irqreturn_t 211static inline irqreturn_t
194timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 212timer_interrupt(int irq, void *dev_id)
195{ 213{
214 struct pt_regs *regs = get_irq_regs();
196 int cpu = smp_processor_id(); 215 int cpu = smp_processor_id();
197 reg_timer_r_masked_intr masked_intr; 216 reg_timer_r_masked_intr masked_intr;
198 reg_timer_rw_ack_intr ack_intr = { 0 }; 217 reg_timer_rw_ack_intr ack_intr = { 0 };
@@ -202,11 +221,11 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
202 if (!masked_intr.tmr0) 221 if (!masked_intr.tmr0)
203 return IRQ_NONE; 222 return IRQ_NONE;
204 223
205 /* acknowledge the timer irq */ 224 /* Acknowledge the timer irq. */
206 ack_intr.tmr0 = 1; 225 ack_intr.tmr0 = 1;
207 REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr); 226 REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr);
208 227
209 /* reset watchdog otherwise it resets us! */ 228 /* Reset watchdog otherwise it resets us! */
210 reset_watchdog(); 229 reset_watchdog();
211 230
212 /* Update statistics. */ 231 /* Update statistics. */
@@ -218,7 +237,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
218 if (cpu != 0) 237 if (cpu != 0)
219 return IRQ_HANDLED; 238 return IRQ_HANDLED;
220 239
221 /* call the real timer interrupt handler */ 240 /* Call the real timer interrupt handler */
222 do_timer(1); 241 do_timer(1);
223 242
224 /* 243 /*
@@ -236,17 +255,17 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
236 if (set_rtc_mmss(xtime.tv_sec) == 0) 255 if (set_rtc_mmss(xtime.tv_sec) == 0)
237 last_rtc_update = xtime.tv_sec; 256 last_rtc_update = xtime.tv_sec;
238 else 257 else
239 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ 258 /* Do it again in 60 s */
259 last_rtc_update = xtime.tv_sec - 600;
240 } 260 }
241 return IRQ_HANDLED; 261 return IRQ_HANDLED;
242} 262}
243 263
244/* timer is IRQF_SHARED so drivers can add stuff to the timer irq chain 264/* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain.
245 * it needs to be IRQF_DISABLED to make the jiffies update work properly 265 * It needs to be IRQF_DISABLED to make the jiffies update work properly.
246 */ 266 */
247 267static struct irqaction irq_timer = {
248static struct irqaction irq_timer = { 268 .handler = timer_interrupt,
249 .mask = timer_interrupt,
250 .flags = IRQF_SHARED | IRQF_DISABLED, 269 .flags = IRQF_SHARED | IRQF_DISABLED,
251 .mask = CPU_MASK_NONE, 270 .mask = CPU_MASK_NONE,
252 .name = "timer" 271 .name = "timer"
@@ -256,27 +275,27 @@ void __init
256cris_timer_init(void) 275cris_timer_init(void)
257{ 276{
258 int cpu = smp_processor_id(); 277 int cpu = smp_processor_id();
259 reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 }; 278 reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 };
260 reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV; 279 reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV;
261 reg_timer_rw_intr_mask timer_intr_mask; 280 reg_timer_rw_intr_mask timer_intr_mask;
262 281
263 /* Setup the etrax timers 282 /* Setup the etrax timers.
264 * Base frequency is 100MHz, divider 1000000 -> 100 HZ 283 * Base frequency is 100MHz, divider 1000000 -> 100 HZ
265 * We use timer0, so timer1 is free. 284 * We use timer0, so timer1 is free.
266 * The trig timer is used by the fasttimer API if enabled. 285 * The trig timer is used by the fasttimer API if enabled.
267 */ 286 */
268 287
269 tmr0_ctrl.op = regk_timer_ld; 288 tmr0_ctrl.op = regk_timer_ld;
270 tmr0_ctrl.freq = regk_timer_f100; 289 tmr0_ctrl.freq = regk_timer_f100;
271 REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div); 290 REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div);
272 REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */ 291 REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */
273 tmr0_ctrl.op = regk_timer_run; 292 tmr0_ctrl.op = regk_timer_run;
274 REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */ 293 REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */
275 294
276 /* enable the timer irq */ 295 /* Enable the timer irq. */
277 timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask); 296 timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask);
278 timer_intr_mask.tmr0 = 1; 297 timer_intr_mask.tmr0 = 1;
279 REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask); 298 REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask);
280} 299}
281 300
282void __init 301void __init
@@ -284,7 +303,7 @@ time_init(void)
284{ 303{
285 reg_intr_vect_rw_mask intr_mask; 304 reg_intr_vect_rw_mask intr_mask;
286 305
287 /* probe for the RTC and read it if it exists 306 /* Probe for the RTC and read it if it exists.
288 * Before the RTC can be probed the loops_per_usec variable needs 307 * Before the RTC can be probed the loops_per_usec variable needs
289 * to be initialized to make usleep work. A better value for 308 * to be initialized to make usleep work. A better value for
290 * loops_per_usec is calculated by the kernel later once the 309 * loops_per_usec is calculated by the kernel later once the
@@ -293,52 +312,74 @@ time_init(void)
293 loops_per_usec = 50; 312 loops_per_usec = 50;
294 313
295 if(RTC_INIT() < 0) { 314 if(RTC_INIT() < 0) {
296 /* no RTC, start at 1980 */ 315 /* No RTC, start at 1980 */
297 xtime.tv_sec = 0; 316 xtime.tv_sec = 0;
298 xtime.tv_nsec = 0; 317 xtime.tv_nsec = 0;
299 have_rtc = 0; 318 have_rtc = 0;
300 } else { 319 } else {
301 /* get the current time */ 320 /* Get the current time */
302 have_rtc = 1; 321 have_rtc = 1;
303 update_xtime_from_cmos(); 322 update_xtime_from_cmos();
304 } 323 }
305 324
306 /* 325 /*
307 * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the 326 * Initialize wall_to_monotonic such that adding it to
308 * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). 327 * xtime will yield zero, the tv_nsec field must be normalized
328 * (i.e., 0 <= nsec < NSEC_PER_SEC).
309 */ 329 */
310 set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); 330 set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
311 331
312 /* Start CPU local timer */ 332 /* Start CPU local timer. */
313 cris_timer_init(); 333 cris_timer_init();
314 334
315 /* enable the timer irq in global config */ 335 /* Enable the timer irq in global config. */
316 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); 336 intr_mask = REG_RD_VECT(intr_vect, regi_irq, rw_mask, 1);
317 intr_mask.timer = 1; 337 intr_mask.timer0 = 1;
318 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); 338 REG_WR_VECT(intr_vect, regi_irq, rw_mask, 1, intr_mask);
319
320 /* now actually register the timer irq handler that calls timer_interrupt() */
321 339
322 setup_irq(TIMER_INTR_VECT, &irq_timer); 340 /* Now actually register the timer irq handler that calls
341 * timer_interrupt(). */
342 setup_irq(TIMER0_INTR_VECT, &irq_timer);
323 343
324 /* enable watchdog if we should use one */ 344 /* Enable watchdog if we should use one. */
325 345
326#if defined(CONFIG_ETRAX_WATCHDOG) 346#if defined(CONFIG_ETRAX_WATCHDOG)
327 printk("Enabling watchdog...\n"); 347 printk(KERN_INFO "Enabling watchdog...\n");
328 start_watchdog(); 348 start_watchdog();
329 349
330 /* If we use the hardware watchdog, we want to trap it as an NMI 350 /* If we use the hardware watchdog, we want to trap it as an NMI
331 and dump registers before it resets us. For this to happen, we 351 * and dump registers before it resets us. For this to happen, we
332 must set the "m" NMI enable flag (which once set, is unset only 352 * must set the "m" NMI enable flag (which once set, is unset only
333 when an NMI is taken). 353 * when an NMI is taken). */
334 354 {
335 The same goes for the external NMI, but that doesn't have any 355 unsigned long flags;
336 driver or infrastructure support yet. */ 356 local_save_flags(flags);
337 { 357 flags |= (1<<30); /* NMI M flag is at bit 30 */
338 unsigned long flags; 358 local_irq_restore(flags);
339 local_save_flags(flags); 359 }
340 flags |= (1<<30); /* NMI M flag is at bit 30 */ 360#endif
341 local_irq_restore(flags); 361
342 } 362#ifdef CONFIG_CPU_FREQ
363 cpufreq_register_notifier(&cris_time_freq_notifier_block,
364 CPUFREQ_TRANSITION_NOTIFIER);
343#endif 365#endif
344} 366}
367
368#ifdef CONFIG_CPU_FREQ
369static int
370cris_time_freq_notifier(struct notifier_block *nb, unsigned long val,
371 void *data)
372{
373 struct cpufreq_freqs *freqs = data;
374 if (val == CPUFREQ_POSTCHANGE) {
375 reg_timer_r_tmr0_data data;
376 reg_timer_rw_tmr0_div div = (freqs->new * 500) / HZ;
377 do {
378 data = REG_RD(timer, timer_regs[freqs->cpu],
379 r_tmr0_data);
380 } while (data > 20);
381 REG_WR(timer, timer_regs[freqs->cpu], rw_tmr0_div, div);
382 }
383 return 0;
384}
385#endif
diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c
index 17fd3dbd1c80..9003e382cada 100644
--- a/arch/cris/arch-v32/kernel/traps.c
+++ b/arch/cris/arch-v32/kernel/traps.c
@@ -1,50 +1,45 @@
1/* 1/*
2 * Copyright (C) 2003, Axis Communications AB. 2 * Copyright (C) 2003-2006, Axis Communications AB.
3 */ 3 */
4 4
5#include <linux/ptrace.h> 5#include <linux/ptrace.h>
6#include <linux/module.h>
6#include <asm/uaccess.h> 7#include <asm/uaccess.h>
7 8#include <hwregs/supp_reg.h>
8#include <asm/arch/hwregs/supp_reg.h> 9#include <hwregs/intr_vect_defs.h>
9 10#include <asm/irq.h>
10extern void reset_watchdog(void);
11extern void stop_watchdog(void);
12
13extern int raw_printk(const char *fmt, ...);
14 11
15void 12void
16show_registers(struct pt_regs *regs) 13show_registers(struct pt_regs *regs)
17{ 14{
18 /* 15 /*
19 * It's possible to use either the USP register or current->thread.usp. 16 * It's possible to use either the USP register or current->thread.usp.
20 * USP might not correspond to the current proccess for all cases this 17 * USP might not correspond to the current process for all cases this
21 * function is called, and current->thread.usp isn't up to date for the 18 * function is called, and current->thread.usp isn't up to date for the
22 * current proccess. Experience shows that using USP is the way to go. 19 * current process. Experience shows that using USP is the way to go.
23 */ 20 */
24 unsigned long usp; 21 unsigned long usp = rdusp();
25 unsigned long d_mmu_cause; 22 unsigned long d_mmu_cause;
26 unsigned long i_mmu_cause; 23 unsigned long i_mmu_cause;
27 24
28 usp = rdusp(); 25 printk("CPU: %d\n", smp_processor_id());
29 26
30 raw_printk("CPU: %d\n", smp_processor_id()); 27 printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n",
28 regs->erp, regs->srp, regs->ccs, usp, regs->mof);
31 29
32 raw_printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n", 30 printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
33 regs->erp, regs->srp, regs->ccs, usp, regs->mof); 31 regs->r0, regs->r1, regs->r2, regs->r3);
34 32
35 raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", 33 printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
36 regs->r0, regs->r1, regs->r2, regs->r3); 34 regs->r4, regs->r5, regs->r6, regs->r7);
37 35
38 raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", 36 printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
39 regs->r4, regs->r5, regs->r6, regs->r7); 37 regs->r8, regs->r9, regs->r10, regs->r11);
40 38
41 raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", 39 printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
42 regs->r8, regs->r9, regs->r10, regs->r11); 40 regs->r12, regs->r13, regs->orig_r10, regs->acr);
43 41
44 raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n", 42 printk(" sp: %08lx\n", (unsigned long)regs);
45 regs->r12, regs->r13, regs->orig_r10, regs->acr);
46
47 raw_printk("sp: %08lx\n", regs);
48 43
49 SUPP_BANK_SEL(BANK_IM); 44 SUPP_BANK_SEL(BANK_IM);
50 SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause); 45 SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause);
@@ -52,18 +47,20 @@ show_registers(struct pt_regs *regs)
52 SUPP_BANK_SEL(BANK_DM); 47 SUPP_BANK_SEL(BANK_DM);
53 SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause); 48 SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause);
54 49
55 raw_printk(" Data MMU Cause: %08lx\n", d_mmu_cause); 50 printk(" Data MMU Cause: %08lx\n", d_mmu_cause);
56 raw_printk("Instruction MMU Cause: %08lx\n", i_mmu_cause); 51 printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
57 52
58 raw_printk("Process %s (pid: %d, stackpage: %08lx)\n", 53 printk("Process %s (pid: %d, stackpage=%08lx)\n",
59 current->comm, current->pid, (unsigned long) current); 54 current->comm, current->pid, (unsigned long)current);
60 55
61 /* Show additional info if in kernel-mode. */ 56 /*
57 * When in-kernel, we also print out the stack and code at the
58 * time of the fault..
59 */
62 if (!user_mode(regs)) { 60 if (!user_mode(regs)) {
63 int i; 61 int i;
64 unsigned char c;
65 62
66 show_stack(NULL, (unsigned long *) usp); 63 show_stack(NULL, (unsigned long *)usp);
67 64
68 /* 65 /*
69 * If the previous stack-dump wasn't a kernel one, dump the 66 * If the previous stack-dump wasn't a kernel one, dump the
@@ -72,7 +69,7 @@ show_registers(struct pt_regs *regs)
72 if (usp != 0) 69 if (usp != 0)
73 show_stack(NULL, NULL); 70 show_stack(NULL, NULL);
74 71
75 raw_printk("\nCode: "); 72 printk("\nCode: ");
76 73
77 if (regs->erp < PAGE_OFFSET) 74 if (regs->erp < PAGE_OFFSET)
78 goto bad_value; 75 goto bad_value;
@@ -84,76 +81,115 @@ show_registers(struct pt_regs *regs)
84 * instruction decoding should be in sync at the interesting 81 * instruction decoding should be in sync at the interesting
85 * point, but small enough to fit on a row. The regs->erp 82 * point, but small enough to fit on a row. The regs->erp
86 * location is pointed out in a ksymoops-friendly way by 83 * location is pointed out in a ksymoops-friendly way by
87 * wrapping the byte for that address in parenthesis. 84 * wrapping the byte for that address in parenthesises.
88 */ 85 */
89 for (i = -12; i < 12; i++) { 86 for (i = -12; i < 12; i++) {
90 if (__get_user(c, &((unsigned char *) regs->erp)[i])) { 87 unsigned char c;
88
89 if (__get_user(c, &((unsigned char *)regs->erp)[i])) {
91bad_value: 90bad_value:
92 raw_printk(" Bad IP value."); 91 printk(" Bad IP value.");
93 break; 92 break;
94 } 93 }
95 94
96 if (i == 0) 95 if (i == 0)
97 raw_printk("(%02x) ", c); 96 printk("(%02x) ", c);
98 else 97 else
99 raw_printk("%02x ", c); 98 printk("%02x ", c);
100 } 99 }
101 100 printk("\n");
102 raw_printk("\n");
103 } 101 }
104} 102}
105 103
106/*
107 * This gets called from entry.S when the watchdog has bitten. Show something
108 * similar to an Oops dump, and if the kernel is configured to be a nice doggy;
109 * halt instead of reboot.
110 */
111void 104void
112watchdog_bite_hook(struct pt_regs *regs) 105arch_enable_nmi(void)
113{ 106{
114#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 107 unsigned long flags;
115 local_irq_disable();
116 stop_watchdog();
117 show_registers(regs);
118 108
119 while (1) 109 local_save_flags(flags);
120 ; /* Do nothing. */ 110 flags |= (1 << 30); /* NMI M flag is at bit 30 */
121#else 111 local_irq_restore(flags);
122 show_registers(regs);
123#endif
124} 112}
125 113
126/* This is normally the Oops function. */ 114extern void (*nmi_handler)(struct pt_regs *);
127void 115void handle_nmi(struct pt_regs *regs)
128die_if_kernel(const char *str, struct pt_regs *regs, long err)
129{ 116{
130 if (user_mode(regs)) 117#ifdef CONFIG_ETRAXFS
131 return; 118 reg_intr_vect_r_nmi r;
119#endif
132 120
133#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 121 if (nmi_handler)
134 /* 122 nmi_handler(regs);
135 * This printout might take too long and could trigger 123
136 * the watchdog normally. If NICE_DOGGY is set, simply 124#ifdef CONFIG_ETRAXFS
137 * stop the watchdog during the printout. 125 /* Wait until nmi is no longer active. */
138 */ 126 do {
139 stop_watchdog(); 127 r = REG_RD(intr_vect, regi_irq, r_nmi);
128 } while (r.ext == regk_intr_vect_on);
140#endif 129#endif
130}
141 131
142 raw_printk("%s: %04lx\n", str, err & 0xffff);
143 132
144 show_registers(regs); 133#ifdef CONFIG_BUG
134extern void die_if_kernel(const char *str, struct pt_regs *regs, long err);
145 135
146#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 136/* Copy of the regs at BUG() time. */
147 reset_watchdog(); 137struct pt_regs BUG_regs;
148#endif
149 138
150 do_exit(SIGSEGV); 139void do_BUG(char *file, unsigned int line)
140{
141 printk("kernel BUG at %s:%d!\n", file, line);
142 die_if_kernel("Oops", &BUG_regs, 0);
151} 143}
144EXPORT_SYMBOL(do_BUG);
152 145
153void arch_enable_nmi(void) 146void fixup_BUG(struct pt_regs *regs)
154{ 147{
155 unsigned long flags; 148 BUG_regs = *regs;
156 local_save_flags(flags); 149
157 flags |= (1<<30); /* NMI M flag is at bit 30 */ 150#ifdef CONFIG_DEBUG_BUGVERBOSE
158 local_irq_restore(flags); 151 /*
152 * Fixup the BUG arguments through exception handlers.
153 */
154 {
155 const struct exception_table_entry *fixup;
156
157 /*
158 * ERP points at the "break 14" + 2, compensate for the 2
159 * bytes.
160 */
161 fixup = search_exception_tables(instruction_pointer(regs) - 2);
162 if (fixup) {
163 /* Adjust the instruction pointer in the stackframe. */
164 instruction_pointer(regs) = fixup->fixup;
165 arch_fixup(regs);
166 }
167 }
168#else
169 /* Dont try to lookup the filename + line, just dump regs. */
170 do_BUG("unknown", 0);
171#endif
159} 172}
173
174/*
175 * Break 14 handler. Save regs and jump into the fixup_BUG.
176 */
177__asm__ ( ".text\n\t"
178 ".global breakh_BUG\n\t"
179 "breakh_BUG:\n\t"
180 SAVE_ALL
181 KGDB_FIXUP
182 "move.d $sp, $r10\n\t"
183 "jsr fixup_BUG\n\t"
184 "nop\n\t"
185 "jump ret_from_intr\n\t"
186 "nop\n\t");
187
188
189#ifdef CONFIG_DEBUG_BUGVERBOSE
190void
191handle_BUG(struct pt_regs *regs)
192{
193}
194#endif
195#endif
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.c b/arch/cris/arch-v32/kernel/vcs_hook.c
deleted file mode 100644
index 64d71c54c22c..000000000000
--- a/arch/cris/arch-v32/kernel/vcs_hook.c
+++ /dev/null
@@ -1,96 +0,0 @@
1// $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $
2//
3// Call simulator hook. This is the part running in the
4// simulated program.
5//
6
7#include "vcs_hook.h"
8#include <stdarg.h>
9#include <asm/arch-v32/hwregs/reg_map.h>
10#include <asm/arch-v32/hwregs/intr_vect_defs.h>
11
12#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
13#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
14
15#define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset]
16#define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset]
17#define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0)
18#define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset]
19
20
21// ------------------------------------------------------------------ hook_call
22int hook_call( unsigned id, unsigned pcnt, ...) {
23 va_list ap;
24 unsigned i;
25 unsigned ret;
26#ifdef USING_SOS
27 PREEMPT_OFF_SAVE();
28#endif
29
30 // pass parameters
31 HOOK_DATA(0) = id;
32
33 /* Have to make hook_print_str a special case since we call with a
34 parameter of byte type. Should perhaps be a separate
35 hook_call. */
36
37 if (id == hook_print_str) {
38 int i;
39 char *str;
40
41 HOOK_DATA(1) = pcnt;
42
43 va_start(ap, pcnt);
44 str = (char*)va_arg(ap,unsigned);
45
46 for (i=0; i!=pcnt; i++) {
47 HOOK_DATA_BYTE(8+i) = str[i];
48 }
49 HOOK_DATA_BYTE(8+i) = 0; /* null byte */
50 }
51 else {
52 va_start(ap, pcnt);
53 for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned);
54 va_end(ap);
55 }
56
57 // read from mem to make sure data has propagated to memory before trigging
58 *((volatile unsigned*) HOOK_MEM_BASE_ADDR);
59
60 // trigger hook
61 HOOK_TRIG(id);
62
63 // wait for call to finish
64 while( VHOOK_DATA(0) > 0 ) {}
65
66 // extract return value
67
68 ret = VHOOK_DATA(1);
69
70#ifdef USING_SOS
71 PREEMPT_RESTORE();
72#endif
73 return ret;
74}
75
76unsigned
77hook_buf(unsigned i)
78{
79 return (HOOK_DATA(i));
80}
81
82void print_str( const char *str ) {
83 int i;
84 for (i=1; str[i]; i++); /* find null at end of string */
85 hook_call(hook_print_str, i, str);
86}
87
88// --------------------------------------------------------------- CPU_KICK_DOG
89void CPU_KICK_DOG(void) {
90 (void) hook_call( hook_kick_dog, 0 );
91}
92
93// ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT
94void CPU_WATCHDOG_TIMEOUT( unsigned t ) {
95 (void) hook_call( hook_dog_timeout, 1, t );
96}
diff --git a/arch/cris/arch-v32/lib/Makefile b/arch/cris/arch-v32/lib/Makefile
index 05b3ec6978d6..eb4aad1f1158 100644
--- a/arch/cris/arch-v32/lib/Makefile
+++ b/arch/cris/arch-v32/lib/Makefile
@@ -2,5 +2,6 @@
2# Makefile for Etrax-specific library files.. 2# Makefile for Etrax-specific library files..
3# 3#
4 4
5lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o 5lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o \
6 csumcpfruser.o spinlock.o delay.o
6 7
diff --git a/arch/cris/arch-v32/lib/checksum.S b/arch/cris/arch-v32/lib/checksum.S
index 32e66181b826..87f3fd71ab10 100644
--- a/arch/cris/arch-v32/lib/checksum.S
+++ b/arch/cris/arch-v32/lib/checksum.S
@@ -1,6 +1,6 @@
1/* 1/*
2 * A fast checksum routine using movem 2 * A fast checksum routine using movem
3 * Copyright (c) 1998-2001, 2003 Axis Communications AB 3 * Copyright (c) 1998-2007 Axis Communications AB
4 * 4 *
5 * csum_partial(const unsigned char * buff, int len, unsigned int sum) 5 * csum_partial(const unsigned char * buff, int len, unsigned int sum)
6 */ 6 */
@@ -12,30 +12,23 @@ csum_partial:
12 ;; r11 - length 12 ;; r11 - length
13 ;; r12 - checksum 13 ;; r12 - checksum
14 14
15 ;; check for breakeven length between movem and normal word looping versions 15 ;; Optimized for large packets
16 ;; we also do _NOT_ want to compute a checksum over more than the 16 subq 10*4, $r11
17 ;; actual length when length < 40 17 blt _word_loop
18 18 move.d $r11, $acr
19 cmpu.w 80,$r11
20 blo _word_loop
21 nop
22
23 ;; need to save the registers we use below in the movem loop
24 ;; this overhead is why we have a check above for breakeven length
25 ;; only r0 - r8 have to be saved, the other ones are clobber-able
26 ;; according to the ABI
27 19
28 subq 9*4,$sp 20 subq 9*4,$sp
29 subq 10*4,$r11 ; update length for the first loop 21 clearf c
30 movem $r8,[$sp] 22 movem $r8,[$sp]
31 23
32 ;; do a movem checksum 24 ;; do a movem checksum
33 25
34_mloop: movem [$r10+],$r9 ; read 10 longwords 26_mloop: movem [$r10+],$r9 ; read 10 longwords
35 27 ;; Loop count without touching the c flag.
28 addoq -10*4, $acr, $acr
36 ;; perform dword checksumming on the 10 longwords 29 ;; perform dword checksumming on the 10 longwords
37 30
38 add.d $r0,$r12 31 addc $r0,$r12
39 addc $r1,$r12 32 addc $r1,$r12
40 addc $r2,$r12 33 addc $r2,$r12
41 addc $r3,$r12 34 addc $r3,$r12
@@ -46,60 +39,41 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords
46 addc $r8,$r12 39 addc $r8,$r12
47 addc $r9,$r12 40 addc $r9,$r12
48 41
49 ;; fold the carry into the checksum, to avoid having to loop the carry 42 ;; test $acr without trashing carry.
50 ;; back into the top 43 move.d $acr, $acr
51 44 bpl _mloop
52 addc 0,$r12 45 ;; r11 <= acr is not really needed in the mloop, just using the dslot
53 addc 0,$r12 ; do it again, since we might have generated a carry 46 ;; to prepare for what is needed after mloop.
54 47 move.d $acr, $r11
55 subq 10*4,$r11
56 bge _mloop
57 nop
58
59 addq 10*4,$r11 ; compensate for last loop underflowing length
60 48
49 ;; fold the last carry into r13
50 addc 0, $r12
61 movem [$sp+],$r8 ; restore regs 51 movem [$sp+],$r8 ; restore regs
62 52
63_word_loop: 53_word_loop:
64 ;; only fold if there is anything to fold. 54 addq 10*4,$r11 ; compensate for last loop underflowing length
65
66 cmpq 0,$r12
67 beq _no_fold
68
69 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
70 ;; r9 and r13 can be used as temporaries.
71 55
72 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9 56 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
73 lsrq 16,$r9 57 lsrq 16,$r9
74 58
75 move.d $r12,$r13 59 move.d $r12,$r13
76 lsrq 16,$r13 ; r13 = checksum >> 16 60 lsrq 16,$r13 ; r13 = checksum >> 16
77 and.d $r9,$r12 ; checksum = checksum & 0xffff 61 and.d $r9,$r12 ; checksum = checksum & 0xffff
78 add.d $r13,$r12 ; checksum += r13
79 move.d $r12,$r13 ; do the same again, maybe we got a carry last add
80 lsrq 16,$r13
81 and.d $r9,$r12
82 add.d $r13,$r12
83 62
84_no_fold: 63_no_fold:
85 cmpq 2,$r11 64 subq 2,$r11
86 blt _no_words 65 blt _no_words
87 nop 66 add.d $r13,$r12 ; checksum += r13
88 67
89 ;; checksum the rest of the words 68 ;; checksum the rest of the words
90
91 subq 2,$r11
92
93_wloop: subq 2,$r11 69_wloop: subq 2,$r11
94 bge _wloop 70 bge _wloop
95 addu.w [$r10+],$r12 71 addu.w [$r10+],$r12
96 72
97 addq 2,$r11
98
99_no_words: 73_no_words:
74 addq 2,$r11
100 ;; see if we have one odd byte more 75 ;; see if we have one odd byte more
101 cmpq 1,$r11 76 bne _do_byte
102 beq _do_byte
103 nop 77 nop
104 ret 78 ret
105 move.d $r12,$r10 79 move.d $r12,$r10
diff --git a/arch/cris/arch-v32/lib/checksumcopy.S b/arch/cris/arch-v32/lib/checksumcopy.S
index 9303ccbadc6d..21aabe91489b 100644
--- a/arch/cris/arch-v32/lib/checksumcopy.S
+++ b/arch/cris/arch-v32/lib/checksumcopy.S
@@ -1,6 +1,6 @@
1/* 1/*
2 * A fast checksum+copy routine using movem 2 * A fast checksum+copy routine using movem
3 * Copyright (c) 1998, 2001, 2003 Axis Communications AB 3 * Copyright (c) 1998-2007 Axis Communications AB
4 * 4 *
5 * Authors: Bjorn Wesen 5 * Authors: Bjorn Wesen
6 * 6 *
@@ -16,32 +16,23 @@ csum_partial_copy_nocheck:
16 ;; r12 - length 16 ;; r12 - length
17 ;; r13 - checksum 17 ;; r13 - checksum
18 18
19 ;; check for breakeven length between movem and normal word looping versions 19 ;; Optimized for large packets
20 ;; we also do _NOT_ want to compute a checksum over more than the 20 subq 10*4, $r12
21 ;; actual length when length < 40 21 blt _word_loop
22 22 move.d $r12, $acr
23 cmpu.w 80,$r12
24 blo _word_loop
25 nop
26
27 ;; need to save the registers we use below in the movem loop
28 ;; this overhead is why we have a check above for breakeven length
29 ;; only r0 - r8 have to be saved, the other ones are clobber-able
30 ;; according to the ABI
31 23
32 subq 9*4,$sp 24 subq 9*4,$sp
33 subq 10*4,$r12 ; update length for the first loop 25 clearf c
34 movem $r8,[$sp] 26 movem $r8,[$sp]
35 27
36 ;; do a movem copy and checksum 28 ;; do a movem copy and checksum
37
381: ;; A failing userspace access (the read) will have this as PC. 291: ;; A failing userspace access (the read) will have this as PC.
39_mloop: movem [$r10+],$r9 ; read 10 longwords 30_mloop: movem [$r10+],$r9 ; read 10 longwords
31 addoq -10*4, $acr, $acr ; loop counter in latency cycle
40 movem $r9,[$r11+] ; write 10 longwords 32 movem $r9,[$r11+] ; write 10 longwords
41 33
42 ;; perform dword checksumming on the 10 longwords 34 ;; perform dword checksumming on the 10 longwords
43 35 addc $r0,$r13
44 add.d $r0,$r13
45 addc $r1,$r13 36 addc $r1,$r13
46 addc $r2,$r13 37 addc $r2,$r13
47 addc $r3,$r13 38 addc $r3,$r13
@@ -52,47 +43,30 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords
52 addc $r8,$r13 43 addc $r8,$r13
53 addc $r9,$r13 44 addc $r9,$r13
54 45
55 ;; fold the carry into the checksum, to avoid having to loop the carry 46 ;; test $acr, without trashing carry.
56 ;; back into the top 47 move.d $acr, $acr
57 48 bpl _mloop
58 addc 0,$r13 49 ;; r12 <= acr is needed after mloop and in the exception handlers.
59 addc 0,$r13 ; do it again, since we might have generated a carry 50 move.d $acr, $r12
60
61 subq 10*4,$r12
62 bge _mloop
63 nop
64
65 addq 10*4,$r12 ; compensate for last loop underflowing length
66 51
52 ;; fold the last carry into r13
53 addc 0, $r13
67 movem [$sp+],$r8 ; restore regs 54 movem [$sp+],$r8 ; restore regs
68 55
69_word_loop: 56_word_loop:
70 ;; only fold if there is anything to fold. 57 addq 10*4,$r12 ; compensate for last loop underflowing length
71
72 cmpq 0,$r13
73 beq _no_fold
74 58
75 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below 59 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
76 ;; r9 can be used as temporary. 60 ;; r9 can be used as temporary.
77
78 move.d $r13,$r9 61 move.d $r13,$r9
79 lsrq 16,$r9 ; r0 = checksum >> 16 62 lsrq 16,$r9 ; r0 = checksum >> 16
80 and.d 0xffff,$r13 ; checksum = checksum & 0xffff 63 and.d 0xffff,$r13 ; checksum = checksum & 0xffff
81 add.d $r9,$r13 ; checksum += r0
82 move.d $r13,$r9 ; do the same again, maybe we got a carry last add
83 lsrq 16,$r9
84 and.d 0xffff,$r13
85 add.d $r9,$r13
86 64
87_no_fold: 65 subq 2, $r12
88 cmpq 2,$r12
89 blt _no_words 66 blt _no_words
90 nop 67 add.d $r9,$r13 ; checksum += r0
91 68
92 ;; copy and checksum the rest of the words 69 ;; copy and checksum the rest of the words
93
94 subq 2,$r12
95
962: ;; A failing userspace access for the read below will have this as PC. 702: ;; A failing userspace access for the read below will have this as PC.
97_wloop: move.w [$r10+],$r9 71_wloop: move.w [$r10+],$r9
98 addu.w $r9,$r13 72 addu.w $r9,$r13
@@ -100,12 +74,9 @@ _wloop: move.w [$r10+],$r9
100 bge _wloop 74 bge _wloop
101 move.w $r9,[$r11+] 75 move.w $r9,[$r11+]
102 76
103 addq 2,$r12
104
105_no_words: 77_no_words:
106 ;; see if we have one odd byte more 78 addq 2,$r12
107 cmpq 1,$r12 79 bne _do_byte
108 beq _do_byte
109 nop 80 nop
110 ret 81 ret
111 move.d $r13,$r10 82 move.d $r13,$r10
diff --git a/arch/cris/arch-v32/lib/delay.c b/arch/cris/arch-v32/lib/delay.c
new file mode 100644
index 000000000000..39f1ac9995b4
--- /dev/null
+++ b/arch/cris/arch-v32/lib/delay.c
@@ -0,0 +1,28 @@
1/*
2 * Precise Delay Loops for ETRAX FS
3 *
4 * Copyright (C) 2006 Axis Communications AB.
5 *
6 */
7
8#include <hwregs/reg_map.h>
9#include <hwregs/reg_rdwr.h>
10#include <hwregs/timer_defs.h>
11#include <linux/types.h>
12#include <linux/delay.h>
13#include <linux/module.h>
14
15/*
16 * On ETRAX FS, we can check the free-running read-only 100MHz timer
17 * getting 32-bit 10ns precision, theoretically good for 42.94967295
18 * seconds. Unsigned arithmetic and careful expression handles
19 * wrapping.
20 */
21
22void cris_delay10ns(u32 n10ns)
23{
24 u32 t0 = REG_RD(timer, regi_timer0, r_time);
25 while (REG_RD(timer, regi_timer0, r_time) - t0 < n10ns)
26 ;
27}
28EXPORT_SYMBOL(cris_delay10ns);
diff --git a/arch/cris/arch-v32/lib/spinlock.S b/arch/cris/arch-v32/lib/spinlock.S
index 2437ae7f6ed2..79087ef59a1c 100644
--- a/arch/cris/arch-v32/lib/spinlock.S
+++ b/arch/cris/arch-v32/lib/spinlock.S
@@ -12,11 +12,11 @@
12 12
13cris_spin_lock: 13cris_spin_lock:
14 clearf p 14 clearf p
151: test.d [$r10] 151: test.b [$r10]
16 beq 1b 16 beq 1b
17 clearf p 17 clearf p
18 ax 18 ax
19 clear.d [$r10] 19 clear.b [$r10]
20 bcs 1b 20 bcs 1b
21 clearf p 21 clearf p
22 ret 22 ret
@@ -24,10 +24,10 @@ cris_spin_lock:
24 24
25cris_spin_trylock: 25cris_spin_trylock:
26 clearf p 26 clearf p
271: move.d [$r10], $r11 271: move.b [$r10], $r11
28 ax 28 ax
29 clear.d [$r10] 29 clear.b [$r10]
30 bcs 1b 30 bcs 1b
31 clearf p 31 clearf p
32 ret 32 ret
33 move.d $r11,$r10 33 movu.b $r11,$r10
diff --git a/arch/cris/arch-v32/mach-a3/Kconfig b/arch/cris/arch-v32/mach-a3/Kconfig
new file mode 100644
index 000000000000..a4df06d5997a
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/Kconfig
@@ -0,0 +1,110 @@
1if CRIS_MACH_ARTPEC3
2
3menu "Artpec-3 options"
4 depends on CRIS_MACH_ARTPEC3
5
6config ETRAX_DRAM_VIRTUAL_BASE
7 hex
8 default "c0000000"
9
10config ETRAX_L2CACHE
11 bool
12 default y
13
14config ETRAX_SERIAL_PORTS
15 int
16 default 5
17
18config ETRAX_DDR
19 bool
20 default y
21
22config ETRAX_DDR2_MRS
23 hex "DDR2 MRS"
24 default "0"
25
26config ETRAX_DDR2_TIMING
27 hex "DDR2 SDRAM timing"
28 default "0"
29 help
30 SDRAM timing parameters.
31
32config ETRAX_DDR2_CONFIG
33 hex "DDR2 config"
34 default "0"
35
36config ETRAX_PIO_CE0_CFG
37 hex "PIO CE0 configuration"
38 default "0"
39
40config ETRAX_PIO_CE1_CFG
41 hex "PIO CE1 configuration"
42 default "0"
43
44config ETRAX_PIO_CE2_CFG
45 hex "PIO CE2 configuration"
46 default "0"
47
48config ETRAX_DEF_GIO_PA_OE
49 hex "GIO_PA_OE"
50 default "00000000"
51 help
52 Configures the direction of general port A bits. 1 is out, 0 is in.
53 This is often totally different depending on the product used.
54 There are some guidelines though - if you know that only LED's are
55 connected to port PA, then they are usually connected to bits 2-4
56 and you can therefore use 1c. On other boards which don't have the
57 LED's at the general ports, these bits are used for all kinds of
58 stuff. If you don't know what to use, it is always safe to put all
59 as inputs, although floating inputs isn't good.
60
61config ETRAX_DEF_GIO_PA_OUT
62 hex "GIO_PA_OUT"
63 default "00000000"
64 help
65 Configures the initial data for the general port A bits. Most
66 products should use 00 here.
67
68config ETRAX_DEF_GIO_PB_OE
69 hex "GIO_PB_OE"
70 default "000000000"
71 help
72 Configures the direction of general port B bits. 1 is out, 0 is in.
73 This is often totally different depending on the product used.
74 There are some guidelines though - if you know that only LED's are
75 connected to port PA, then they are usually connected to bits 2-4
76 and you can therefore use 1c. On other boards which don't have the
77 LED's at the general ports, these bits are used for all kinds of
78 stuff. If you don't know what to use, it is always safe to put all
79 as inputs, although floating inputs isn't good.
80
81config ETRAX_DEF_GIO_PB_OUT
82 hex "GIO_PB_OUT"
83 default "000000000"
84 help
85 Configures the initial data for the general port B bits. Most
86 products should use 00000 here.
87
88config ETRAX_DEF_GIO_PC_OE
89 hex "GIO_PC_OE"
90 default "00000"
91 help
92 Configures the direction of general port C bits. 1 is out, 0 is in.
93 This is often totally different depending on the product used.
94 There are some guidelines though - if you know that only LED's are
95 connected to port PA, then they are usually connected to bits 2-4
96 and you can therefore use 1c. On other boards which don't have the
97 LED's at the general ports, these bits are used for all kinds of
98 stuff. If you don't know what to use, it is always safe to put all
99 as inputs, although floating inputs isn't good.
100
101config ETRAX_DEF_GIO_PC_OUT
102 hex "GIO_PC_OUT"
103 default "00000"
104 help
105 Configures the initial data for the general port C bits. Most
106 products should use 00000 here.
107
108endmenu
109
110endif
diff --git a/arch/cris/arch-v32/mach-a3/Makefile b/arch/cris/arch-v32/mach-a3/Makefile
new file mode 100644
index 000000000000..41fa6a6893a9
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/Makefile
@@ -0,0 +1,11 @@
1# $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $
2#
3# Makefile for the linux kernel.
4#
5
6obj-y := dma.o pinmux.o io.o arbiter.o
7obj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
8obj-$(CONFIG_CPU_FREQ) += cpufreq.o
9
10clean:
11
diff --git a/arch/cris/arch-v32/mach-a3/arbiter.c b/arch/cris/arch-v32/mach-a3/arbiter.c
new file mode 100644
index 000000000000..8b924db71c9a
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/arbiter.c
@@ -0,0 +1,634 @@
1/*
2 * Memory arbiter functions. Allocates bandwidth through the
3 * arbiter and sets up arbiter breakpoints.
4 *
5 * The algorithm first assigns slots to the clients that has specified
6 * bandwidth (e.g. ethernet) and then the remaining slots are divided
7 * on all the active clients.
8 *
9 * Copyright (c) 2004-2007 Axis Communications AB.
10 *
11 * The artpec-3 has two arbiters. The memory hierarchy looks like this:
12 *
13 *
14 * CPU DMAs
15 * | |
16 * | |
17 * -------------- ------------------
18 * | foo arbiter|----| Internal memory|
19 * -------------- ------------------
20 * |
21 * --------------
22 * | L2 cache |
23 * --------------
24 * |
25 * h264 etc |
26 * | |
27 * | |
28 * --------------
29 * | bar arbiter|
30 * --------------
31 * |
32 * ---------
33 * | SDRAM |
34 * ---------
35 *
36 */
37
38#include <hwregs/reg_map.h>
39#include <hwregs/reg_rdwr.h>
40#include <hwregs/marb_foo_defs.h>
41#include <hwregs/marb_bar_defs.h>
42#include <arbiter.h>
43#include <hwregs/intr_vect.h>
44#include <linux/interrupt.h>
45#include <linux/irq.h>
46#include <linux/signal.h>
47#include <linux/errno.h>
48#include <linux/spinlock.h>
49#include <asm/io.h>
50#include <asm/irq_regs.h>
51
52#define D(x)
53
54struct crisv32_watch_entry {
55 unsigned long instance;
56 watch_callback *cb;
57 unsigned long start;
58 unsigned long end;
59 int used;
60};
61
62#define NUMBER_OF_BP 4
63#define SDRAM_BANDWIDTH 400000000
64#define INTMEM_BANDWIDTH 400000000
65#define NBR_OF_SLOTS 64
66#define NBR_OF_REGIONS 2
67#define NBR_OF_CLIENTS 15
68#define ARBITERS 2
69#define UNASSIGNED 100
70
71struct arbiter {
72 unsigned long instance;
73 int nbr_regions;
74 int nbr_clients;
75 int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
76 int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
77};
78
79static struct crisv32_watch_entry watches[ARBITERS][NUMBER_OF_BP] =
80{
81 {
82 {regi_marb_foo_bp0},
83 {regi_marb_foo_bp1},
84 {regi_marb_foo_bp2},
85 {regi_marb_foo_bp3}
86 },
87 {
88 {regi_marb_bar_bp0},
89 {regi_marb_bar_bp1},
90 {regi_marb_bar_bp2},
91 {regi_marb_bar_bp3}
92 }
93};
94
95struct arbiter arbiters[ARBITERS] =
96{
97 { /* L2 cache arbiter */
98 .instance = regi_marb_foo,
99 .nbr_regions = 2,
100 .nbr_clients = 15
101 },
102 { /* DDR2 arbiter */
103 .instance = regi_marb_bar,
104 .nbr_regions = 1,
105 .nbr_clients = 9
106 }
107};
108
109static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH};
110
111DEFINE_SPINLOCK(arbiter_lock);
112
113static irqreturn_t
114crisv32_foo_arbiter_irq(int irq, void *dev_id);
115static irqreturn_t
116crisv32_bar_arbiter_irq(int irq, void *dev_id);
117
118/*
119 * "I'm the arbiter, I know the score.
120 * From square one I'll be watching all 64."
121 * (memory arbiter slots, that is)
122 *
123 * Or in other words:
124 * Program the memory arbiter slots for "region" according to what's
125 * in requested_slots[] and active_clients[], while minimizing
126 * latency. A caller may pass a non-zero positive amount for
127 * "unused_slots", which must then be the unallocated, remaining
128 * number of slots, free to hand out to any client.
129 */
130
131static void crisv32_arbiter_config(int arbiter, int region, int unused_slots)
132{
133 int slot;
134 int client;
135 int interval = 0;
136
137 /*
138 * This vector corresponds to the hardware arbiter slots (see
139 * the hardware documentation for semantics). We initialize
140 * each slot with a suitable sentinel value outside the valid
141 * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
142 * client indexes. Then it's fed to the hardware.
143 */
144 s8 val[NBR_OF_SLOTS];
145
146 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
147 val[slot] = -1;
148
149 for (client = 0; client < arbiters[arbiter].nbr_clients; client++) {
150 int pos;
151 /* Allocate the requested non-zero number of slots, but
152 * also give clients with zero-requests one slot each
153 * while stocks last. We do the latter here, in client
154 * order. This makes sure zero-request clients are the
155 * first to get to any spare slots, else those slots
156 * could, when bandwidth is allocated close to the limit,
157 * all be allocated to low-index non-zero-request clients
158 * in the default-fill loop below. Another positive but
159 * secondary effect is a somewhat better spread of the
160 * zero-bandwidth clients in the vector, avoiding some of
161 * the latency that could otherwise be caused by the
162 * partitioning of non-zero-bandwidth clients at low
163 * indexes and zero-bandwidth clients at high
164 * indexes. (Note that this spreading can only affect the
165 * unallocated bandwidth.) All the above only matters for
166 * memory-intensive situations, of course.
167 */
168 if (!arbiters[arbiter].requested_slots[region][client]) {
169 /*
170 * Skip inactive clients. Also skip zero-slot
171 * allocations in this pass when there are no known
172 * free slots.
173 */
174 if (!arbiters[arbiter].active_clients[region][client] ||
175 unused_slots <= 0)
176 continue;
177
178 unused_slots--;
179
180 /* Only allocate one slot for this client. */
181 interval = NBR_OF_SLOTS;
182 } else
183 interval = NBR_OF_SLOTS /
184 arbiters[arbiter].requested_slots[region][client];
185
186 pos = 0;
187 while (pos < NBR_OF_SLOTS) {
188 if (val[pos] >= 0)
189 pos++;
190 else {
191 val[pos] = client;
192 pos += interval;
193 }
194 }
195 }
196
197 client = 0;
198 for (slot = 0; slot < NBR_OF_SLOTS; slot++) {
199 /*
200 * Allocate remaining slots in round-robin
201 * client-number order for active clients. For this
202 * pass, we ignore requested bandwidth and previous
203 * allocations.
204 */
205 if (val[slot] < 0) {
206 int first = client;
207 while (!arbiters[arbiter].active_clients[region][client]) {
208 client = (client + 1) %
209 arbiters[arbiter].nbr_clients;
210 if (client == first)
211 break;
212 }
213 val[slot] = client;
214 client = (client + 1) % arbiters[arbiter].nbr_clients;
215 }
216 if (arbiter == 0) {
217 if (region == EXT_REGION)
218 REG_WR_INT_VECT(marb_foo, regi_marb_foo,
219 rw_l2_slots, slot, val[slot]);
220 else if (region == INT_REGION)
221 REG_WR_INT_VECT(marb_foo, regi_marb_foo,
222 rw_intm_slots, slot, val[slot]);
223 } else {
224 REG_WR_INT_VECT(marb_bar, regi_marb_bar,
225 rw_ddr2_slots, slot, val[slot]);
226 }
227 }
228}
229
230extern char _stext, _etext;
231
232static void crisv32_arbiter_init(void)
233{
234 static int initialized;
235
236 if (initialized)
237 return;
238
239 initialized = 1;
240
241 /*
242 * CPU caches are always set to active, but with zero
243 * bandwidth allocated. It should be ok to allocate zero
244 * bandwidth for the caches, because DMA for other channels
245 * will supposedly finish, once their programmed amount is
246 * done, and then the caches will get access according to the
247 * "fixed scheme" for unclaimed slots. Though, if for some
248 * use-case somewhere, there's a maximum CPU latency for
249 * e.g. some interrupt, we have to start allocating specific
250 * bandwidth for the CPU caches too.
251 */
252 arbiters[0].active_clients[EXT_REGION][11] = 1;
253 arbiters[0].active_clients[EXT_REGION][12] = 1;
254 crisv32_arbiter_config(0, EXT_REGION, 0);
255 crisv32_arbiter_config(0, INT_REGION, 0);
256 crisv32_arbiter_config(1, EXT_REGION, 0);
257
258 if (request_irq(MEMARB_FOO_INTR_VECT, crisv32_foo_arbiter_irq,
259 IRQF_DISABLED, "arbiter", NULL))
260 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
261
262 if (request_irq(MEMARB_BAR_INTR_VECT, crisv32_bar_arbiter_irq,
263 IRQF_DISABLED, "arbiter", NULL))
264 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
265
266#ifndef CONFIG_ETRAX_KGDB
267 /* Global watch for writes to kernel text segment. */
268 crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
269 MARB_CLIENTS(arbiter_all_clients, arbiter_bar_all_clients),
270 arbiter_all_write, NULL);
271#endif
272
273 /* Set up max burst sizes by default */
274 REG_WR_INT(marb_bar, regi_marb_bar, rw_h264_rd_burst, 3);
275 REG_WR_INT(marb_bar, regi_marb_bar, rw_h264_wr_burst, 3);
276 REG_WR_INT(marb_bar, regi_marb_bar, rw_ccd_burst, 3);
277 REG_WR_INT(marb_bar, regi_marb_bar, rw_vin_wr_burst, 3);
278 REG_WR_INT(marb_bar, regi_marb_bar, rw_vin_rd_burst, 3);
279 REG_WR_INT(marb_bar, regi_marb_bar, rw_sclr_rd_burst, 3);
280 REG_WR_INT(marb_bar, regi_marb_bar, rw_vout_burst, 3);
281 REG_WR_INT(marb_bar, regi_marb_bar, rw_sclr_fifo_burst, 3);
282 REG_WR_INT(marb_bar, regi_marb_bar, rw_l2cache_burst, 3);
283}
284
285int crisv32_arbiter_allocate_bandwidth(int client, int region,
286 unsigned long bandwidth)
287{
288 int i;
289 int total_assigned = 0;
290 int total_clients = 0;
291 int req;
292 int arbiter = 0;
293
294 crisv32_arbiter_init();
295
296 if (client & 0xffff0000) {
297 arbiter = 1;
298 client >>= 16;
299 }
300
301 for (i = 0; i < arbiters[arbiter].nbr_clients; i++) {
302 total_assigned += arbiters[arbiter].requested_slots[region][i];
303 total_clients += arbiters[arbiter].active_clients[region][i];
304 }
305
306 /* Avoid division by 0 for 0-bandwidth requests. */
307 req = bandwidth == 0
308 ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
309
310 /*
311 * We make sure that there are enough slots only for non-zero
312 * requests. Requesting 0 bandwidth *may* allocate slots,
313 * though if all bandwidth is allocated, such a client won't
314 * get any and will have to rely on getting memory access
315 * according to the fixed scheme that's the default when one
316 * of the slot-allocated clients doesn't claim their slot.
317 */
318 if (total_assigned + req > NBR_OF_SLOTS)
319 return -ENOMEM;
320
321 arbiters[arbiter].active_clients[region][client] = 1;
322 arbiters[arbiter].requested_slots[region][client] = req;
323 crisv32_arbiter_config(arbiter, region, NBR_OF_SLOTS - total_assigned);
324
325 /* Propagate allocation from foo to bar */
326 if (arbiter == 0)
327 crisv32_arbiter_allocate_bandwidth(8 << 16,
328 EXT_REGION, bandwidth);
329 return 0;
330}
331
332/*
333 * Main entry for bandwidth deallocation.
334 *
335 * Strictly speaking, for a somewhat constant set of clients where
336 * each client gets a constant bandwidth and is just enabled or
337 * disabled (somewhat dynamically), no action is necessary here to
338 * avoid starvation for non-zero-allocation clients, as the allocated
339 * slots will just be unused. However, handing out those unused slots
340 * to active clients avoids needless latency if the "fixed scheme"
341 * would give unclaimed slots to an eager low-index client.
342 */
343
344void crisv32_arbiter_deallocate_bandwidth(int client, int region)
345{
346 int i;
347 int total_assigned = 0;
348 int arbiter = 0;
349
350 if (client & 0xffff0000)
351 arbiter = 1;
352
353 arbiters[arbiter].requested_slots[region][client] = 0;
354 arbiters[arbiter].active_clients[region][client] = 0;
355
356 for (i = 0; i < arbiters[arbiter].nbr_clients; i++)
357 total_assigned += arbiters[arbiter].requested_slots[region][i];
358
359 crisv32_arbiter_config(arbiter, region, NBR_OF_SLOTS - total_assigned);
360}
361
362int crisv32_arbiter_watch(unsigned long start, unsigned long size,
363 unsigned long clients, unsigned long accesses,
364 watch_callback *cb)
365{
366 int i;
367 int arbiter;
368 int used[2];
369 int ret = 0;
370
371 crisv32_arbiter_init();
372
373 if (start > 0x80000000) {
374 printk(KERN_ERR "Arbiter: %lX doesn't look like a "
375 "physical address", start);
376 return -EFAULT;
377 }
378
379 spin_lock(&arbiter_lock);
380
381 if (clients & 0xffff)
382 used[0] = 1;
383 if (clients & 0xffff0000)
384 used[1] = 1;
385
386 for (arbiter = 0; arbiter < ARBITERS; arbiter++) {
387 if (!used[arbiter])
388 continue;
389
390 for (i = 0; i < NUMBER_OF_BP; i++) {
391 if (!watches[arbiter][i].used) {
392 unsigned intr_mask;
393 if (arbiter)
394 intr_mask = REG_RD_INT(marb_bar,
395 regi_marb_bar, rw_intr_mask);
396 else
397 intr_mask = REG_RD_INT(marb_foo,
398 regi_marb_foo, rw_intr_mask);
399
400 watches[arbiter][i].used = 1;
401 watches[arbiter][i].start = start;
402 watches[arbiter][i].end = start + size;
403 watches[arbiter][i].cb = cb;
404
405 ret |= (i + 1) << (arbiter + 8);
406 if (arbiter) {
407 REG_WR_INT(marb_bar_bp,
408 watches[arbiter][i].instance,
409 rw_first_addr,
410 watches[arbiter][i].start);
411 REG_WR_INT(marb_bar_bp,
412 watches[arbiter][i].instance,
413 rw_last_addr,
414 watches[arbiter][i].end);
415 REG_WR_INT(marb_bar_bp,
416 watches[arbiter][i].instance,
417 rw_op, accesses);
418 REG_WR_INT(marb_bar_bp,
419 watches[arbiter][i].instance,
420 rw_clients,
421 clients & 0xffff);
422 } else {
423 REG_WR_INT(marb_foo_bp,
424 watches[arbiter][i].instance,
425 rw_first_addr,
426 watches[arbiter][i].start);
427 REG_WR_INT(marb_foo_bp,
428 watches[arbiter][i].instance,
429 rw_last_addr,
430 watches[arbiter][i].end);
431 REG_WR_INT(marb_foo_bp,
432 watches[arbiter][i].instance,
433 rw_op, accesses);
434 REG_WR_INT(marb_foo_bp,
435 watches[arbiter][i].instance,
436 rw_clients, clients >> 16);
437 }
438
439 if (i == 0)
440 intr_mask |= 1;
441 else if (i == 1)
442 intr_mask |= 2;
443 else if (i == 2)
444 intr_mask |= 4;
445 else if (i == 3)
446 intr_mask |= 8;
447
448 if (arbiter)
449 REG_WR_INT(marb_bar, regi_marb_bar,
450 rw_intr_mask, intr_mask);
451 else
452 REG_WR_INT(marb_foo, regi_marb_foo,
453 rw_intr_mask, intr_mask);
454
455 spin_unlock(&arbiter_lock);
456
457 break;
458 }
459 }
460 }
461 spin_unlock(&arbiter_lock);
462 if (ret)
463 return ret;
464 else
465 return -ENOMEM;
466}
467
468int crisv32_arbiter_unwatch(int id)
469{
470 int arbiter;
471 int intr_mask;
472
473 crisv32_arbiter_init();
474
475 spin_lock(&arbiter_lock);
476
477 for (arbiter = 0; arbiter < ARBITERS; arbiter++) {
478 int id2;
479
480 if (arbiter)
481 intr_mask = REG_RD_INT(marb_bar, regi_marb_bar,
482 rw_intr_mask);
483 else
484 intr_mask = REG_RD_INT(marb_foo, regi_marb_foo,
485 rw_intr_mask);
486
487 id2 = (id & (0xff << (arbiter + 8))) >> (arbiter + 8);
488 if (id2 == 0)
489 continue;
490 id2--;
491 if ((id2 >= NUMBER_OF_BP) || (!watches[arbiter][id2].used)) {
492 spin_unlock(&arbiter_lock);
493 return -EINVAL;
494 }
495
496 memset(&watches[arbiter][id2], 0,
497 sizeof(struct crisv32_watch_entry));
498
499 if (id2 == 0)
500 intr_mask &= ~1;
501 else if (id2 == 1)
502 intr_mask &= ~2;
503 else if (id2 == 2)
504 intr_mask &= ~4;
505 else if (id2 == 3)
506 intr_mask &= ~8;
507
508 if (arbiter)
509 REG_WR_INT(marb_bar, regi_marb_bar, rw_intr_mask,
510 intr_mask);
511 else
512 REG_WR_INT(marb_foo, regi_marb_foo, rw_intr_mask,
513 intr_mask);
514 }
515
516 spin_unlock(&arbiter_lock);
517 return 0;
518}
519
520extern void show_registers(struct pt_regs *regs);
521
522
523static irqreturn_t
524crisv32_foo_arbiter_irq(int irq, void *dev_id)
525{
526 reg_marb_foo_r_masked_intr masked_intr =
527 REG_RD(marb_foo, regi_marb_foo, r_masked_intr);
528 reg_marb_foo_bp_r_brk_clients r_clients;
529 reg_marb_foo_bp_r_brk_addr r_addr;
530 reg_marb_foo_bp_r_brk_op r_op;
531 reg_marb_foo_bp_r_brk_first_client r_first;
532 reg_marb_foo_bp_r_brk_size r_size;
533 reg_marb_foo_bp_rw_ack ack = {0};
534 reg_marb_foo_rw_ack_intr ack_intr = {
535 .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1
536 };
537 struct crisv32_watch_entry *watch;
538 unsigned arbiter = (unsigned)dev_id;
539
540 masked_intr = REG_RD(marb_foo, regi_marb_foo, r_masked_intr);
541
542 if (masked_intr.bp0)
543 watch = &watches[arbiter][0];
544 else if (masked_intr.bp1)
545 watch = &watches[arbiter][1];
546 else if (masked_intr.bp2)
547 watch = &watches[arbiter][2];
548 else if (masked_intr.bp3)
549 watch = &watches[arbiter][3];
550 else
551 return IRQ_NONE;
552
553 /* Retrieve all useful information and print it. */
554 r_clients = REG_RD(marb_foo_bp, watch->instance, r_brk_clients);
555 r_addr = REG_RD(marb_foo_bp, watch->instance, r_brk_addr);
556 r_op = REG_RD(marb_foo_bp, watch->instance, r_brk_op);
557 r_first = REG_RD(marb_foo_bp, watch->instance, r_brk_first_client);
558 r_size = REG_RD(marb_foo_bp, watch->instance, r_brk_size);
559
560 printk(KERN_DEBUG "Arbiter IRQ\n");
561 printk(KERN_DEBUG "Clients %X addr %X op %X first %X size %X\n",
562 REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_clients, r_clients),
563 REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_addr, r_addr),
564 REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_op, r_op),
565 REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_first_client, r_first),
566 REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_size, r_size));
567
568 REG_WR(marb_foo_bp, watch->instance, rw_ack, ack);
569 REG_WR(marb_foo, regi_marb_foo, rw_ack_intr, ack_intr);
570
571 printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs());
572
573 if (watch->cb)
574 watch->cb();
575
576 return IRQ_HANDLED;
577}
578
579static irqreturn_t
580crisv32_bar_arbiter_irq(int irq, void *dev_id)
581{
582 reg_marb_bar_r_masked_intr masked_intr =
583 REG_RD(marb_bar, regi_marb_bar, r_masked_intr);
584 reg_marb_bar_bp_r_brk_clients r_clients;
585 reg_marb_bar_bp_r_brk_addr r_addr;
586 reg_marb_bar_bp_r_brk_op r_op;
587 reg_marb_bar_bp_r_brk_first_client r_first;
588 reg_marb_bar_bp_r_brk_size r_size;
589 reg_marb_bar_bp_rw_ack ack = {0};
590 reg_marb_bar_rw_ack_intr ack_intr = {
591 .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1
592 };
593 struct crisv32_watch_entry *watch;
594 unsigned arbiter = (unsigned)dev_id;
595
596 masked_intr = REG_RD(marb_bar, regi_marb_bar, r_masked_intr);
597
598 if (masked_intr.bp0)
599 watch = &watches[arbiter][0];
600 else if (masked_intr.bp1)
601 watch = &watches[arbiter][1];
602 else if (masked_intr.bp2)
603 watch = &watches[arbiter][2];
604 else if (masked_intr.bp3)
605 watch = &watches[arbiter][3];
606 else
607 return IRQ_NONE;
608
609 /* Retrieve all useful information and print it. */
610 r_clients = REG_RD(marb_bar_bp, watch->instance, r_brk_clients);
611 r_addr = REG_RD(marb_bar_bp, watch->instance, r_brk_addr);
612 r_op = REG_RD(marb_bar_bp, watch->instance, r_brk_op);
613 r_first = REG_RD(marb_bar_bp, watch->instance, r_brk_first_client);
614 r_size = REG_RD(marb_bar_bp, watch->instance, r_brk_size);
615
616 printk(KERN_DEBUG "Arbiter IRQ\n");
617 printk(KERN_DEBUG "Clients %X addr %X op %X first %X size %X\n",
618 REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_clients, r_clients),
619 REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_addr, r_addr),
620 REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_op, r_op),
621 REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_first_client, r_first),
622 REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_size, r_size));
623
624 REG_WR(marb_bar_bp, watch->instance, rw_ack, ack);
625 REG_WR(marb_bar, regi_marb_bar, rw_ack_intr, ack_intr);
626
627 printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs()->erp);
628
629 if (watch->cb)
630 watch->cb();
631
632 return IRQ_HANDLED;
633}
634
diff --git a/arch/cris/arch-v32/mach-a3/cpufreq.c b/arch/cris/arch-v32/mach-a3/cpufreq.c
new file mode 100644
index 000000000000..8e5a3cab8ad7
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/cpufreq.c
@@ -0,0 +1,153 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/cpufreq.h>
4#include <hwregs/reg_map.h>
5#include <hwregs/reg_rdwr.h>
6#include <hwregs/clkgen_defs.h>
7#include <hwregs/ddr2_defs.h>
8
9static int
10cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
11 void *data);
12
13static struct notifier_block cris_sdram_freq_notifier_block = {
14 .notifier_call = cris_sdram_freq_notifier
15};
16
17static struct cpufreq_frequency_table cris_freq_table[] = {
18 {0x01, 6000},
19 {0x02, 200000},
20 {0, CPUFREQ_TABLE_END},
21};
22
23static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
24{
25 reg_clkgen_rw_clk_ctrl clk_ctrl;
26 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
27 return clk_ctrl.pll ? 200000 : 6000;
28}
29
30static void cris_freq_set_cpu_state(unsigned int state)
31{
32 int i = 0;
33 struct cpufreq_freqs freqs;
34 reg_clkgen_rw_clk_ctrl clk_ctrl;
35 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
36
37#ifdef CONFIG_SMP
38 for_each_present_cpu(i)
39#endif
40 {
41 freqs.old = cris_freq_get_cpu_frequency(i);
42 freqs.new = cris_freq_table[state].frequency;
43 freqs.cpu = i;
44 }
45
46 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
47
48 local_irq_disable();
49
50 /* Even though we may be SMP they will share the same clock
51 * so all settings are made on CPU0. */
52 if (cris_freq_table[state].frequency == 200000)
53 clk_ctrl.pll = 1;
54 else
55 clk_ctrl.pll = 0;
56 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
57
58 local_irq_enable();
59
60 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
61};
62
63static int cris_freq_verify(struct cpufreq_policy *policy)
64{
65 return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
66}
67
68static int cris_freq_target(struct cpufreq_policy *policy,
69 unsigned int target_freq,
70 unsigned int relation)
71{
72 unsigned int newstate = 0;
73
74 if (cpufreq_frequency_table_target(policy, cris_freq_table,
75 target_freq, relation, &newstate))
76 return -EINVAL;
77
78 cris_freq_set_cpu_state(newstate);
79
80 return 0;
81}
82
83static int cris_freq_cpu_init(struct cpufreq_policy *policy)
84{
85 int result;
86
87 /* cpuinfo and default policy values */
88 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
89 policy->cpuinfo.transition_latency = 1000000; /* 1ms */
90 policy->cur = cris_freq_get_cpu_frequency(0);
91
92 result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
93 if (result)
94 return (result);
95
96 cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
97
98 return 0;
99}
100
101
102static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
103{
104 cpufreq_frequency_table_put_attr(policy->cpu);
105 return 0;
106}
107
108
109static struct freq_attr *cris_freq_attr[] = {
110 &cpufreq_freq_attr_scaling_available_freqs,
111 NULL,
112};
113
114static struct cpufreq_driver cris_freq_driver = {
115 .get = cris_freq_get_cpu_frequency,
116 .verify = cris_freq_verify,
117 .target = cris_freq_target,
118 .init = cris_freq_cpu_init,
119 .exit = cris_freq_cpu_exit,
120 .name = "cris_freq",
121 .owner = THIS_MODULE,
122 .attr = cris_freq_attr,
123};
124
125static int __init cris_freq_init(void)
126{
127 int ret;
128 ret = cpufreq_register_driver(&cris_freq_driver);
129 cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
130 CPUFREQ_TRANSITION_NOTIFIER);
131 return ret;
132}
133
134static int
135cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
136 void *data)
137{
138 int i;
139 struct cpufreq_freqs *freqs = data;
140 if (val == CPUFREQ_PRECHANGE) {
141 reg_ddr2_rw_cfg cfg =
142 REG_RD(ddr2, regi_ddr2_ctrl, rw_cfg);
143 cfg.ref_interval = (freqs->new == 200000 ? 1560 : 46);
144
145 if (freqs->new == 200000)
146 for (i = 0; i < 50000; i++);
147 REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
148 }
149 return 0;
150}
151
152
153module_init(cris_freq_init);
diff --git a/arch/cris/arch-v32/mach-a3/dma.c b/arch/cris/arch-v32/mach-a3/dma.c
new file mode 100644
index 000000000000..25f236ef0b81
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/dma.c
@@ -0,0 +1,185 @@
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <asm/arch/mach/dma.h>
6#include <hwregs/reg_map.h>
7#include <hwregs/reg_rdwr.h>
8#include <hwregs/marb_defs.h>
9#include <hwregs/clkgen_defs.h>
10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h>
12#include <asm/system.h>
13#include <arbiter.h>
14
15static char used_dma_channels[MAX_DMA_CHANNELS];
16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
17
18static DEFINE_SPINLOCK(dma_lock);
19
20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
21 unsigned options, unsigned int bandwidth, enum dma_owner owner)
22{
23 unsigned long flags;
24 reg_clkgen_rw_clk_ctrl clk_ctrl;
25 reg_strmux_rw_cfg strmux_cfg;
26
27 if (crisv32_arbiter_allocate_bandwidth(dmanr,
28 options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
29 bandwidth))
30 return -ENOMEM;
31
32 spin_lock_irqsave(&dma_lock, flags);
33
34 if (used_dma_channels[dmanr]) {
35 spin_unlock_irqrestore(&dma_lock, flags);
36 if (options & DMA_VERBOSE_ON_ERROR)
37 printk(KERN_ERR "Failed to request DMA %i for %s, "
38 "already allocated by %s\n",
39 dmanr,
40 device_id,
41 used_dma_channels_users[dmanr]);
42
43 if (options & DMA_PANIC_ON_ERROR)
44 panic("request_dma error!");
45 spin_unlock_irqrestore(&dma_lock, flags);
46 return -EBUSY;
47 }
48 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
49 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
50
51 switch (dmanr) {
52 case 0:
53 case 1:
54 clk_ctrl.dma0_1_eth = 1;
55 break;
56 case 2:
57 case 3:
58 clk_ctrl.dma2_3_strcop = 1;
59 break;
60 case 4:
61 case 5:
62 clk_ctrl.dma4_5_iop = 1;
63 break;
64 case 6:
65 case 7:
66 clk_ctrl.sser_ser_dma6_7 = 1;
67 break;
68 case 9:
69 case 11:
70 clk_ctrl.dma9_11 = 1;
71 break;
72#if MAX_DMA_CHANNELS-1 != 11
73#error Check dma.c
74#endif
75 default:
76 spin_unlock_irqrestore(&dma_lock, flags);
77 if (options & DMA_VERBOSE_ON_ERROR)
78 printk(KERN_ERR "Failed to request DMA %i for %s, "
79 "only 0-%i valid)\n",
80 dmanr, device_id, MAX_DMA_CHANNELS-1);
81
82 if (options & DMA_PANIC_ON_ERROR)
83 panic("request_dma error!");
84 return -EINVAL;
85 }
86
87 switch (owner) {
88 case dma_eth:
89 if (dmanr == 0)
90 strmux_cfg.dma0 = regk_strmux_eth;
91 else if (dmanr == 1)
92 strmux_cfg.dma1 = regk_strmux_eth;
93 else
94 panic("Invalid DMA channel for eth\n");
95 break;
96 case dma_ser0:
97 if (dmanr == 0)
98 strmux_cfg.dma0 = regk_strmux_ser0;
99 else if (dmanr == 1)
100 strmux_cfg.dma1 = regk_strmux_ser0;
101 else
102 panic("Invalid DMA channel for ser0\n");
103 break;
104 case dma_ser3:
105 if (dmanr == 2)
106 strmux_cfg.dma2 = regk_strmux_ser3;
107 else if (dmanr == 3)
108 strmux_cfg.dma3 = regk_strmux_ser3;
109 else
110 panic("Invalid DMA channel for ser3\n");
111 break;
112 case dma_strp:
113 if (dmanr == 2)
114 strmux_cfg.dma2 = regk_strmux_strcop;
115 else if (dmanr == 3)
116 strmux_cfg.dma3 = regk_strmux_strcop;
117 else
118 panic("Invalid DMA channel for strp\n");
119 break;
120 case dma_ser1:
121 if (dmanr == 4)
122 strmux_cfg.dma4 = regk_strmux_ser1;
123 else if (dmanr == 5)
124 strmux_cfg.dma5 = regk_strmux_ser1;
125 else
126 panic("Invalid DMA channel for ser1\n");
127 break;
128 case dma_iop:
129 if (dmanr == 4)
130 strmux_cfg.dma4 = regk_strmux_iop;
131 else if (dmanr == 5)
132 strmux_cfg.dma5 = regk_strmux_iop;
133 else
134 panic("Invalid DMA channel for iop\n");
135 break;
136 case dma_ser2:
137 if (dmanr == 6)
138 strmux_cfg.dma6 = regk_strmux_ser2;
139 else if (dmanr == 7)
140 strmux_cfg.dma7 = regk_strmux_ser2;
141 else
142 panic("Invalid DMA channel for ser2\n");
143 break;
144 case dma_sser:
145 if (dmanr == 6)
146 strmux_cfg.dma6 = regk_strmux_sser;
147 else if (dmanr == 7)
148 strmux_cfg.dma7 = regk_strmux_sser;
149 else
150 panic("Invalid DMA channel for sser\n");
151 break;
152 case dma_ser4:
153 if (dmanr == 9)
154 strmux_cfg.dma9 = regk_strmux_ser4;
155 else
156 panic("Invalid DMA channel for ser4\n");
157 break;
158 case dma_jpeg:
159 if (dmanr == 9)
160 strmux_cfg.dma9 = regk_strmux_jpeg;
161 else
162 panic("Invalid DMA channel for JPEG\n");
163 break;
164 case dma_h264:
165 if (dmanr == 11)
166 strmux_cfg.dma11 = regk_strmux_h264;
167 else
168 panic("Invalid DMA channel for H264\n");
169 break;
170 }
171
172 used_dma_channels[dmanr] = 1;
173 used_dma_channels_users[dmanr] = device_id;
174 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
175 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
176 spin_unlock_irqrestore(&dma_lock, flags);
177 return 0;
178}
179
180void crisv32_free_dma(unsigned int dmanr)
181{
182 spin_lock(&dma_lock);
183 used_dma_channels[dmanr] = 0;
184 spin_unlock(&dma_lock);
185}
diff --git a/arch/cris/arch-v32/mach-a3/dram_init.S b/arch/cris/arch-v32/mach-a3/dram_init.S
new file mode 100644
index 000000000000..94d6b41cb299
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/dram_init.S
@@ -0,0 +1,104 @@
1/*
2 * DDR SDRAM initialization - alter with care
3 * This file is intended to be included from other assembler files
4 *
5 * Note: This file may not modify r8 or r9 because they are used to
6 * carry information from the decompresser to the kernel
7 *
8 * Copyright (C) 2005-2007 Axis Communications AB
9 *
10 * Authors: Mikael Starvik <starvik@axis.com>
11 */
12
13/* Just to be certain the config file is included, we include it here
14 * explicitely instead of depending on it being included in the file that
15 * uses this code.
16 */
17
18#include <hwregs/asm/reg_map_asm.h>
19#include <hwregs/asm/ddr2_defs_asm.h>
20
21 ;; WARNING! The registers r8 and r9 are used as parameters carrying
22 ;; information from the decompressor (if the kernel was compressed).
23 ;; They should not be used in the code below.
24
25 ;; Refer to ddr2 MDS for initialization sequence
26
27 ; Start clock
28 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_cfg), $r0
29 move.d REG_STATE(ddr2, rw_phy_cfg, en, yes), $r1
30 move.d $r1, [$r0]
31
32 ; Reset phy and start calibration
33 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_ctrl), $r0
34 move.d REG_STATE(ddr2, rw_phy_ctrl, rst, yes) | \
35 REG_STATE(ddr2, rw_phy_ctrl, cal_rst, yes), $r1
36 move.d $r1, [$r0]
37 move.d REG_STATE(ddr2, rw_phy_ctrl, cal_start, yes), $r1
38 move.d $r1, [$r0]
39
40 ; 2. Wait 200us
41 move.d 10000, $r2
421: bne 1b
43 subq 1, $r2
44
45 ; Issue commands
46 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_ctrl), $r0
47 move.d sdram_commands_start, $r2
48command_loop:
49 movu.b [$r2+], $r1
50 movu.w [$r2+], $r3
51do_cmd:
52 lslq 16, $r1
53 or.d $r3, $r1
54 move.d $r1, [$r0]
55 cmp.d sdram_commands_end, $r2
56 blo command_loop
57 nop
58
59 ; Set timing
60 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing), $r0
61 move.d CONFIG_ETRAX_DDR2_TIMING, $r1
62 move.d $r1, [$r0]
63
64 ; Set latency
65 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_latency), $r0
66 move.d 0x13, $r1
67 move.d $r1, [$r0]
68
69 ; Set configuration
70 move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg), $r0
71 move.d CONFIG_ETRAX_DDR2_CONFIG, $r1
72 move.d $r1, [$r0]
73
74 ba after_sdram_commands
75 nop
76
77sdram_commands_start:
78 .byte regk_ddr2_deselect
79 .word 0
80 .byte regk_ddr2_pre
81 .word regk_ddr2_pre_all
82 .byte regk_ddr2_emrs2
83 .word 0
84 .byte regk_ddr2_emrs3
85 .word 0
86 .byte regk_ddr2_emrs
87 .word regk_ddr2_dll_en
88 .byte regk_ddr2_mrs
89 .word regk_ddr2_dll_rst
90 .byte regk_ddr2_pre
91 .word regk_ddr2_pre_all
92 .byte regk_ddr2_ref
93 .word 0
94 .byte regk_ddr2_ref
95 .word 0
96 .byte regk_ddr2_mrs
97 .word CONFIG_ETRAX_DDR2_MRS & 0xffff
98 .byte regk_ddr2_emrs
99 .word regk_ddr2_ocd_default | regk_ddr2_dll_en
100 .byte regk_ddr2_emrs
101 .word regk_ddr2_ocd_exit | regk_ddr2_dll_en | (CONFIG_ETRAX_DDR2_MRS >> 16)
102sdram_commands_end:
103 .align 1
104after_sdram_commands:
diff --git a/arch/cris/arch-v32/mach-a3/hw_settings.S b/arch/cris/arch-v32/mach-a3/hw_settings.S
new file mode 100644
index 000000000000..258a6329cd4a
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/hw_settings.S
@@ -0,0 +1,51 @@
1/*
2 * This table is used by some tools to extract hardware parameters.
3 * The table should be included in the kernel and the decompressor.
4 * Don't forget to update the tools if you change this table.
5 *
6 * Copyright (C) 2001-2007 Axis Communications AB
7 *
8 * Authors: Mikael Starvik <starvik@axis.com>
9 */
10
11#include <hwregs/asm/reg_map_asm.h>
12#include <hwregs/asm/ddr2_defs_asm.h>
13#include <hwregs/asm/gio_defs_asm.h>
14
15 .ascii "HW_PARAM_MAGIC" ; Magic number
16 .dword 0xc0004000 ; Kernel start address
17
18 ; Debug port
19#ifdef CONFIG_ETRAX_DEBUG_PORT0
20 .dword 0
21#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
22 .dword 1
23#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
24 .dword 2
25#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
26 .dword 3
27#else
28 .dword 4 ; No debug
29#endif
30
31 ; Register values
32 .dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg)
33 .dword CONFIG_ETRAX_DDR2_CONFIG
34 .dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing)
35 .dword CONFIG_ETRAX_DDR2_TIMING
36 .dword CONFIG_ETRAX_DDR2_MRS
37
38 .dword REG_ADDR(gio, regi_gio, rw_pa_dout)
39 .dword CONFIG_ETRAX_DEF_GIO_PA_OUT
40 .dword REG_ADDR(gio, regi_gio, rw_pa_oe)
41 .dword CONFIG_ETRAX_DEF_GIO_PA_OE
42 .dword REG_ADDR(gio, regi_gio, rw_pb_dout)
43 .dword CONFIG_ETRAX_DEF_GIO_PB_OUT
44 .dword REG_ADDR(gio, regi_gio, rw_pb_oe)
45 .dword CONFIG_ETRAX_DEF_GIO_PB_OE
46 .dword REG_ADDR(gio, regi_gio, rw_pc_dout)
47 .dword CONFIG_ETRAX_DEF_GIO_PC_OUT
48 .dword REG_ADDR(gio, regi_gio, rw_pc_oe)
49 .dword CONFIG_ETRAX_DEF_GIO_PC_OE
50
51 .dword 0 ; No more register values
diff --git a/arch/cris/arch-v32/mach-a3/io.c b/arch/cris/arch-v32/mach-a3/io.c
new file mode 100644
index 000000000000..9eeaf3eca474
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/io.c
@@ -0,0 +1,149 @@
1/*
2 * Helper functions for I/O pins.
3 *
4 * Copyright (c) 2005-2007 Axis Communications AB.
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9#include <linux/init.h>
10#include <linux/string.h>
11#include <linux/ctype.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/io.h>
15#include <asm/arch/mach/pinmux.h>
16#include <hwregs/gio_defs.h>
17
18struct crisv32_ioport crisv32_ioports[] = {
19 {
20 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
21 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
22 (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
23 32
24 },
25 {
26 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
27 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
28 (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
29 32
30 },
31 {
32 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
33 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
34 (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
35 16
36 },
37};
38
39#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
40
41struct crisv32_iopin crisv32_led_net0_green;
42struct crisv32_iopin crisv32_led_net0_red;
43struct crisv32_iopin crisv32_led2_green;
44struct crisv32_iopin crisv32_led2_red;
45struct crisv32_iopin crisv32_led3_green;
46struct crisv32_iopin crisv32_led3_red;
47
48/* Dummy port used when green LED and red LED is on the same bit */
49static unsigned long io_dummy;
50static struct crisv32_ioport dummy_port = {
51 &io_dummy,
52 &io_dummy,
53 &io_dummy,
54 32
55};
56static struct crisv32_iopin dummy_led = {
57 &dummy_port,
58 0
59};
60
61static int __init crisv32_io_init(void)
62{
63 int ret = 0;
64
65 u32 i;
66
67 /* Locks *should* be dynamically initialized. */
68 for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
69 spin_lock_init(&crisv32_ioports[i].lock);
70 spin_lock_init(&dummy_port.lock);
71
72 /* Initialize LEDs */
73#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
74 ret += crisv32_io_get_name(&crisv32_led_net0_green,
75 CONFIG_ETRAX_LED_G_NET0);
76 crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
77 if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
78 ret += crisv32_io_get_name(&crisv32_led_net0_red,
79 CONFIG_ETRAX_LED_R_NET0);
80 crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
81 } else
82 crisv32_led_net0_red = dummy_led;
83#endif
84
85 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
86 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
87 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
88 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);
89
90 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
91 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
92 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
93 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
94
95 return ret;
96}
97
98__initcall(crisv32_io_init);
99
100int crisv32_io_get(struct crisv32_iopin *iopin,
101 unsigned int port, unsigned int pin)
102{
103 if (port > NBR_OF_PORTS)
104 return -EINVAL;
105 if (port > crisv32_ioports[port].pin_count)
106 return -EINVAL;
107
108 iopin->bit = 1 << pin;
109 iopin->port = &crisv32_ioports[port];
110
111 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
112 return -EIO;
113
114 return 0;
115}
116
117int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
118{
119 int port;
120 int pin;
121
122 if (toupper(*name) == 'P')
123 name++;
124
125 if (toupper(*name) < 'A' || toupper(*name) > 'E')
126 return -EINVAL;
127
128 port = toupper(*name) - 'A';
129 name++;
130 pin = simple_strtoul(name, NULL, 10);
131
132 if (pin < 0 || pin > crisv32_ioports[port].pin_count)
133 return -EINVAL;
134
135 iopin->bit = 1 << pin;
136 iopin->port = &crisv32_ioports[port];
137
138 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
139 return -EIO;
140
141 return 0;
142}
143
144#ifdef CONFIG_PCI
145/* PCI I/O access stuff */
146struct cris_io_operations *cris_iops = NULL;
147EXPORT_SYMBOL(cris_iops);
148#endif
149
diff --git a/arch/cris/arch-v32/mach-a3/pinmux.c b/arch/cris/arch-v32/mach-a3/pinmux.c
new file mode 100644
index 000000000000..0a28c9bedfb7
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/pinmux.c
@@ -0,0 +1,386 @@
1/*
2 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
3 * Unassigned pins and GPIO pins can be allocated to a fixed interface
4 * or the I/O processor instead.
5 *
6 * Copyright (c) 2005-2007 Axis Communications AB.
7 */
8
9#include <linux/init.h>
10#include <linux/errno.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/spinlock.h>
14#include <hwregs/reg_map.h>
15#include <hwregs/reg_rdwr.h>
16#include <pinmux.h>
17#include <hwregs/pinmux_defs.h>
18#include <hwregs/clkgen_defs.h>
19
20#undef DEBUG
21
22#define PINS 80
23#define PORT_PINS 32
24#define PORTS 3
25
26static char pins[PINS];
27static DEFINE_SPINLOCK(pinmux_lock);
28
29static void crisv32_pinmux_set(int port);
30
31int
32crisv32_pinmux_init(void)
33{
34 static int initialized;
35
36 if (!initialized) {
37 initialized = 1;
38 REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
39 crisv32_pinmux_alloc(PORT_A, 0, 31, pinmux_gpio);
40 crisv32_pinmux_alloc(PORT_B, 0, 31, pinmux_gpio);
41 crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_gpio);
42 }
43
44 return 0;
45}
46
47int
48crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
49{
50 int i;
51 unsigned long flags;
52
53 crisv32_pinmux_init();
54
55 if (port >= PORTS)
56 return -EINVAL;
57
58 spin_lock_irqsave(&pinmux_lock, flags);
59
60 for (i = first_pin; i <= last_pin; i++) {
61 if ((pins[port * PORT_PINS + i] != pinmux_none) &&
62 (pins[port * PORT_PINS + i] != pinmux_gpio) &&
63 (pins[port * PORT_PINS + i] != mode)) {
64 spin_unlock_irqrestore(&pinmux_lock, flags);
65#ifdef DEBUG
66 panic("Pinmux alloc failed!\n");
67#endif
68 return -EPERM;
69 }
70 }
71
72 for (i = first_pin; i <= last_pin; i++)
73 pins[port * PORT_PINS + i] = mode;
74
75 crisv32_pinmux_set(port);
76
77 spin_unlock_irqrestore(&pinmux_lock, flags);
78
79 return 0;
80}
81
82int
83crisv32_pinmux_alloc_fixed(enum fixed_function function)
84{
85 int ret = -EINVAL;
86 char saved[sizeof pins];
87 unsigned long flags;
88
89 spin_lock_irqsave(&pinmux_lock, flags);
90
91 /* Save internal data for recovery */
92 memcpy(saved, pins, sizeof pins);
93
94 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */
95
96 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
97 reg_clkgen_rw_clk_ctrl clk_ctrl = REG_RD(clkgen, regi_clkgen,
98 rw_clk_ctrl);
99
100 switch (function) {
101 case pinmux_eth:
102 clk_ctrl.eth = regk_clkgen_yes;
103 clk_ctrl.dma0_1_eth = regk_clkgen_yes;
104 ret = crisv32_pinmux_alloc(PORT_B, 8, 23, pinmux_fixed);
105 ret |= crisv32_pinmux_alloc(PORT_B, 24, 25, pinmux_fixed);
106 hwprot.eth = hwprot.eth_mdio = regk_pinmux_yes;
107 break;
108 case pinmux_geth:
109 ret = crisv32_pinmux_alloc(PORT_B, 0, 7, pinmux_fixed);
110 hwprot.geth = regk_pinmux_yes;
111 break;
112 case pinmux_tg_cmos:
113 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes;
114 ret = crisv32_pinmux_alloc(PORT_B, 27, 29, pinmux_fixed);
115 hwprot.tg_clk = regk_pinmux_yes;
116 break;
117 case pinmux_tg_ccd:
118 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes;
119 ret = crisv32_pinmux_alloc(PORT_B, 27, 31, pinmux_fixed);
120 ret |= crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_fixed);
121 hwprot.tg = hwprot.tg_clk = regk_pinmux_yes;
122 break;
123 case pinmux_vout:
124 clk_ctrl.strdma0_2_video = regk_clkgen_yes;
125 ret = crisv32_pinmux_alloc(PORT_A, 8, 18, pinmux_fixed);
126 hwprot.vout = hwprot.vout_sync = regk_pinmux_yes;
127 break;
128 case pinmux_ser1:
129 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
130 ret = crisv32_pinmux_alloc(PORT_A, 24, 25, pinmux_fixed);
131 hwprot.ser1 = regk_pinmux_yes;
132 break;
133 case pinmux_ser2:
134 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
135 ret = crisv32_pinmux_alloc(PORT_A, 26, 27, pinmux_fixed);
136 hwprot.ser2 = regk_pinmux_yes;
137 break;
138 case pinmux_ser3:
139 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
140 ret = crisv32_pinmux_alloc(PORT_A, 28, 29, pinmux_fixed);
141 hwprot.ser3 = regk_pinmux_yes;
142 break;
143 case pinmux_ser4:
144 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
145 ret = crisv32_pinmux_alloc(PORT_A, 30, 31, pinmux_fixed);
146 hwprot.ser4 = regk_pinmux_yes;
147 break;
148 case pinmux_sser:
149 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
150 ret = crisv32_pinmux_alloc(PORT_A, 19, 23, pinmux_fixed);
151 hwprot.sser = regk_pinmux_yes;
152 break;
153 case pinmux_pio:
154 hwprot.pio = regk_pinmux_yes;
155 ret = 0;
156 break;
157 case pinmux_pwm0:
158 ret = crisv32_pinmux_alloc(PORT_A, 30, 30, pinmux_fixed);
159 hwprot.pwm0 = regk_pinmux_yes;
160 break;
161 case pinmux_pwm1:
162 ret = crisv32_pinmux_alloc(PORT_A, 31, 31, pinmux_fixed);
163 hwprot.pwm1 = regk_pinmux_yes;
164 break;
165 case pinmux_pwm2:
166 ret = crisv32_pinmux_alloc(PORT_B, 26, 26, pinmux_fixed);
167 hwprot.pwm2 = regk_pinmux_yes;
168 break;
169 case pinmux_i2c0:
170 ret = crisv32_pinmux_alloc(PORT_A, 0, 1, pinmux_fixed);
171 hwprot.i2c0 = regk_pinmux_yes;
172 break;
173 case pinmux_i2c1:
174 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
175 hwprot.i2c1 = regk_pinmux_yes;
176 break;
177 case pinmux_i2c1_3wire:
178 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
179 ret |= crisv32_pinmux_alloc(PORT_A, 7, 7, pinmux_fixed);
180 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes;
181 break;
182 case pinmux_i2c1_sda1:
183 ret = crisv32_pinmux_alloc(PORT_A, 2, 4, pinmux_fixed);
184 hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes;
185 break;
186 case pinmux_i2c1_sda2:
187 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
188 ret |= crisv32_pinmux_alloc(PORT_A, 5, 5, pinmux_fixed);
189 hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes;
190 break;
191 case pinmux_i2c1_sda3:
192 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
193 ret |= crisv32_pinmux_alloc(PORT_A, 6, 6, pinmux_fixed);
194 hwprot.i2c1 = hwprot.i2c1_sda3 = regk_pinmux_yes;
195 break;
196 default:
197 ret = -EINVAL;
198 break;
199 }
200
201 if (!ret) {
202 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
203 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
204 } else
205 memcpy(pins, saved, sizeof pins);
206
207 spin_unlock_irqrestore(&pinmux_lock, flags);
208
209 return ret;
210}
211
212void
213crisv32_pinmux_set(int port)
214{
215 int i;
216 int gpio_val = 0;
217 int iop_val = 0;
218 int pin = port * PORT_PINS;
219
220 for (i = 0; (i < PORT_PINS) && (pin < PINS); i++, pin++) {
221 if (pins[pin] == pinmux_gpio)
222 gpio_val |= (1 << i);
223 else if (pins[pin] == pinmux_iop)
224 iop_val |= (1 << i);
225 }
226
227 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_gio_pa + 4 * port,
228 gpio_val);
229 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_iop_pa + 4 * port,
230 iop_val);
231
232#ifdef DEBUG
233 crisv32_pinmux_dump();
234#endif
235}
236
237int
238crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
239{
240 int i;
241 unsigned long flags;
242
243 crisv32_pinmux_init();
244
245 if (port > PORTS)
246 return -EINVAL;
247
248 spin_lock_irqsave(&pinmux_lock, flags);
249
250 for (i = first_pin; i <= last_pin; i++)
251 pins[port * PORT_PINS + i] = pinmux_none;
252
253 crisv32_pinmux_set(port);
254 spin_unlock_irqrestore(&pinmux_lock, flags);
255
256 return 0;
257}
258
259int
260crisv32_pinmux_dealloc_fixed(enum fixed_function function)
261{
262 int ret = -EINVAL;
263 char saved[sizeof pins];
264 unsigned long flags;
265
266 spin_lock_irqsave(&pinmux_lock, flags);
267
268 /* Save internal data for recovery */
269 memcpy(saved, pins, sizeof pins);
270
271 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */
272
273 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
274
275 switch (function) {
276 case pinmux_eth:
277 ret = crisv32_pinmux_dealloc(PORT_B, 8, 23);
278 ret |= crisv32_pinmux_dealloc(PORT_B, 24, 25);
279 ret |= crisv32_pinmux_dealloc(PORT_B, 0, 7);
280 hwprot.eth = hwprot.eth_mdio = hwprot.geth = regk_pinmux_no;
281 break;
282 case pinmux_tg_cmos:
283 ret = crisv32_pinmux_dealloc(PORT_B, 27, 29);
284 hwprot.tg_clk = regk_pinmux_no;
285 break;
286 case pinmux_tg_ccd:
287 ret = crisv32_pinmux_dealloc(PORT_B, 27, 31);
288 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 15);
289 hwprot.tg = hwprot.tg_clk = regk_pinmux_no;
290 break;
291 case pinmux_vout:
292 ret = crisv32_pinmux_dealloc(PORT_A, 8, 18);
293 hwprot.vout = hwprot.vout_sync = regk_pinmux_no;
294 break;
295 case pinmux_ser1:
296 ret = crisv32_pinmux_dealloc(PORT_A, 24, 25);
297 hwprot.ser1 = regk_pinmux_no;
298 break;
299 case pinmux_ser2:
300 ret = crisv32_pinmux_dealloc(PORT_A, 26, 27);
301 hwprot.ser2 = regk_pinmux_no;
302 break;
303 case pinmux_ser3:
304 ret = crisv32_pinmux_dealloc(PORT_A, 28, 29);
305 hwprot.ser3 = regk_pinmux_no;
306 break;
307 case pinmux_ser4:
308 ret = crisv32_pinmux_dealloc(PORT_A, 30, 31);
309 hwprot.ser4 = regk_pinmux_no;
310 break;
311 case pinmux_sser:
312 ret = crisv32_pinmux_dealloc(PORT_A, 19, 23);
313 hwprot.sser = regk_pinmux_no;
314 break;
315 case pinmux_pwm0:
316 ret = crisv32_pinmux_dealloc(PORT_A, 30, 30);
317 hwprot.pwm0 = regk_pinmux_no;
318 break;
319 case pinmux_pwm1:
320 ret = crisv32_pinmux_dealloc(PORT_A, 31, 31);
321 hwprot.pwm1 = regk_pinmux_no;
322 break;
323 case pinmux_pwm2:
324 ret = crisv32_pinmux_dealloc(PORT_B, 26, 26);
325 hwprot.pwm2 = regk_pinmux_no;
326 break;
327 case pinmux_i2c0:
328 ret = crisv32_pinmux_dealloc(PORT_A, 0, 1);
329 hwprot.i2c0 = regk_pinmux_no;
330 break;
331 case pinmux_i2c1:
332 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
333 hwprot.i2c1 = regk_pinmux_no;
334 break;
335 case pinmux_i2c1_3wire:
336 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
337 ret |= crisv32_pinmux_dealloc(PORT_A, 7, 7);
338 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_no;
339 break;
340 case pinmux_i2c1_sda1:
341 ret = crisv32_pinmux_dealloc(PORT_A, 2, 4);
342 hwprot.i2c1_sda1 = regk_pinmux_no;
343 break;
344 case pinmux_i2c1_sda2:
345 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
346 ret |= crisv32_pinmux_dealloc(PORT_A, 5, 5);
347 hwprot.i2c1_sda2 = regk_pinmux_no;
348 break;
349 case pinmux_i2c1_sda3:
350 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
351 ret |= crisv32_pinmux_dealloc(PORT_A, 6, 6);
352 hwprot.i2c1_sda3 = regk_pinmux_no;
353 break;
354 default:
355 ret = -EINVAL;
356 break;
357 }
358
359 if (!ret)
360 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
361 else
362 memcpy(pins, saved, sizeof pins);
363
364 spin_unlock_irqrestore(&pinmux_lock, flags);
365
366 return ret;
367}
368
369void
370crisv32_pinmux_dump(void)
371{
372 int i, j;
373 int pin = 0;
374
375 crisv32_pinmux_init();
376
377 for (i = 0; i < PORTS; i++) {
378 pin++;
379 printk(KERN_DEBUG "Port %c\n", 'A'+i);
380 for (j = 0; (j < PORT_PINS) && (pin < PINS); j++, pin++)
381 printk(KERN_DEBUG
382 " Pin %d = %d\n", j, pins[i * PORT_PINS + j]);
383 }
384}
385
386__initcall(crisv32_pinmux_init);
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.c b/arch/cris/arch-v32/mach-a3/vcs_hook.c
new file mode 100644
index 000000000000..58b1a5469fd7
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/vcs_hook.c
@@ -0,0 +1,103 @@
1/*
2 * Simulator hook mechanism
3 */
4
5#include "vcs_hook.h"
6#include <asm/io.h>
7#include <stdarg.h>
8
9#define HOOK_TRIG_ADDR 0xb7000000
10#define HOOK_MEM_BASE_ADDR 0xce000000
11
12static volatile unsigned *hook_base;
13
14#define HOOK_DATA(offset) hook_base[offset]
15#define VHOOK_DATA(offset) hook_base[offset]
16#define HOOK_TRIG(funcid) \
17 do { \
18 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19 } while (0)
20#define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset]
21
22static void hook_init(void)
23{
24 static int first = 1;
25 if (first) {
26 first = 0;
27 hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192);
28 }
29}
30
31static unsigned hook_trig(unsigned id)
32{
33 unsigned ret;
34
35 /* preempt_disable(); */
36
37 /* Dummy read from mem to make sure data has propagated to memory
38 * before trigging */
39 ret = *hook_base;
40
41 /* trigger hook */
42 HOOK_TRIG(id);
43
44 /* wait for call to finish */
45 while (VHOOK_DATA(0) > 0) ;
46
47 /* extract return value */
48
49 ret = VHOOK_DATA(1);
50
51 return ret;
52}
53
54int hook_call(unsigned id, unsigned pcnt, ...)
55{
56 va_list ap;
57 int i;
58 unsigned ret;
59
60 hook_init();
61
62 HOOK_DATA(0) = id;
63
64 va_start(ap, pcnt);
65 for (i = 1; i <= pcnt; i++)
66 HOOK_DATA(i) = va_arg(ap, unsigned);
67 va_end(ap);
68
69 ret = hook_trig(id);
70
71 return ret;
72}
73
74int hook_call_str(unsigned id, unsigned size, const char *str)
75{
76 int i;
77 unsigned ret;
78
79 hook_init();
80
81 HOOK_DATA(0) = id;
82 HOOK_DATA(1) = size;
83
84 for (i = 0; i < size; i++)
85 HOOK_DATA_BYTE(8 + i) = str[i];
86 HOOK_DATA_BYTE(8 + i) = 0;
87
88 ret = hook_trig(id);
89
90 return ret;
91}
92
93void print_str(const char *str)
94{
95 int i;
96 /* find null at end of string */
97 for (i = 1; str[i]; i++) ;
98 hook_call(hook_print_str, i, str);
99}
100
101void CPU_WATCHDOG_TIMEOUT(unsigned t)
102{
103}
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.h b/arch/cris/arch-v32/mach-a3/vcs_hook.h
new file mode 100644
index 000000000000..8b73d0e8392d
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/vcs_hook.h
@@ -0,0 +1,58 @@
1/*
2 * Simulator hook call mechanism
3 */
4
5#ifndef __hook_h__
6#define __hook_h__
7
8int hook_call(unsigned id, unsigned pcnt, ...);
9int hook_call_str(unsigned id, unsigned size, const char *str);
10
11enum hook_ids {
12 hook_debug_on = 1,
13 hook_debug_off,
14 hook_stop_sim_ok,
15 hook_stop_sim_fail,
16 hook_alloc_shared,
17 hook_ptr_shared,
18 hook_free_shared,
19 hook_file2shared,
20 hook_cmp_shared,
21 hook_print_params,
22 hook_sim_time,
23 hook_stop_sim,
24 hook_kick_dog,
25 hook_dog_timeout,
26 hook_rand,
27 hook_srand,
28 hook_rand_range,
29 hook_print_str,
30 hook_print_hex,
31 hook_cmp_offset_shared,
32 hook_fill_random_shared,
33 hook_alloc_random_data,
34 hook_calloc_random_data,
35 hook_print_int,
36 hook_print_uint,
37 hook_fputc,
38 hook_init_fd,
39 hook_sbrk,
40 hook_print_context_descr,
41 hook_print_data_descr,
42 hook_print_group_descr,
43 hook_fill_shared,
44 hook_sl_srand,
45 hook_sl_rand_irange,
46 hook_sl_rand_urange,
47 hook_sl_sh_malloc_aligned,
48 hook_sl_sh_calloc_aligned,
49 hook_sl_sh_alloc_random_data,
50 hook_sl_sh_file2mem,
51 hook_sl_vera_mbox_handle,
52 hook_sl_vera_mbox_put,
53 hook_sl_vera_mbox_get,
54 hook_sl_system,
55 hook_sl_sh_hexdump
56};
57
58#endif
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
new file mode 100644
index 000000000000..f6d74475f1c6
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -0,0 +1,216 @@
1if ETRAXFS
2
3menu "ETRAX FS options"
4 depends on ETRAXFS
5
6config ETRAX_DRAM_VIRTUAL_BASE
7 hex
8 depends on ETRAX_ARCH_V32
9 default "c0000000"
10
11config ETRAX_SERIAL_PORTS
12 int
13 default 4
14
15config ETRAX_MEM_GRP1_CONFIG
16 hex "MEM_GRP1_CONFIG"
17 depends on ETRAX_ARCH_V32
18 default "4044a"
19 help
20 Waitstates for flash. The default value is suitable for the
21 standard flashes used in axis products (120 ns).
22
23config ETRAX_MEM_GRP2_CONFIG
24 hex "MEM_GRP2_CONFIG"
25 depends on ETRAX_ARCH_V32
26 default "0"
27 help
28 Waitstates for SRAM. 0 is a good choice for most Axis products.
29
30config ETRAX_MEM_GRP3_CONFIG
31 hex "MEM_GRP3_CONFIG"
32 depends on ETRAX_ARCH_V32
33 default "0"
34 help
35 Waitstates for CSP0-3. 0 is a good choice for most Axis products.
36 It may need to be changed if external devices such as extra
37 register-mapped LEDs are used.
38
39config ETRAX_MEM_GRP4_CONFIG
40 hex "MEM_GRP4_CONFIG"
41 depends on ETRAX_ARCH_V32
42 default "0"
43 help
44 Waitstates for CSP4-6. 0 is a good choice for most Axis products.
45
46config ETRAX_SDRAM_GRP0_CONFIG
47 hex "SDRAM_GRP0_CONFIG"
48 depends on ETRAX_ARCH_V32
49 default "336"
50 help
51 SDRAM configuration for group 0. The value depends on the
52 hardware configuration. The default value is suitable
53 for 32 MB organized as two 16 bits chips (e.g. Axis
54 part number 18550) connected as one 32 bit device (i.e. in
55 the same group).
56
57config ETRAX_SDRAM_GRP1_CONFIG
58 hex "SDRAM_GRP1_CONFIG"
59 depends on ETRAX_ARCH_V32
60 default "0"
61 help
62 SDRAM configuration for group 1. The defult value is 0
63 because group 1 is not used in the default configuration,
64 described in the help for SDRAM_GRP0_CONFIG.
65
66config ETRAX_SDRAM_TIMING
67 hex "SDRAM_TIMING"
68 depends on ETRAX_ARCH_V32
69 default "104a"
70 help
71 SDRAM timing parameters. The default value is ok for
72 most hardwares but large SDRAMs may require a faster
73 refresh (a.k.a 8K refresh). The default value implies
74 100MHz clock and SDR mode.
75
76config ETRAX_SDRAM_COMMAND
77 hex "SDRAM_COMMAND"
78 depends on ETRAX_ARCH_V32
79 default "0"
80 help
81 SDRAM command. Should be 0 unless you really know what
82 you are doing (may be != 0 for unusual address line
83 mappings such as in a MCM)..
84
85config ETRAX_DEF_GIO_PA_OE
86 hex "GIO_PA_OE"
87 depends on ETRAX_ARCH_V32
88 default "1c"
89 help
90 Configures the direction of general port A bits. 1 is out, 0 is in.
91 This is often totally different depending on the product used.
92 There are some guidelines though - if you know that only LED's are
93 connected to port PA, then they are usually connected to bits 2-4
94 and you can therefore use 1c. On other boards which don't have the
95 LED's at the general ports, these bits are used for all kinds of
96 stuff. If you don't know what to use, it is always safe to put all
97 as inputs, although floating inputs isn't good.
98
99config ETRAX_DEF_GIO_PA_OUT
100 hex "GIO_PA_OUT"
101 depends on ETRAX_ARCH_V32
102 default "00"
103 help
104 Configures the initial data for the general port A bits. Most
105 products should use 00 here.
106
107config ETRAX_DEF_GIO_PB_OE
108 hex "GIO_PB_OE"
109 depends on ETRAX_ARCH_V32
110 default "00000"
111 help
112 Configures the direction of general port B bits. 1 is out, 0 is in.
113 This is often totally different depending on the product used.
114 There are some guidelines though - if you know that only LED's are
115 connected to port PA, then they are usually connected to bits 2-4
116 and you can therefore use 1c. On other boards which don't have the
117 LED's at the general ports, these bits are used for all kinds of
118 stuff. If you don't know what to use, it is always safe to put all
119 as inputs, although floating inputs isn't good.
120
121config ETRAX_DEF_GIO_PB_OUT
122 hex "GIO_PB_OUT"
123 depends on ETRAX_ARCH_V32
124 default "00000"
125 help
126 Configures the initial data for the general port B bits. Most
127 products should use 00000 here.
128
129config ETRAX_DEF_GIO_PC_OE
130 hex "GIO_PC_OE"
131 depends on ETRAX_ARCH_V32
132 default "00000"
133 help
134 Configures the direction of general port C bits. 1 is out, 0 is in.
135 This is often totally different depending on the product used.
136 There are some guidelines though - if you know that only LED's are
137 connected to port PA, then they are usually connected to bits 2-4
138 and you can therefore use 1c. On other boards which don't have the
139 LED's at the general ports, these bits are used for all kinds of
140 stuff. If you don't know what to use, it is always safe to put all
141 as inputs, although floating inputs isn't good.
142
143config ETRAX_DEF_GIO_PC_OUT
144 hex "GIO_PC_OUT"
145 depends on ETRAX_ARCH_V32
146 default "00000"
147 help
148 Configures the initial data for the general port C bits. Most
149 products should use 00000 here.
150
151config ETRAX_DEF_GIO_PD_OE
152 hex "GIO_PD_OE"
153 depends on ETRAX_ARCH_V32
154 default "00000"
155 help
156 Configures the direction of general port D bits. 1 is out, 0 is in.
157 This is often totally different depending on the product used.
158 There are some guidelines though - if you know that only LED's are
159 connected to port PA, then they are usually connected to bits 2-4
160 and you can therefore use 1c. On other boards which don't have the
161 LED's at the general ports, these bits are used for all kinds of
162 stuff. If you don't know what to use, it is always safe to put all
163 as inputs, although floating inputs isn't good.
164
165config ETRAX_DEF_GIO_PD_OUT
166 hex "GIO_PD_OUT"
167 depends on ETRAX_ARCH_V32
168 default "00000"
169 help
170 Configures the initial data for the general port D bits. Most
171 products should use 00000 here.
172
173config ETRAX_DEF_GIO_PE_OE
174 hex "GIO_PE_OE"
175 depends on ETRAX_ARCH_V32
176 default "00000"
177 help
178 Configures the direction of general port E bits. 1 is out, 0 is in.
179 This is often totally different depending on the product used.
180 There are some guidelines though - if you know that only LED's are
181 connected to port PA, then they are usually connected to bits 2-4
182 and you can therefore use 1c. On other boards which don't have the
183 LED's at the general ports, these bits are used for all kinds of
184 stuff. If you don't know what to use, it is always safe to put all
185 as inputs, although floating inputs isn't good.
186
187config ETRAX_DEF_GIO_PE_OUT
188 hex "GIO_PE_OUT"
189 depends on ETRAX_ARCH_V32
190 default "00000"
191 help
192 Configures the initial data for the general port E bits. Most
193 products should use 00000 here.
194
195config ETRAX_DEF_GIO_PV_OE
196 hex "GIO_PV_OE"
197 depends on ETRAX_VIRTUAL_GPIO
198 default "0000"
199 help
200 Configures the direction of virtual general port V bits. 1 is out,
201 0 is in. This is often totally different depending on the product
202 used. These bits are used for all kinds of stuff. If you don't know
203 what to use, it is always safe to put all as inputs, although
204 floating inputs isn't good.
205
206config ETRAX_DEF_GIO_PV_OUT
207 hex "GIO_PV_OUT"
208 depends on ETRAX_VIRTUAL_GPIO
209 default "0000"
210 help
211 Configures the initial data for the virtual general port V bits.
212 Most products should use 0000 here.
213
214endmenu
215
216endif
diff --git a/arch/cris/arch-v32/mach-fs/Makefile b/arch/cris/arch-v32/mach-fs/Makefile
new file mode 100644
index 000000000000..4ff407a1b931
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/Makefile
@@ -0,0 +1,11 @@
1# $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $
2#
3# Makefile for the linux kernel.
4#
5
6obj-y := dma.o pinmux.o io.o arbiter.o
7bj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
8obj-$(CONFIG_CPU_FREQ) += cpufreq.o
9
10clean:
11
diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c
new file mode 100644
index 000000000000..84d31bd7b692
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/arbiter.c
@@ -0,0 +1,404 @@
1/*
2 * Memory arbiter functions. Allocates bandwidth through the
3 * arbiter and sets up arbiter breakpoints.
4 *
5 * The algorithm first assigns slots to the clients that has specified
6 * bandwidth (e.g. ethernet) and then the remaining slots are divided
7 * on all the active clients.
8 *
9 * Copyright (c) 2004-2007 Axis Communications AB.
10 */
11
12#include <hwregs/reg_map.h>
13#include <hwregs/reg_rdwr.h>
14#include <hwregs/marb_defs.h>
15#include <arbiter.h>
16#include <hwregs/intr_vect.h>
17#include <linux/interrupt.h>
18#include <linux/signal.h>
19#include <linux/errno.h>
20#include <linux/spinlock.h>
21#include <asm/io.h>
22#include <asm/irq_regs.h>
23
24struct crisv32_watch_entry {
25 unsigned long instance;
26 watch_callback *cb;
27 unsigned long start;
28 unsigned long end;
29 int used;
30};
31
32#define NUMBER_OF_BP 4
33#define NBR_OF_CLIENTS 14
34#define NBR_OF_SLOTS 64
35#define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */
36#define INTMEM_BANDWIDTH 400000000
37#define NBR_OF_REGIONS 2
38
39static struct crisv32_watch_entry watches[NUMBER_OF_BP] = {
40 {regi_marb_bp0},
41 {regi_marb_bp1},
42 {regi_marb_bp2},
43 {regi_marb_bp3}
44};
45
46static u8 requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
47static u8 active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
48static int max_bandwidth[NBR_OF_REGIONS] =
49 { SDRAM_BANDWIDTH, INTMEM_BANDWIDTH };
50
51DEFINE_SPINLOCK(arbiter_lock);
52
53static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id);
54
55/*
56 * "I'm the arbiter, I know the score.
57 * From square one I'll be watching all 64."
58 * (memory arbiter slots, that is)
59 *
60 * Or in other words:
61 * Program the memory arbiter slots for "region" according to what's
62 * in requested_slots[] and active_clients[], while minimizing
63 * latency. A caller may pass a non-zero positive amount for
64 * "unused_slots", which must then be the unallocated, remaining
65 * number of slots, free to hand out to any client.
66 */
67
68static void crisv32_arbiter_config(int region, int unused_slots)
69{
70 int slot;
71 int client;
72 int interval = 0;
73
74 /*
75 * This vector corresponds to the hardware arbiter slots (see
76 * the hardware documentation for semantics). We initialize
77 * each slot with a suitable sentinel value outside the valid
78 * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
79 * client indexes. Then it's fed to the hardware.
80 */
81 s8 val[NBR_OF_SLOTS];
82
83 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
84 val[slot] = -1;
85
86 for (client = 0; client < NBR_OF_CLIENTS; client++) {
87 int pos;
88 /* Allocate the requested non-zero number of slots, but
89 * also give clients with zero-requests one slot each
90 * while stocks last. We do the latter here, in client
91 * order. This makes sure zero-request clients are the
92 * first to get to any spare slots, else those slots
93 * could, when bandwidth is allocated close to the limit,
94 * all be allocated to low-index non-zero-request clients
95 * in the default-fill loop below. Another positive but
96 * secondary effect is a somewhat better spread of the
97 * zero-bandwidth clients in the vector, avoiding some of
98 * the latency that could otherwise be caused by the
99 * partitioning of non-zero-bandwidth clients at low
100 * indexes and zero-bandwidth clients at high
101 * indexes. (Note that this spreading can only affect the
102 * unallocated bandwidth.) All the above only matters for
103 * memory-intensive situations, of course.
104 */
105 if (!requested_slots[region][client]) {
106 /*
107 * Skip inactive clients. Also skip zero-slot
108 * allocations in this pass when there are no known
109 * free slots.
110 */
111 if (!active_clients[region][client]
112 || unused_slots <= 0)
113 continue;
114
115 unused_slots--;
116
117 /* Only allocate one slot for this client. */
118 interval = NBR_OF_SLOTS;
119 } else
120 interval =
121 NBR_OF_SLOTS / requested_slots[region][client];
122
123 pos = 0;
124 while (pos < NBR_OF_SLOTS) {
125 if (val[pos] >= 0)
126 pos++;
127 else {
128 val[pos] = client;
129 pos += interval;
130 }
131 }
132 }
133
134 client = 0;
135 for (slot = 0; slot < NBR_OF_SLOTS; slot++) {
136 /*
137 * Allocate remaining slots in round-robin
138 * client-number order for active clients. For this
139 * pass, we ignore requested bandwidth and previous
140 * allocations.
141 */
142 if (val[slot] < 0) {
143 int first = client;
144 while (!active_clients[region][client]) {
145 client = (client + 1) % NBR_OF_CLIENTS;
146 if (client == first)
147 break;
148 }
149 val[slot] = client;
150 client = (client + 1) % NBR_OF_CLIENTS;
151 }
152 if (region == EXT_REGION)
153 REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot,
154 val[slot]);
155 else if (region == INT_REGION)
156 REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot,
157 val[slot]);
158 }
159}
160
161extern char _stext, _etext;
162
163static void crisv32_arbiter_init(void)
164{
165 static int initialized;
166
167 if (initialized)
168 return;
169
170 initialized = 1;
171
172 /*
173 * CPU caches are always set to active, but with zero
174 * bandwidth allocated. It should be ok to allocate zero
175 * bandwidth for the caches, because DMA for other channels
176 * will supposedly finish, once their programmed amount is
177 * done, and then the caches will get access according to the
178 * "fixed scheme" for unclaimed slots. Though, if for some
179 * use-case somewhere, there's a maximum CPU latency for
180 * e.g. some interrupt, we have to start allocating specific
181 * bandwidth for the CPU caches too.
182 */
183 active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
184 crisv32_arbiter_config(EXT_REGION, 0);
185 crisv32_arbiter_config(INT_REGION, 0);
186
187 if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
188 "arbiter", NULL))
189 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
190
191#ifndef CONFIG_ETRAX_KGDB
192 /* Global watch for writes to kernel text segment. */
193 crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
194 arbiter_all_clients, arbiter_all_write, NULL);
195#endif
196}
197
198/* Main entry for bandwidth allocation. */
199
200int crisv32_arbiter_allocate_bandwidth(int client, int region,
201 unsigned long bandwidth)
202{
203 int i;
204 int total_assigned = 0;
205 int total_clients = 0;
206 int req;
207
208 crisv32_arbiter_init();
209
210 for (i = 0; i < NBR_OF_CLIENTS; i++) {
211 total_assigned += requested_slots[region][i];
212 total_clients += active_clients[region][i];
213 }
214
215 /* Avoid division by 0 for 0-bandwidth requests. */
216 req = bandwidth == 0
217 ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
218
219 /*
220 * We make sure that there are enough slots only for non-zero
221 * requests. Requesting 0 bandwidth *may* allocate slots,
222 * though if all bandwidth is allocated, such a client won't
223 * get any and will have to rely on getting memory access
224 * according to the fixed scheme that's the default when one
225 * of the slot-allocated clients doesn't claim their slot.
226 */
227 if (total_assigned + req > NBR_OF_SLOTS)
228 return -ENOMEM;
229
230 active_clients[region][client] = 1;
231 requested_slots[region][client] = req;
232 crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
233
234 return 0;
235}
236
237/*
238 * Main entry for bandwidth deallocation.
239 *
240 * Strictly speaking, for a somewhat constant set of clients where
241 * each client gets a constant bandwidth and is just enabled or
242 * disabled (somewhat dynamically), no action is necessary here to
243 * avoid starvation for non-zero-allocation clients, as the allocated
244 * slots will just be unused. However, handing out those unused slots
245 * to active clients avoids needless latency if the "fixed scheme"
246 * would give unclaimed slots to an eager low-index client.
247 */
248
249void crisv32_arbiter_deallocate_bandwidth(int client, int region)
250{
251 int i;
252 int total_assigned = 0;
253
254 requested_slots[region][client] = 0;
255 active_clients[region][client] = 0;
256
257 for (i = 0; i < NBR_OF_CLIENTS; i++)
258 total_assigned += requested_slots[region][i];
259
260 crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
261}
262
263int crisv32_arbiter_watch(unsigned long start, unsigned long size,
264 unsigned long clients, unsigned long accesses,
265 watch_callback *cb)
266{
267 int i;
268
269 crisv32_arbiter_init();
270
271 if (start > 0x80000000) {
272 printk(KERN_ERR "Arbiter: %lX doesn't look like a "
273 "physical address", start);
274 return -EFAULT;
275 }
276
277 spin_lock(&arbiter_lock);
278
279 for (i = 0; i < NUMBER_OF_BP; i++) {
280 if (!watches[i].used) {
281 reg_marb_rw_intr_mask intr_mask =
282 REG_RD(marb, regi_marb, rw_intr_mask);
283
284 watches[i].used = 1;
285 watches[i].start = start;
286 watches[i].end = start + size;
287 watches[i].cb = cb;
288
289 REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr,
290 watches[i].start);
291 REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr,
292 watches[i].end);
293 REG_WR_INT(marb_bp, watches[i].instance, rw_op,
294 accesses);
295 REG_WR_INT(marb_bp, watches[i].instance, rw_clients,
296 clients);
297
298 if (i == 0)
299 intr_mask.bp0 = regk_marb_yes;
300 else if (i == 1)
301 intr_mask.bp1 = regk_marb_yes;
302 else if (i == 2)
303 intr_mask.bp2 = regk_marb_yes;
304 else if (i == 3)
305 intr_mask.bp3 = regk_marb_yes;
306
307 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
308 spin_unlock(&arbiter_lock);
309
310 return i;
311 }
312 }
313 spin_unlock(&arbiter_lock);
314 return -ENOMEM;
315}
316
317int crisv32_arbiter_unwatch(int id)
318{
319 reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
320
321 crisv32_arbiter_init();
322
323 spin_lock(&arbiter_lock);
324
325 if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
326 spin_unlock(&arbiter_lock);
327 return -EINVAL;
328 }
329
330 memset(&watches[id], 0, sizeof(struct crisv32_watch_entry));
331
332 if (id == 0)
333 intr_mask.bp0 = regk_marb_no;
334 else if (id == 1)
335 intr_mask.bp2 = regk_marb_no;
336 else if (id == 2)
337 intr_mask.bp2 = regk_marb_no;
338 else if (id == 3)
339 intr_mask.bp3 = regk_marb_no;
340
341 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
342
343 spin_unlock(&arbiter_lock);
344 return 0;
345}
346
347extern void show_registers(struct pt_regs *regs);
348
349static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id)
350{
351 reg_marb_r_masked_intr masked_intr =
352 REG_RD(marb, regi_marb, r_masked_intr);
353 reg_marb_bp_r_brk_clients r_clients;
354 reg_marb_bp_r_brk_addr r_addr;
355 reg_marb_bp_r_brk_op r_op;
356 reg_marb_bp_r_brk_first_client r_first;
357 reg_marb_bp_r_brk_size r_size;
358 reg_marb_bp_rw_ack ack = { 0 };
359 reg_marb_rw_ack_intr ack_intr = {
360 .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1
361 };
362 struct crisv32_watch_entry *watch;
363
364 if (masked_intr.bp0) {
365 watch = &watches[0];
366 ack_intr.bp0 = regk_marb_yes;
367 } else if (masked_intr.bp1) {
368 watch = &watches[1];
369 ack_intr.bp1 = regk_marb_yes;
370 } else if (masked_intr.bp2) {
371 watch = &watches[2];
372 ack_intr.bp2 = regk_marb_yes;
373 } else if (masked_intr.bp3) {
374 watch = &watches[3];
375 ack_intr.bp3 = regk_marb_yes;
376 } else {
377 return IRQ_NONE;
378 }
379
380 /* Retrieve all useful information and print it. */
381 r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients);
382 r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr);
383 r_op = REG_RD(marb_bp, watch->instance, r_brk_op);
384 r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client);
385 r_size = REG_RD(marb_bp, watch->instance, r_brk_size);
386
387 printk(KERN_INFO "Arbiter IRQ\n");
388 printk(KERN_INFO "Clients %X addr %X op %X first %X size %X\n",
389 REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients),
390 REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr),
391 REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op),
392 REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first),
393 REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size));
394
395 REG_WR(marb_bp, watch->instance, rw_ack, ack);
396 REG_WR(marb, regi_marb, rw_ack_intr, ack_intr);
397
398 printk(KERN_INFO "IRQ occured at %lX\n", get_irq_regs()->erp);
399
400 if (watch->cb)
401 watch->cb();
402
403 return IRQ_HANDLED;
404}
diff --git a/arch/cris/arch-v32/mach-fs/cpufreq.c b/arch/cris/arch-v32/mach-fs/cpufreq.c
new file mode 100644
index 000000000000..d57631c0d8d1
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/cpufreq.c
@@ -0,0 +1,146 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/cpufreq.h>
4#include <hwregs/reg_map.h>
5#include <asm/arch/hwregs/reg_rdwr.h>
6#include <asm/arch/hwregs/config_defs.h>
7#include <asm/arch/hwregs/bif_core_defs.h>
8
9static int
10cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
11 void *data);
12
13static struct notifier_block cris_sdram_freq_notifier_block = {
14 .notifier_call = cris_sdram_freq_notifier
15};
16
17static struct cpufreq_frequency_table cris_freq_table[] = {
18 {0x01, 6000},
19 {0x02, 200000},
20 {0, CPUFREQ_TABLE_END},
21};
22
23static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
24{
25 reg_config_rw_clk_ctrl clk_ctrl;
26 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
27 return clk_ctrl.pll ? 200000 : 6000;
28}
29
30static void cris_freq_set_cpu_state(unsigned int state)
31{
32 int i;
33 struct cpufreq_freqs freqs;
34 reg_config_rw_clk_ctrl clk_ctrl;
35 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
36
37 for_each_possible_cpu(i) {
38 freqs.old = cris_freq_get_cpu_frequency(i);
39 freqs.new = cris_freq_table[state].frequency;
40 freqs.cpu = i;
41 }
42
43 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
44
45 local_irq_disable();
46
47 /* Even though we may be SMP they will share the same clock
48 * so all settings are made on CPU0. */
49 if (cris_freq_table[state].frequency == 200000)
50 clk_ctrl.pll = 1;
51 else
52 clk_ctrl.pll = 0;
53 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
54
55 local_irq_enable();
56
57 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
58};
59
60static int cris_freq_verify(struct cpufreq_policy *policy)
61{
62 return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
63}
64
65static int cris_freq_target(struct cpufreq_policy *policy,
66 unsigned int target_freq, unsigned int relation)
67{
68 unsigned int newstate = 0;
69
70 if (cpufreq_frequency_table_target
71 (policy, cris_freq_table, target_freq, relation, &newstate))
72 return -EINVAL;
73
74 cris_freq_set_cpu_state(newstate);
75
76 return 0;
77}
78
79static int cris_freq_cpu_init(struct cpufreq_policy *policy)
80{
81 int result;
82
83 /* cpuinfo and default policy values */
84 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
85 policy->cpuinfo.transition_latency = 1000000; /* 1ms */
86 policy->cur = cris_freq_get_cpu_frequency(0);
87
88 result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
89 if (result)
90 return (result);
91
92 cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
93
94 return 0;
95}
96
97static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
98{
99 cpufreq_frequency_table_put_attr(policy->cpu);
100 return 0;
101}
102
103static struct freq_attr *cris_freq_attr[] = {
104 &cpufreq_freq_attr_scaling_available_freqs,
105 NULL,
106};
107
108static struct cpufreq_driver cris_freq_driver = {
109 .get = cris_freq_get_cpu_frequency,
110 .verify = cris_freq_verify,
111 .target = cris_freq_target,
112 .init = cris_freq_cpu_init,
113 .exit = cris_freq_cpu_exit,
114 .name = "cris_freq",
115 .owner = THIS_MODULE,
116 .attr = cris_freq_attr,
117};
118
119static int __init cris_freq_init(void)
120{
121 int ret;
122 ret = cpufreq_register_driver(&cris_freq_driver);
123 cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
124 CPUFREQ_TRANSITION_NOTIFIER);
125 return ret;
126}
127
128static int
129cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
130 void *data)
131{
132 int i;
133 struct cpufreq_freqs *freqs = data;
134 if (val == CPUFREQ_PRECHANGE) {
135 reg_bif_core_rw_sdram_timing timing =
136 REG_RD(bif_core, regi_bif_core, rw_sdram_timing);
137 timing.cpd = (freqs->new == 200000 ? 0 : 1);
138
139 if (freqs->new == 200000)
140 for (i = 0; i < 50000; i++) ;
141 REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
142 }
143 return 0;
144}
145
146module_init(cris_freq_init);
diff --git a/arch/cris/arch-v32/kernel/dma.c b/arch/cris/arch-v32/mach-fs/dma.c
index 570e19128ffd..a6acf4e6345c 100644
--- a/arch/cris/arch-v32/kernel/dma.c
+++ b/arch/cris/arch-v32/mach-fs/dma.c
@@ -3,49 +3,54 @@
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/spinlock.h> 4#include <linux/spinlock.h>
5#include <asm/dma.h> 5#include <asm/dma.h>
6#include <asm/arch/hwregs/reg_map.h> 6#include <hwregs/reg_map.h>
7#include <asm/arch/hwregs/reg_rdwr.h> 7#include <hwregs/reg_rdwr.h>
8#include <asm/arch/hwregs/marb_defs.h> 8#include <hwregs/marb_defs.h>
9#include <asm/arch/hwregs/config_defs.h> 9#include <hwregs/config_defs.h>
10#include <asm/arch/hwregs/strmux_defs.h> 10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <asm/system.h> 12#include <asm/system.h>
13#include <asm/arch/arbiter.h> 13#include <asm/arch/mach/arbiter.h>
14 14
15static char used_dma_channels[MAX_DMA_CHANNELS]; 15static char used_dma_channels[MAX_DMA_CHANNELS];
16static const char * used_dma_channels_users[MAX_DMA_CHANNELS]; 16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
17 17
18static DEFINE_SPINLOCK(dma_lock); 18static DEFINE_SPINLOCK(dma_lock);
19 19
20int crisv32_request_dma(unsigned int dmanr, const char * device_id, 20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
21 unsigned options, unsigned int bandwidth, 21 unsigned options, unsigned int bandwidth,
22 enum dma_owner owner) 22 enum dma_owner owner)
23{ 23{
24 unsigned long flags; 24 unsigned long flags;
25 reg_config_rw_clk_ctrl clk_ctrl; 25 reg_config_rw_clk_ctrl clk_ctrl;
26 reg_strmux_rw_cfg strmux_cfg; 26 reg_strmux_rw_cfg strmux_cfg;
27 27
28 if (crisv32_arbiter_allocate_bandwidth(dmanr, 28 if (crisv32_arbiter_allocate_bandwidth(dmanr,
29 options & DMA_INT_MEM ? INT_REGION : EXT_REGION, 29 options & DMA_INT_MEM ?
30 bandwidth)) 30 INT_REGION : EXT_REGION,
31 return -ENOMEM; 31 bandwidth))
32 return -ENOMEM;
32 33
33 spin_lock_irqsave(&dma_lock, flags); 34 spin_lock_irqsave(&dma_lock, flags);
34 35
35 if (used_dma_channels[dmanr]) { 36 if (used_dma_channels[dmanr]) {
36 spin_unlock_irqrestore(&dma_lock, flags); 37 spin_unlock_irqrestore(&dma_lock, flags);
37 if (options & DMA_VERBOSE_ON_ERROR) { 38 if (options & DMA_VERBOSE_ON_ERROR) {
38 printk("Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]); 39 printk(KERN_ERR "Failed to request DMA %i for %s, "
40 "already allocated by %s\n",
41 dmanr,
42 device_id,
43 used_dma_channels_users[dmanr]);
39 } 44 }
40 if (options & DMA_PANIC_ON_ERROR) 45 if (options & DMA_PANIC_ON_ERROR)
41 panic("request_dma error!"); 46 panic("request_dma error!");
47 spin_unlock_irqrestore(&dma_lock, flags);
42 return -EBUSY; 48 return -EBUSY;
43 } 49 }
44 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); 50 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
45 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); 51 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
46 52
47 switch(dmanr) 53 switch (dmanr) {
48 {
49 case 0: 54 case 0:
50 case 1: 55 case 1:
51 clk_ctrl.dma01_eth0 = 1; 56 clk_ctrl.dma01_eth0 = 1;
@@ -72,7 +77,9 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id,
72 default: 77 default:
73 spin_unlock_irqrestore(&dma_lock, flags); 78 spin_unlock_irqrestore(&dma_lock, flags);
74 if (options & DMA_VERBOSE_ON_ERROR) { 79 if (options & DMA_VERBOSE_ON_ERROR) {
75 printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1); 80 printk(KERN_ERR "Failed to request DMA %i for %s, "
81 "only 0-%i valid)\n",
82 dmanr, device_id, MAX_DMA_CHANNELS - 1);
76 } 83 }
77 84
78 if (options & DMA_PANIC_ON_ERROR) 85 if (options & DMA_PANIC_ON_ERROR)
@@ -80,8 +87,7 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id,
80 return -EINVAL; 87 return -EINVAL;
81 } 88 }
82 89
83 switch(owner) 90 switch (owner) {
84 {
85 case dma_eth0: 91 case dma_eth0:
86 if (dmanr == 0) 92 if (dmanr == 0)
87 strmux_cfg.dma0 = regk_strmux_eth0; 93 strmux_cfg.dma0 = regk_strmux_eth0;
@@ -212,7 +218,7 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id,
212 used_dma_channels_users[dmanr] = device_id; 218 used_dma_channels_users[dmanr] = device_id;
213 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl); 219 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
214 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); 220 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
215 spin_unlock_irqrestore(&dma_lock,flags); 221 spin_unlock_irqrestore(&dma_lock, flags);
216 return 0; 222 return 0;
217} 223}
218 224
diff --git a/arch/cris/arch-v32/lib/dram_init.S b/arch/cris/arch-v32/mach-fs/dram_init.S
index 218fbe259ee5..6fbad336527b 100644
--- a/arch/cris/arch-v32/lib/dram_init.S
+++ b/arch/cris/arch-v32/mach-fs/dram_init.S
@@ -1,23 +1,22 @@
1/* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $ 1/*
2 *
3 * DRAM/SDRAM initialization - alter with care 2 * DRAM/SDRAM initialization - alter with care
4 * This file is intended to be included from other assembler files 3 * This file is intended to be included from other assembler files
5 * 4 *
6 * Note: This file may not modify r8 or r9 because they are used to 5 * Note: This file may not modify r8 or r9 because they are used to
7 * carry information from the decompresser to the kernel 6 * carry information from the decompresser to the kernel
8 * 7 *
9 * Copyright (C) 2000-2003 Axis Communications AB 8 * Copyright (C) 2000-2007 Axis Communications AB
10 * 9 *
11 * Authors: Mikael Starvik (starvik@axis.com) 10 * Authors: Mikael Starvik <starvik@axis.com>
12 */ 11 */
13 12
14/* Just to be certain the config file is included, we include it here 13/* Just to be certain the config file is included, we include it here
15 * explicitly instead of depending on it being included in the file that 14 * explicitely instead of depending on it being included in the file that
16 * uses this code. 15 * uses this code.
17 */ 16 */
18 17
19#include <asm/arch/hwregs/asm/reg_map_asm.h> 18#include <hwregs/asm/reg_map_asm.h>
20#include <asm/arch/hwregs/asm/bif_core_defs_asm.h> 19#include <hwregs/asm/bif_core_defs_asm.h>
21 20
22 ;; WARNING! The registers r8 and r9 are used as parameters carrying 21 ;; WARNING! The registers r8 and r9 are used as parameters carrying
23 ;; information from the decompressor (if the kernel was compressed). 22 ;; information from the decompressor (if the kernel was compressed).
@@ -46,7 +45,7 @@
46 45
47 move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2 46 move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2
48 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1 47 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
49 and.d 0x07, $r1 ; Get CAS latency 48 and.d 0x07, $r1 ; Get CAS latency
50 cmpq 2, $r1 ; CL = 2 ? 49 cmpq 2, $r1 ; CL = 2 ?
51 beq _bw_check 50 beq _bw_check
52 nop 51 nop
@@ -80,12 +79,10 @@ _set_timing:
80 subq 1, $r2 79 subq 1, $r2
81 80
82 ; Issue initialization command sequence 81 ; Issue initialization command sequence
83 move.d _sdram_commands_start, $r2 82 lapc _sdram_commands_start, $r2
84 and.d 0x000fffff, $r2 ; Make sure commands are read from flash 83 lapc _sdram_commands_end, $r3
85 move.d _sdram_commands_end, $r3
86 and.d 0x000fffff, $r3
871: clear.d $r6 841: clear.d $r6
88 move.b [$r2+], $r6 ; Load command 85 move.b [$r2+], $r6 ; Load command
89 or.d $r4, $r6 ; Add calculated mrs 86 or.d $r4, $r6 ; Add calculated mrs
90 move.d $r6, [$r5] ; Write rw_sdram_cmd 87 move.d $r6, [$r5] ; Write rw_sdram_cmd
91 ; Wait 80 ns between each command 88 ; Wait 80 ns between each command
diff --git a/arch/cris/arch-v32/lib/hw_settings.S b/arch/cris/arch-v32/mach-fs/hw_settings.S
index fff9443513d1..8bde93c36214 100644
--- a/arch/cris/arch-v32/lib/hw_settings.S
+++ b/arch/cris/arch-v32/mach-fs/hw_settings.S
@@ -1,18 +1,16 @@
1/* 1/*
2 * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $
3 *
4 * This table is used by some tools to extract hardware parameters. 2 * This table is used by some tools to extract hardware parameters.
5 * The table should be included in the kernel and the decompressor. 3 * The table should be included in the kernel and the decompressor.
6 * Don't forget to update the tools if you change this table. 4 * Don't forget to update the tools if you change this table.
7 * 5 *
8 * Copyright (C) 2001 Axis Communications AB 6 * Copyright (C) 2001-2007 Axis Communications AB
9 * 7 *
10 * Authors: Mikael Starvik (starvik@axis.com) 8 * Authors: Mikael Starvik <starvik@axis.com>
11 */ 9 */
12 10
13#include <asm/arch/hwregs/asm/reg_map_asm.h> 11#include <hwregs/asm/reg_map_asm.h>
14#include <asm/arch/hwregs/asm/bif_core_defs_asm.h> 12#include <hwregs/asm/bif_core_defs_asm.h>
15#include <asm/arch/hwregs/asm/gio_defs_asm.h> 13#include <hwregs/asm/gio_defs_asm.h>
16 14
17 .ascii "HW_PARAM_MAGIC" ; Magic number 15 .ascii "HW_PARAM_MAGIC" ; Magic number
18 .dword 0xc0004000 ; Kernel start address 16 .dword 0xc0004000 ; Kernel start address
diff --git a/arch/cris/arch-v32/mach-fs/io.c b/arch/cris/arch-v32/mach-fs/io.c
new file mode 100644
index 000000000000..a03a3ad3a188
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/io.c
@@ -0,0 +1,191 @@
1/*
2 * Helper functions for I/O pins.
3 *
4 * Copyright (c) 2004-2007 Axis Communications AB.
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9#include <linux/init.h>
10#include <linux/string.h>
11#include <linux/ctype.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/io.h>
15#include <asm/arch/pinmux.h>
16#include <asm/arch/hwregs/gio_defs.h>
17
18#ifndef DEBUG
19#define DEBUG(x)
20#endif
21
22struct crisv32_ioport crisv32_ioports[] = {
23 {
24 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
25 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
26 (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
27 8
28 },
29 {
30 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
31 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
32 (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
33 18
34 },
35 {
36 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
37 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
38 (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
39 18
40 },
41 {
42 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_oe),
43 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_dout),
44 (unsigned long *)REG_ADDR(gio, regi_gio, r_pd_din),
45 18
46 },
47 {
48 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_oe),
49 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_dout),
50 (unsigned long *)REG_ADDR(gio, regi_gio, r_pe_din),
51 18
52 }
53};
54
55#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
56
57struct crisv32_iopin crisv32_led_net0_green;
58struct crisv32_iopin crisv32_led_net0_red;
59struct crisv32_iopin crisv32_led_net1_green;
60struct crisv32_iopin crisv32_led_net1_red;
61struct crisv32_iopin crisv32_led2_green;
62struct crisv32_iopin crisv32_led2_red;
63struct crisv32_iopin crisv32_led3_green;
64struct crisv32_iopin crisv32_led3_red;
65
66/* Dummy port used when green LED and red LED is on the same bit */
67static unsigned long io_dummy;
68static struct crisv32_ioport dummy_port = {
69 &io_dummy,
70 &io_dummy,
71 &io_dummy,
72 18
73};
74static struct crisv32_iopin dummy_led = {
75 &dummy_port,
76 0
77};
78
79static int __init crisv32_io_init(void)
80{
81 int ret = 0;
82
83 u32 i;
84
85 /* Locks *should* be dynamically initialized. */
86 for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
87 spin_lock_init(&crisv32_ioports[i].lock);
88 spin_lock_init(&dummy_port.lock);
89
90 /* Initialize LEDs */
91#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
92 ret +=
93 crisv32_io_get_name(&crisv32_led_net0_green,
94 CONFIG_ETRAX_LED_G_NET0);
95 crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
96 if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
97 ret +=
98 crisv32_io_get_name(&crisv32_led_net0_red,
99 CONFIG_ETRAX_LED_R_NET0);
100 crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
101 } else
102 crisv32_led_net0_red = dummy_led;
103#endif
104
105#ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO
106 ret +=
107 crisv32_io_get_name(&crisv32_led_net1_green,
108 CONFIG_ETRAX_LED_G_NET1);
109 crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out);
110 if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) {
111 crisv32_io_get_name(&crisv32_led_net1_red,
112 CONFIG_ETRAX_LED_R_NET1);
113 crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out);
114 } else
115 crisv32_led_net1_red = dummy_led;
116#endif
117
118 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
119 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
120 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
121 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);
122
123 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
124 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
125 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
126 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
127
128 return ret;
129}
130
131__initcall(crisv32_io_init);
132
133int crisv32_io_get(struct crisv32_iopin *iopin,
134 unsigned int port, unsigned int pin)
135{
136 if (port > NBR_OF_PORTS)
137 return -EINVAL;
138 if (port > crisv32_ioports[port].pin_count)
139 return -EINVAL;
140
141 iopin->bit = 1 << pin;
142 iopin->port = &crisv32_ioports[port];
143
144 /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
145 /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
146 if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
147 return -EIO;
148 DEBUG(printk(KERN_DEBUG "crisv32_io_get: Allocated pin %d on port %d\n",
149 pin, port));
150
151 return 0;
152}
153
154int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
155{
156 int port;
157 int pin;
158
159 if (toupper(*name) == 'P')
160 name++;
161
162 if (toupper(*name) < 'A' || toupper(*name) > 'E')
163 return -EINVAL;
164
165 port = toupper(*name) - 'A';
166 name++;
167 pin = simple_strtoul(name, NULL, 10);
168
169 if (pin < 0 || pin > crisv32_ioports[port].pin_count)
170 return -EINVAL;
171
172 iopin->bit = 1 << pin;
173 iopin->port = &crisv32_ioports[port];
174
175 /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
176 /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
177 if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
178 return -EIO;
179
180 DEBUG(printk(KERN_DEBUG
181 "crisv32_io_get_name: Allocated pin %d on port %d\n",
182 pin, port));
183
184 return 0;
185}
186
187#ifdef CONFIG_PCI
188/* PCI I/O access stuff */
189struct cris_io_operations *cris_iops = NULL;
190EXPORT_SYMBOL(cris_iops);
191#endif
diff --git a/arch/cris/arch-v32/mach-fs/pinmux.c b/arch/cris/arch-v32/mach-fs/pinmux.c
new file mode 100644
index 000000000000..d722ad9ae626
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/pinmux.c
@@ -0,0 +1,309 @@
1/*
2 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
3 * Unassigned pins and GPIO pins can be allocated to a fixed interface
4 * or the I/O processor instead.
5 *
6 * Copyright (c) 2004-2007 Axis Communications AB.
7 */
8
9#include <linux/init.h>
10#include <linux/errno.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/spinlock.h>
14#include <hwregs/reg_map.h>
15#include <hwregs/reg_rdwr.h>
16#include <pinmux.h>
17#include <hwregs/pinmux_defs.h>
18
19#undef DEBUG
20
21#define PORT_PINS 18
22#define PORTS 4
23
24static char pins[PORTS][PORT_PINS];
25static DEFINE_SPINLOCK(pinmux_lock);
26
27static void crisv32_pinmux_set(int port);
28
29int crisv32_pinmux_init(void)
30{
31 static int initialized;
32
33 if (!initialized) {
34 reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
35 initialized = 1;
36 REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
37 pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
38 pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
39 REG_WR(pinmux, regi_pinmux, rw_pa, pa);
40 crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
41 crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
42 crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio);
43 crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio);
44 }
45
46 return 0;
47}
48
49int
50crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
51{
52 int i;
53 unsigned long flags;
54
55 crisv32_pinmux_init();
56
57 if (port > PORTS)
58 return -EINVAL;
59
60 spin_lock_irqsave(&pinmux_lock, flags);
61
62 for (i = first_pin; i <= last_pin; i++) {
63 if ((pins[port][i] != pinmux_none)
64 && (pins[port][i] != pinmux_gpio)
65 && (pins[port][i] != mode)) {
66 spin_unlock_irqrestore(&pinmux_lock, flags);
67#ifdef DEBUG
68 panic("Pinmux alloc failed!\n");
69#endif
70 return -EPERM;
71 }
72 }
73
74 for (i = first_pin; i <= last_pin; i++)
75 pins[port][i] = mode;
76
77 crisv32_pinmux_set(port);
78
79 spin_unlock_irqrestore(&pinmux_lock, flags);
80
81 return 0;
82}
83
84int crisv32_pinmux_alloc_fixed(enum fixed_function function)
85{
86 int ret = -EINVAL;
87 char saved[sizeof pins];
88 unsigned long flags;
89
90 spin_lock_irqsave(&pinmux_lock, flags);
91
92 /* Save internal data for recovery */
93 memcpy(saved, pins, sizeof pins);
94
95 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
96
97 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
98
99 switch (function) {
100 case pinmux_ser1:
101 ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
102 hwprot.ser1 = regk_pinmux_yes;
103 break;
104 case pinmux_ser2:
105 ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
106 hwprot.ser2 = regk_pinmux_yes;
107 break;
108 case pinmux_ser3:
109 ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
110 hwprot.ser3 = regk_pinmux_yes;
111 break;
112 case pinmux_sser0:
113 ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
114 ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
115 hwprot.sser0 = regk_pinmux_yes;
116 break;
117 case pinmux_sser1:
118 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
119 hwprot.sser1 = regk_pinmux_yes;
120 break;
121 case pinmux_ata0:
122 ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
123 ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
124 hwprot.ata0 = regk_pinmux_yes;
125 break;
126 case pinmux_ata1:
127 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
128 ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
129 hwprot.ata1 = regk_pinmux_yes;
130 break;
131 case pinmux_ata2:
132 ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
133 ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
134 hwprot.ata2 = regk_pinmux_yes;
135 break;
136 case pinmux_ata3:
137 ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
138 ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
139 hwprot.ata2 = regk_pinmux_yes;
140 break;
141 case pinmux_ata:
142 ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
143 ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
144 hwprot.ata = regk_pinmux_yes;
145 break;
146 case pinmux_eth1:
147 ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
148 hwprot.eth1 = regk_pinmux_yes;
149 hwprot.eth1_mgm = regk_pinmux_yes;
150 break;
151 case pinmux_timer:
152 ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
153 hwprot.timer = regk_pinmux_yes;
154 spin_unlock_irqrestore(&pinmux_lock, flags);
155 return ret;
156 }
157
158 if (!ret)
159 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
160 else
161 memcpy(pins, saved, sizeof pins);
162
163 spin_unlock_irqrestore(&pinmux_lock, flags);
164
165 return ret;
166}
167
168void crisv32_pinmux_set(int port)
169{
170 int i;
171 int gpio_val = 0;
172 int iop_val = 0;
173
174 for (i = 0; i < PORT_PINS; i++) {
175 if (pins[port][i] == pinmux_gpio)
176 gpio_val |= (1 << i);
177 else if (pins[port][i] == pinmux_iop)
178 iop_val |= (1 << i);
179 }
180
181 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8 * port,
182 gpio_val);
183 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8 * port,
184 iop_val);
185
186#ifdef DEBUG
187 crisv32_pinmux_dump();
188#endif
189}
190
191int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
192{
193 int i;
194 unsigned long flags;
195
196 crisv32_pinmux_init();
197
198 if (port > PORTS)
199 return -EINVAL;
200
201 spin_lock_irqsave(&pinmux_lock, flags);
202
203 for (i = first_pin; i <= last_pin; i++)
204 pins[port][i] = pinmux_none;
205
206 crisv32_pinmux_set(port);
207 spin_unlock_irqrestore(&pinmux_lock, flags);
208
209 return 0;
210}
211
212int crisv32_pinmux_dealloc_fixed(enum fixed_function function)
213{
214 int ret = -EINVAL;
215 char saved[sizeof pins];
216 unsigned long flags;
217
218 spin_lock_irqsave(&pinmux_lock, flags);
219
220 /* Save internal data for recovery */
221 memcpy(saved, pins, sizeof pins);
222
223 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
224
225 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
226
227 switch (function) {
228 case pinmux_ser1:
229 ret = crisv32_pinmux_dealloc(PORT_C, 4, 7);
230 hwprot.ser1 = regk_pinmux_no;
231 break;
232 case pinmux_ser2:
233 ret = crisv32_pinmux_dealloc(PORT_C, 8, 11);
234 hwprot.ser2 = regk_pinmux_no;
235 break;
236 case pinmux_ser3:
237 ret = crisv32_pinmux_dealloc(PORT_C, 12, 15);
238 hwprot.ser3 = regk_pinmux_no;
239 break;
240 case pinmux_sser0:
241 ret = crisv32_pinmux_dealloc(PORT_C, 0, 3);
242 ret |= crisv32_pinmux_dealloc(PORT_C, 16, 16);
243 hwprot.sser0 = regk_pinmux_no;
244 break;
245 case pinmux_sser1:
246 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4);
247 hwprot.sser1 = regk_pinmux_no;
248 break;
249 case pinmux_ata0:
250 ret = crisv32_pinmux_dealloc(PORT_D, 5, 7);
251 ret |= crisv32_pinmux_dealloc(PORT_D, 15, 17);
252 hwprot.ata0 = regk_pinmux_no;
253 break;
254 case pinmux_ata1:
255 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4);
256 ret |= crisv32_pinmux_dealloc(PORT_E, 17, 17);
257 hwprot.ata1 = regk_pinmux_no;
258 break;
259 case pinmux_ata2:
260 ret = crisv32_pinmux_dealloc(PORT_C, 11, 15);
261 ret |= crisv32_pinmux_dealloc(PORT_E, 3, 3);
262 hwprot.ata2 = regk_pinmux_no;
263 break;
264 case pinmux_ata3:
265 ret = crisv32_pinmux_dealloc(PORT_C, 8, 10);
266 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 2);
267 hwprot.ata2 = regk_pinmux_no;
268 break;
269 case pinmux_ata:
270 ret = crisv32_pinmux_dealloc(PORT_B, 0, 15);
271 ret |= crisv32_pinmux_dealloc(PORT_D, 8, 15);
272 hwprot.ata = regk_pinmux_no;
273 break;
274 case pinmux_eth1:
275 ret = crisv32_pinmux_dealloc(PORT_E, 0, 17);
276 hwprot.eth1 = regk_pinmux_no;
277 hwprot.eth1_mgm = regk_pinmux_no;
278 break;
279 case pinmux_timer:
280 ret = crisv32_pinmux_dealloc(PORT_C, 16, 16);
281 hwprot.timer = regk_pinmux_no;
282 spin_unlock_irqrestore(&pinmux_lock, flags);
283 return ret;
284 }
285
286 if (!ret)
287 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
288 else
289 memcpy(pins, saved, sizeof pins);
290
291 spin_unlock_irqrestore(&pinmux_lock, flags);
292
293 return ret;
294}
295
296void crisv32_pinmux_dump(void)
297{
298 int i, j;
299
300 crisv32_pinmux_init();
301
302 for (i = 0; i < PORTS; i++) {
303 printk(KERN_DEBUG "Port %c\n", 'B' + i);
304 for (j = 0; j < PORT_PINS; j++)
305 printk(KERN_DEBUG " Pin %d = %d\n", j, pins[i][j]);
306 }
307}
308
309__initcall(crisv32_pinmux_init);
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.c b/arch/cris/arch-v32/mach-fs/vcs_hook.c
new file mode 100644
index 000000000000..593b10f07ef1
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.c
@@ -0,0 +1,100 @@
1/*
2 * Call simulator hook. This is the part running in the
3 * simulated program.
4 */
5
6#include "vcs_hook.h"
7#include <stdarg.h>
8#include <asm/arch-v32/hwregs/reg_map.h>
9#include <asm/arch-v32/hwregs/intr_vect_defs.h>
10
11#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
12#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
13
14#define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset]
15#define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset]
16#define HOOK_TRIG(funcid) \
17 do { \
18 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19 } while (0)
20#define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset]
21
22int hook_call(unsigned id, unsigned pcnt, ...)
23{
24 va_list ap;
25 unsigned i;
26 unsigned ret;
27#ifdef USING_SOS
28 PREEMPT_OFF_SAVE();
29#endif
30
31 /* pass parameters */
32 HOOK_DATA(0) = id;
33
34 /* Have to make hook_print_str a special case since we call with a
35 * parameter of byte type. Should perhaps be a separate
36 * hook_call. */
37
38 if (id == hook_print_str) {
39 int i;
40 char *str;
41
42 HOOK_DATA(1) = pcnt;
43
44 va_start(ap, pcnt);
45 str = (char *)va_arg(ap, unsigned);
46
47 for (i = 0; i != pcnt; i++)
48 HOOK_DATA_BYTE(8 + i) = str[i];
49
50 HOOK_DATA_BYTE(8 + i) = 0; /* null byte */
51 } else {
52 va_start(ap, pcnt);
53 for (i = 1; i <= pcnt; i++)
54 HOOK_DATA(i) = va_arg(ap, unsigned);
55 va_end(ap);
56 }
57
58 /* read from mem to make sure data has propagated to memory before
59 * trigging */
60 ret = *((volatile unsigned *)HOOK_MEM_BASE_ADDR);
61
62 /* trigger hook */
63 HOOK_TRIG(id);
64
65 /* wait for call to finish */
66 while (VHOOK_DATA(0) > 0) ;
67
68 /* extract return value */
69
70 ret = VHOOK_DATA(1);
71
72#ifdef USING_SOS
73 PREEMPT_RESTORE();
74#endif
75 return ret;
76}
77
78unsigned hook_buf(unsigned i)
79{
80 return (HOOK_DATA(i));
81}
82
83void print_str(const char *str)
84{
85 int i;
86 /* find null at end of string */
87 for (i = 1; str[i]; i++) ;
88 hook_call(hook_print_str, i, str);
89}
90
91void CPU_KICK_DOG(void)
92{
93 (void)hook_call(hook_kick_dog, 0);
94}
95
96void CPU_WATCHDOG_TIMEOUT(unsigned t)
97{
98 (void)hook_call(hook_dog_timeout, 1, t);
99}
100
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.h b/arch/cris/arch-v32/mach-fs/vcs_hook.h
index 7d73709e3cc6..c000b9fece41 100644
--- a/arch/cris/arch-v32/kernel/vcs_hook.h
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.h
@@ -1,11 +1,11 @@
1// $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $ 1/*
2// 2 * Call simulator hook functions
3// Call simulator hook functions 3 */
4 4
5#ifndef HOOK_H 5#ifndef HOOK_H
6#define HOOK_H 6#define HOOK_H
7 7
8int hook_call( unsigned id, unsigned pcnt, ...); 8int hook_call(unsigned id, unsigned pcnt, ...);
9 9
10enum hook_ids { 10enum hook_ids {
11 hook_debug_on = 1, 11 hook_debug_on = 1,
diff --git a/arch/cris/arch-v32/mm/Makefile b/arch/cris/arch-v32/mm/Makefile
index 9146f88484b1..0b801f2964ac 100644
--- a/arch/cris/arch-v32/mm/Makefile
+++ b/arch/cris/arch-v32/mm/Makefile
@@ -1,3 +1,4 @@
1# Makefile for the Linux/cris parts of the memory manager. 1# Makefile for the Linux/cris parts of the memory manager.
2 2
3obj-y := mmu.o init.o tlb.o intmem.o 3obj-y += mmu.o init.o tlb.o intmem.o
4obj-$(CONFIG_ETRAX_L2CACHE) += l2cache.o
diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c
index a84ba7ff22d2..5a9ac5834647 100644
--- a/arch/cris/arch-v32/mm/init.c
+++ b/arch/cris/arch-v32/mm/init.c
@@ -65,7 +65,7 @@ cris_mmu_init(void)
65 REG_STATE(mmu, rw_mm_cfg, seg_d, page) | 65 REG_STATE(mmu, rw_mm_cfg, seg_d, page) |
66 REG_STATE(mmu, rw_mm_cfg, seg_c, linear) | 66 REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
67 REG_STATE(mmu, rw_mm_cfg, seg_b, linear) | 67 REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
68#ifndef CONFIG_ETRAXFS_SIM 68#ifndef CONFIG_ETRAX_VCS_SIM
69 REG_STATE(mmu, rw_mm_cfg, seg_a, page) | 69 REG_STATE(mmu, rw_mm_cfg, seg_a, page) |
70#else 70#else
71 REG_STATE(mmu, rw_mm_cfg, seg_a, linear) | 71 REG_STATE(mmu, rw_mm_cfg, seg_a, linear) |
@@ -84,13 +84,9 @@ cris_mmu_init(void)
84 mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) | 84 mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) |
85 REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) | 85 REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) |
86 REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) | 86 REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) |
87#ifndef CONFIG_ETRAXFS_SIM
88 REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) | 87 REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
89#else
90 REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x0) |
91#endif
92 REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) | 88 REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
93#ifndef CONFIG_ETRAXFS_SIM 89#ifndef CONFIG_ETRAX_VCS_SIM
94 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) | 90 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) |
95#else 91#else
96 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) | 92 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) |
diff --git a/arch/cris/arch-v32/mm/intmem.c b/arch/cris/arch-v32/mm/intmem.c
index 41ee7f7997fd..9e8b69cdf19e 100644
--- a/arch/cris/arch-v32/mm/intmem.c
+++ b/arch/cris/arch-v32/mm/intmem.c
@@ -7,11 +7,17 @@
7#include <linux/list.h> 7#include <linux/list.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <asm/io.h> 9#include <asm/io.h>
10#include <asm/arch/memmap.h> 10#include <memmap.h>
11 11
12#define STATUS_FREE 0 12#define STATUS_FREE 0
13#define STATUS_ALLOCATED 1 13#define STATUS_ALLOCATED 1
14 14
15#ifdef CONFIG_ETRAX_L2CACHE
16#define RESERVED_SIZE 66*1024
17#else
18#define RESERVED_SIZE 0
19#endif
20
15struct intmem_allocation { 21struct intmem_allocation {
16 struct list_head entry; 22 struct list_head entry;
17 unsigned int size; 23 unsigned int size;
@@ -30,9 +36,10 @@ static void crisv32_intmem_init(void)
30 struct intmem_allocation* alloc = 36 struct intmem_allocation* alloc =
31 (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL); 37 (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);
32 INIT_LIST_HEAD(&intmem_allocations); 38 INIT_LIST_HEAD(&intmem_allocations);
33 intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE); 39 intmem_virtual = ioremap(MEM_INTMEM_START + RESERVED_SIZE,
40 MEM_INTMEM_SIZE - RESERVED_SIZE);
34 initiated = 1; 41 initiated = 1;
35 alloc->size = MEM_INTMEM_SIZE; 42 alloc->size = MEM_INTMEM_SIZE - RESERVED_SIZE;
36 alloc->offset = 0; 43 alloc->offset = 0;
37 alloc->status = STATUS_FREE; 44 alloc->status = STATUS_FREE;
38 list_add_tail(&alloc->entry, &intmem_allocations); 45 list_add_tail(&alloc->entry, &intmem_allocations);
@@ -59,19 +66,23 @@ void* crisv32_intmem_alloc(unsigned size, unsigned align)
59 (struct intmem_allocation*) 66 (struct intmem_allocation*)
60 kmalloc(sizeof *alloc, GFP_ATOMIC); 67 kmalloc(sizeof *alloc, GFP_ATOMIC);
61 alloc->status = STATUS_FREE; 68 alloc->status = STATUS_FREE;
62 alloc->size = allocation->size - size - alignment; 69 alloc->size = allocation->size - size -
63 alloc->offset = allocation->offset + size; 70 alignment;
71 alloc->offset = allocation->offset + size +
72 alignment;
64 list_add(&alloc->entry, &allocation->entry); 73 list_add(&alloc->entry, &allocation->entry);
65 74
66 if (alignment) { 75 if (alignment) {
67 struct intmem_allocation* tmp; 76 struct intmem_allocation *tmp;
68 tmp = (struct intmem_allocation*) 77 tmp = (struct intmem_allocation *)
69 kmalloc(sizeof *tmp, GFP_ATOMIC); 78 kmalloc(sizeof *tmp,
79 GFP_ATOMIC);
70 tmp->offset = allocation->offset; 80 tmp->offset = allocation->offset;
71 tmp->size = alignment; 81 tmp->size = alignment;
72 tmp->status = STATUS_FREE; 82 tmp->status = STATUS_FREE;
73 allocation->offset += alignment; 83 allocation->offset += alignment;
74 list_add_tail(&tmp->entry, &allocation->entry); 84 list_add_tail(&tmp->entry,
85 &allocation->entry);
75 } 86 }
76 } 87 }
77 allocation->status = STATUS_ALLOCATED; 88 allocation->status = STATUS_ALLOCATED;
@@ -96,22 +107,24 @@ void crisv32_intmem_free(void* addr)
96 107
97 list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) { 108 list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
98 if (allocation->offset == (int)(addr - intmem_virtual)) { 109 if (allocation->offset == (int)(addr - intmem_virtual)) {
99 struct intmem_allocation* prev = 110 struct intmem_allocation *prev =
100 list_entry(allocation->entry.prev, 111 list_entry(allocation->entry.prev,
101 struct intmem_allocation, entry); 112 struct intmem_allocation, entry);
102 struct intmem_allocation* next = 113 struct intmem_allocation *next =
103 list_entry(allocation->entry.next, 114 list_entry(allocation->entry.next,
104 struct intmem_allocation, entry); 115 struct intmem_allocation, entry);
105 116
106 allocation->status = STATUS_FREE; 117 allocation->status = STATUS_FREE;
107 /* Join with prev and/or next if also free */ 118 /* Join with prev and/or next if also free */
108 if (prev->status == STATUS_FREE) { 119 if ((prev != &intmem_allocations) &&
120 (prev->status == STATUS_FREE)) {
109 prev->size += allocation->size; 121 prev->size += allocation->size;
110 list_del(&allocation->entry); 122 list_del(&allocation->entry);
111 kfree(allocation); 123 kfree(allocation);
112 allocation = prev; 124 allocation = prev;
113 } 125 }
114 if (next->status == STATUS_FREE) { 126 if ((next != &intmem_allocations) &&
127 (next->status == STATUS_FREE)) {
115 allocation->size += next->size; 128 allocation->size += next->size;
116 list_del(&next->entry); 129 list_del(&next->entry);
117 kfree(next); 130 kfree(next);
@@ -125,15 +138,16 @@ void crisv32_intmem_free(void* addr)
125 138
126void* crisv32_intmem_phys_to_virt(unsigned long addr) 139void* crisv32_intmem_phys_to_virt(unsigned long addr)
127{ 140{
128 return (void*)(addr - MEM_INTMEM_START+ 141 return (void *)(addr - (MEM_INTMEM_START + RESERVED_SIZE) +
129 (unsigned long)intmem_virtual); 142 (unsigned long)intmem_virtual);
130} 143}
131 144
132unsigned long crisv32_intmem_virt_to_phys(void* addr) 145unsigned long crisv32_intmem_virt_to_phys(void* addr)
133{ 146{
134 return (unsigned long)((unsigned long )addr - 147 return (unsigned long)((unsigned long )addr -
135 (unsigned long)intmem_virtual + MEM_INTMEM_START); 148 (unsigned long)intmem_virtual + MEM_INTMEM_START +
149 RESERVED_SIZE);
136} 150}
137 151
138 152module_init(crisv32_intmem_init);
139 153
diff --git a/arch/cris/arch-v32/mm/l2cache.c b/arch/cris/arch-v32/mm/l2cache.c
new file mode 100644
index 000000000000..332ff10dcc6b
--- /dev/null
+++ b/arch/cris/arch-v32/mm/l2cache.c
@@ -0,0 +1,29 @@
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/string.h>
4#include <memmap.h>
5#include <hwregs/reg_map.h>
6#include <hwregs/reg_rdwr.h>
7#include <hwregs/l2cache_defs.h>
8#include <asm/io.h>
9
10#define L2CACHE_SIZE 64
11
12int __init l2cache_init(void)
13{
14 reg_l2cache_rw_ctrl ctrl = {0};
15 reg_l2cache_rw_cfg cfg = {.en = regk_l2cache_yes};
16
17 ctrl.csize = L2CACHE_SIZE;
18 ctrl.cbase = L2CACHE_SIZE / 4 + (L2CACHE_SIZE % 4 ? 1 : 0);
19 REG_WR(l2cache, regi_l2cache, rw_ctrl, ctrl);
20
21 /* Flush the tag memory */
22 memset((void *)(MEM_INTMEM_START | MEM_NON_CACHEABLE), 0, 2*1024);
23
24 /* Enable the cache */
25 REG_WR(l2cache, regi_l2cache, rw_cfg, cfg);
26
27 return 0;
28}
29
diff --git a/arch/cris/arch-v32/mm/mmu.S b/arch/cris/arch-v32/mm/mmu.S
index 27b70e5006af..2238d154bde3 100644
--- a/arch/cris/arch-v32/mm/mmu.S
+++ b/arch/cris/arch-v32/mm/mmu.S
@@ -1,3 +1,5 @@
1; WARNING : The refill handler has been modified, see below !!!
2
1/* 3/*
2 * Copyright (C) 2003 Axis Communications AB 4 * Copyright (C) 2003 Axis Communications AB
3 * 5 *
@@ -61,6 +63,14 @@
61; Note that the code is optimized to minimize stalls (makes the code harder 63; Note that the code is optimized to minimize stalls (makes the code harder
62; to read). 64; to read).
63; 65;
66; WARNING !!!
67; Modified by Mikael Asker 060725: added a workaround for strange TLB
68; behavior. If the same PTE is present in more than one set, the TLB
69; doesn't recognize it and we get stuck in a loop of refill exceptions.
70; The workaround detects such loops and exits them by flushing
71; the TLB contents. The problem and workaround were verified
72; in VCS by Mikael Starvik.
73;
64; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each 74; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
65; PMD holds 16 MB of virtual memory. 75; PMD holds 16 MB of virtual memory.
66; Bits 0-12 : Offset within a page 76; Bits 0-12 : Offset within a page
@@ -68,6 +78,11 @@
68; Bits 24-31 : PMD offset within the PGD 78; Bits 24-31 : PMD offset within the PGD
69 79
70.macro MMU_REFILL_HANDLER handler, mmu 80.macro MMU_REFILL_HANDLER handler, mmu
81 .data
821: .dword 0 ; refill_count
83 ; == 0 <=> last_refill_cause is invalid
842: .dword 0 ; last_refill_cause
85 .text
71 .globl \handler 86 .globl \handler
72\handler: 87\handler:
73 subq 4, $sp 88 subq 4, $sp
@@ -76,42 +91,96 @@
76 subq 4, $sp 91 subq 4, $sp
77 move \mmu, $srs ; Select MMU support register bank 92 move \mmu, $srs ; Select MMU support register bank
78 move.d $acr, [$sp] 93 move.d $acr, [$sp]
79 subq 4, $sp 94 subq 12, $sp
80 move.d $r0, [$sp] 95 move.d 1b, $acr ; Point to refill_count
96 movem $r2, [$sp]
97
98 test.d [$acr] ; refill_count == 0 ?
99 beq 5f ; yes, last_refill_cause is invalid
100 move.d $acr, $r1
101
102 ; last_refill_cause is valid, investigate cause
103 addq 4, $r1 ; Point to last_refill_cause
104 move $s3, $r0 ; Get rw_mm_cause
105 move.d [$r1], $r2 ; Get last_refill_cause
106 cmp.d $r0, $r2 ; rw_mm_cause == last_refill_cause ?
107 beq 6f ; yes, increment count
108 moveq 1, $r2
109
110 ; rw_mm_cause != last_refill_cause
111 move.d $r2, [$acr] ; refill_count = 1
112 move.d $r0, [$r1] ; last_refill_cause = rw_mm_cause
113
1143: ; Probably not in a loop, continue normal processing
81#ifdef CONFIG_SMP 115#ifdef CONFIG_SMP
82 move $s7, $acr ; PGD 116 move $s7, $acr ; PGD
83#else 117#else
84 move.d per_cpu__current_pgd, $acr ; PGD 118 move.d per_cpu__current_pgd, $acr ; PGD
85#endif 119#endif
86 ; Look up PMD in PGD 120 ; Look up PMD in PGD
87 move $s3, $r0 ; rw_mm_cause
88 lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31) 121 lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31)
89 move.d [$acr], $acr ; PGD for the current process 122 move.d [$acr], $acr ; PGD for the current process
90 addi $r0.d, $acr, $acr 123 addi $r0.d, $acr, $acr
91 move $s3, $r0 ; rw_mm_cause 124 move $s3, $r0 ; rw_mm_cause
92 move.d [$acr], $acr ; Get PMD 125 move.d [$acr], $acr ; Get PMD
93 beq 1f 126 beq 8f
94 ; Look up PTE in PMD 127 ; Look up PTE in PMD
95 lsrq PAGE_SHIFT, $r0 128 lsrq PAGE_SHIFT, $r0
96 and.w PAGE_MASK, $acr ; Remove PMD flags 129 and.w PAGE_MASK, $acr ; Remove PMD flags
97 and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23) 130 and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23)
98 addi $r0.d, $acr, $acr 131 addi $r0.d, $acr, $acr
99 move.d [$acr], $acr ; Get PTE 132 move.d [$acr], $acr ; Get PTE
100 beq 2f 133 beq 9f
101 move.d [$sp+], $r0 ; Pop r0 in delayslot 134 movem [$sp], $r2 ; Restore r0-r2 in delay slot
135 addq 12, $sp
102 ; Store in TLB 136 ; Store in TLB
103 move $acr, $s5 137 move $acr, $s5
104 ; Return 1384: ; Return
105 move.d [$sp+], $acr 139 move.d [$sp+], $acr
106 move [$sp], $srs 140 move [$sp], $srs
107 addq 4, $sp 141 addq 4, $sp
108 rete 142 rete
109 rfe 143 rfe
1101: ; PMD missing, let the mm subsystem fix it up. 144
111 move.d [$sp+], $r0 ; Pop r0 1455: ; last_refill_cause is invalid
1122: ; PTE missing, let the mm subsystem fix it up. 146 moveq 1, $r2
147 addq 4, $r1 ; Point to last_refill_cause
148 move.d $r2, [$acr] ; refill_count = 1
149 move $s3, $r0 ; Get rw_mm_cause
150 ba 3b ; Continue normal processing
151 move.d $r0,[$r1] ; last_refill_cause = rw_mm_cause
152
1536: ; rw_mm_cause == last_refill_cause
154 move.d [$acr], $r2 ; Get refill_count
155 cmpq 4, $r2 ; refill_count > 4 ?
156 bhi 7f ; yes
157 addq 1, $r2 ; refill_count++
158 ba 3b ; Continue normal processing
159 move.d $r2, [$acr]
160
1617: ; refill_count > 4, error
162 move.d $acr, $r0 ; Save pointer to refill_count
163 clear.d [$r0] ; refill_count = 0
164
165 ;; rewind the short stack
166 movem [$sp], $r2 ; Restore r0-r2
167 addq 12, $sp
168 move.d [$sp+], $acr
169 move [$sp], $srs
170 addq 4, $sp
171 ;; Keep it simple (slow), save all the regs.
172 SAVE_ALL
173 jsr __flush_tlb_all
174 nop
175 ba ret_from_intr ; Return
176 nop
177
1788: ; PMD missing, let the mm subsystem fix it up.
179 movem [$sp], $r2 ; Restore r0-r2
1809: ; PTE missing, let the mm subsystem fix it up.
181 addq 12, $sp
113 move.d [$sp+], $acr 182 move.d [$sp+], $acr
114 move [$sp], $srs 183 move [$sp], $srs
115 addq 4, $sp 184 addq 4, $sp
116 SAVE_ALL 185 SAVE_ALL
117 move \mmu, $srs 186 move \mmu, $srs
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index a076ef6e9389..eda5ebcaea54 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -13,8 +13,8 @@
13#include <asm/arch/hwregs/supp_reg.h> 13#include <asm/arch/hwregs/supp_reg.h>
14 14
15#define UPDATE_TLB_SEL_IDX(val) \ 15#define UPDATE_TLB_SEL_IDX(val) \
16do { \ 16do { \
17 unsigned long tlb_sel; \ 17 unsigned long tlb_sel; \
18 \ 18 \
19 tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, val); \ 19 tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, val); \
20 SUPP_REG_WR(RW_MM_TLB_SEL, tlb_sel); \ 20 SUPP_REG_WR(RW_MM_TLB_SEL, tlb_sel); \
@@ -30,8 +30,8 @@ do { \
30 * The TLB can host up to 256 different mm contexts at the same time. The running 30 * The TLB can host up to 256 different mm contexts at the same time. The running
31 * context is found in the PID register. Each TLB entry contains a page_id that 31 * context is found in the PID register. Each TLB entry contains a page_id that
32 * has to match the PID register to give a hit. page_id_map keeps track of which 32 * has to match the PID register to give a hit. page_id_map keeps track of which
33 * mm is assigned to which page_id, making sure it's known when to invalidate TLB 33 * mm's is assigned to which page_id's, making sure it's known when to
34 * entries. 34 * invalidate TLB entries.
35 * 35 *
36 * The last page_id is never running, it is used as an invalid page_id so that 36 * The last page_id is never running, it is used as an invalid page_id so that
37 * it's possible to make TLB entries that will nerver match. 37 * it's possible to make TLB entries that will nerver match.
@@ -179,29 +179,29 @@ void
179switch_mm(struct mm_struct *prev, struct mm_struct *next, 179switch_mm(struct mm_struct *prev, struct mm_struct *next,
180 struct task_struct *tsk) 180 struct task_struct *tsk)
181{ 181{
182 int cpu = smp_processor_id(); 182 if (prev != next) {
183 183 int cpu = smp_processor_id();
184 /* Make sure there is a MMU context. */ 184
185 spin_lock(&mmu_context_lock); 185 /* Make sure there is a MMU context. */
186 get_mmu_context(next); 186 spin_lock(&mmu_context_lock);
187 cpu_set(cpu, next->cpu_vm_mask); 187 get_mmu_context(next);
188 spin_unlock(&mmu_context_lock); 188 cpu_set(cpu, next->cpu_vm_mask);
189 189 spin_unlock(&mmu_context_lock);
190 /* 190
191 * Remember the pgd for the fault handlers. Keep a separate copy of it 191 /*
192 * because current and active_mm might be invalid at points where 192 * Remember the pgd for the fault handlers. Keep a seperate
193 * there's still a need to derefer the pgd. 193 * copy of it because current and active_mm might be invalid
194 */ 194 * at points where * there's still a need to derefer the pgd.
195 per_cpu(current_pgd, cpu) = next->pgd; 195 */
196 196 per_cpu(current_pgd, cpu) = next->pgd;
197 /* Switch context in the MMU. */ 197
198 if (tsk && task_thread_info(tsk)) 198 /* Switch context in the MMU. */
199 { 199 if (tsk && task_thread_info(tsk)) {
200 SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls); 200 SPEC_REG_WR(SPEC_REG_PID, next->context.page_id |
201 } 201 task_thread_info(tsk)->tls);
202 else 202 } else {
203 { 203 SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
204 SPEC_REG_WR(SPEC_REG_PID, next->context.page_id); 204 }
205 } 205 }
206} 206}
207 207
diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S
index fead8c59ea63..d5f28e40717c 100644
--- a/arch/cris/arch-v32/vmlinux.lds.S
+++ b/arch/cris/arch-v32/vmlinux.lds.S
@@ -9,6 +9,13 @@
9 */ 9 */
10 10
11#include <asm-generic/vmlinux.lds.h> 11#include <asm-generic/vmlinux.lds.h>
12#include <asm/page.h>
13
14#ifdef CONFIG_ETRAX_VMEM_SIZE
15#define __CONFIG_ETRAX_VMEM_SIZE CONFIG_ETRAX_VMEM_SIZE
16#else
17#define __CONFIG_ETRAX_VMEM_SIZE 0
18#endif
12 19
13jiffies = jiffies_64; 20jiffies = jiffies_64;
14SECTIONS 21SECTIONS
@@ -17,18 +24,19 @@ SECTIONS
17 dram_start = .; 24 dram_start = .;
18 ebp_start = .; 25 ebp_start = .;
19 26
20 /* The boot section is only necessary until the VCS top level testbench */ 27 /* The boot section is only necessary until the VCS top */
21 /* includes both flash and DRAM. */ 28 /* level testbench includes both flash and DRAM. */
22 .boot : { *(.boot) } 29 .boot : { *(.boot) }
23 30
24 . = DRAM_VIRTUAL_BASE + 0x4000; /* See head.S and pages reserved at the start. */ 31 /* See head.S and pages reserved at the start. */
32 . = DRAM_VIRTUAL_BASE + 0x4000;
25 33
26 _text = .; /* Text and read-only data. */ 34 _text = .; /* Text and read-only data. */
27 text_start = .; /* Lots of aliases. */ 35 text_start = .; /* Lots of aliases. */
28 _stext = .; 36 _stext = .;
29 __stext = .; 37 __stext = .;
30 .text : { 38 .text : {
31 *(.text) 39 TEXT_TEXT
32 SCHED_TEXT 40 SCHED_TEXT
33 LOCK_TEXT 41 LOCK_TEXT
34 *(.fixup) 42 *(.fixup)
@@ -39,9 +47,9 @@ SECTIONS
39 __etext = .; 47 __etext = .;
40 48
41 . = ALIGN(4); /* Exception table. */ 49 . = ALIGN(4); /* Exception table. */
42 __start___ex_table = .; 50 __start___ex_table = .;
43 __ex_table : { *(__ex_table) } 51 __ex_table : { *(__ex_table) }
44 __stop___ex_table = .; 52 __stop___ex_table = .;
45 53
46 RODATA 54 RODATA
47 55
@@ -54,33 +62,27 @@ SECTIONS
54 __edata = . ; /* End of data section. */ 62 __edata = . ; /* End of data section. */
55 _edata = . ; 63 _edata = . ;
56 64
57 . = ALIGN(8192); /* init_task and stack, must be aligned. */ 65 . = ALIGN(PAGE_SIZE); /* init_task and stack, must be aligned. */
58 .data.init_task : { *(.data.init_task) } 66 .data.init_task : { *(.data.init_task) }
59 67
60 . = ALIGN(8192); /* Init code and data. */ 68 . = ALIGN(PAGE_SIZE); /* Init code and data. */
61 __init_begin = .; 69 __init_begin = .;
62 .init.text : { 70 .init.text : {
63 _sinittext = .; 71 _sinittext = .;
64 INIT_TEXT 72 INIT_TEXT
65 _einittext = .; 73 _einittext = .;
66 } 74 }
67 .init.data : { INIT_DATA } 75 .init.data : { INIT_DATA }
68 . = ALIGN(16); 76 . = ALIGN(16);
69 __setup_start = .; 77 __setup_start = .;
70 .init.setup : { *(.init.setup) } 78 .init.setup : { *(.init.setup) }
71 __setup_end = .; 79 __setup_end = .;
72 __start___param = .; 80 __start___param = .;
73 __param : { *(__param) } 81 __param : { *(__param) }
74 __stop___param = .; 82 __stop___param = .;
75 .initcall.init : { 83 .initcall.init : {
76 __initcall_start = .; 84 __initcall_start = .;
77 *(.initcall1.init); 85 INITCALLS
78 *(.initcall2.init);
79 *(.initcall3.init);
80 *(.initcall4.init);
81 *(.initcall5.init);
82 *(.initcall6.init);
83 *(.initcall7.init);
84 __initcall_end = .; 86 __initcall_end = .;
85 } 87 }
86 88
@@ -91,25 +93,23 @@ SECTIONS
91 } 93 }
92 SECURITY_INIT 94 SECURITY_INIT
93 95
94 PERCPU(8192) 96 __vmlinux_end = .; /* Last address of the physical file. */
97 PERCPU(PAGE_SIZE)
95 98
96#ifdef CONFIG_BLK_DEV_INITRD
97 .init.ramfs : { 99 .init.ramfs : {
98 __initramfs_start = .; 100 __initramfs_start = .;
99 *(.init.ramfs) 101 *(.init.ramfs)
100 __initramfs_end = .; 102 __initramfs_end = .;
101 /*
102 * We fill to the next page, so we can discard all init
103 * pages without needing to consider what payload might be
104 * appended to the kernel image.
105 */
106 FILL (0);
107 . = ALIGN (8192);
108 } 103 }
109#endif
110 104
111 __vmlinux_end = .; /* Last address of the physical file. */ 105 /*
112 __init_end = .; 106 * We fill to the next page, so we can discard all init
107 * pages without needing to consider what payload might be
108 * appended to the kernel image.
109 */
110 . = ALIGN (PAGE_SIZE);
111
112 __init_end = .;
113 113
114 __data_end = . ; /* Move to _edata? */ 114 __data_end = . ; /* Move to _edata? */
115 __bss_start = .; /* BSS. */ 115 __bss_start = .; /* BSS. */
@@ -123,11 +123,11 @@ SECTIONS
123 __end = .; 123 __end = .;
124 124
125 /* Sections to be discarded */ 125 /* Sections to be discarded */
126 /DISCARD/ : { 126 /DISCARD/ : {
127 EXIT_TEXT 127 EXIT_TEXT
128 EXIT_DATA 128 EXIT_DATA
129 *(.exitcall.exit) 129 *(.exitcall.exit)
130 } 130 }
131 131
132 dram_end = dram_start + CONFIG_ETRAX_DRAM_SIZE*1024*1024; 132 dram_end = dram_start + (CONFIG_ETRAX_DRAM_SIZE - __CONFIG_ETRAX_VMEM_SIZE)*1024*1024;
133} 133}