enable start-stop-daemon by default, i want to use this to clean up a few init script...
[15.05/openwrt.git] / target / linux / etrax-2.6 / patches / cris / 002-arch-cris.patch
1 diff -urN linux-2.6.19.2.old/arch/cris/Kconfig linux-2.6.19.2.dev/arch/cris/Kconfig
2 --- linux-2.6.19.2.old/arch/cris/Kconfig        2007-01-10 20:10:37.000000000 +0100
3 +++ linux-2.6.19.2.dev/arch/cris/Kconfig        2007-01-17 18:17:18.000000000 +0100
4 @@ -16,6 +16,10 @@
5  config RWSEM_XCHGADD_ALGORITHM
6         bool
7  
8 +config GENERIC_IOMAP
9 +       bool
10 +       default y
11 +
12  config GENERIC_FIND_NEXT_BIT
13         bool
14         default y
15 @@ -42,6 +46,29 @@
16  
17  source "fs/Kconfig.binfmt"
18  
19 +config GENERIC_HARDIRQS
20 +       bool
21 +       default y
22 +
23 +config SMP
24 +       bool "SMP"
25 +       help
26 +         SMP support. Always Say N.
27 +
28 +config NR_CPUS
29 +       int
30 +       depends on SMP
31 +       default 2
32 +
33 +config SCHED_MC
34 +       bool "Multi-core scheduler support"
35 +       depends on SMP
36 +       default y
37 +       help
38 +         Multi-core scheduler support improves the CPU scheduler's decision
39 +         making when dealing with multi-core CPU chips at a cost of slightly
40 +         increased overhead in some places. If unsure say N here.
41 +
42  config ETRAX_CMDLINE
43         string "Kernel command line"
44         default "root=/dev/mtdblock3"
45 @@ -70,17 +97,11 @@
46          timers).
47          This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
48  
49 -config PREEMPT
50 -       bool "Preemptible Kernel"
51 -       help
52 -         This option reduces the latency of the kernel when reacting to
53 -         real-time or interactive events by allowing a low priority process to
54 -         be preempted even if it is in kernel mode executing a system call.
55 -         This allows applications to run more reliably even when the system is
56 -         under load.
57 +config OOM_REBOOT
58 +       bool "Enable reboot at out of memory"
59  
60 -         Say Y here if you are building a kernel for a desktop, embedded
61 -         or real-time system.  Say N if you are unsure.
62 +source "kernel/Kconfig.preempt"
63 +source "kernel/Kconfig.sched"
64  
65  source mm/Kconfig
66  
67 @@ -107,6 +128,16 @@
68         help
69           Support the xsim ETRAX Simulator.
70  
71 +config ETRAXFS
72 +       bool "ETRAX-FS-V32"
73 +       help
74 +         Support CRIS V32.
75 +
76 +config ETRAXFS_SIM
77 +       bool "ETRAX-FS-V32-Simulator"
78 +       help
79 +         Support CRIS V32 VCS simualtor.
80 +
81  endchoice
82  
83  config ETRAX_ARCH_V10
84 @@ -114,6 +145,11 @@
85         default y if ETRAX100LX || ETRAX100LX_V2
86         default n if !(ETRAX100LX || ETRAX100LX_V2)
87  
88 +config ETRAX_ARCH_V32
89 +       bool
90 +       default y if ETRAXFS || ETRAXFS_SIM
91 +       default n if !(ETRAXFS || ETRAXFS_SIM) 
92 +
93  config ETRAX_DRAM_SIZE
94         int "DRAM size (dec, in MB)"
95         default "8"
96 @@ -121,12 +157,23 @@
97           Size of DRAM (decimal in MB) typically 2, 8 or 16.
98  
99  config ETRAX_FLASH_BUSWIDTH
100 -       int "Buswidth of flash in bytes"
101 +       int "Buswidth of NOR flash in bytes"
102         default "2"
103         help
104 -         Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
105 +         Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
106  
107 -source arch/cris/arch-v10/Kconfig
108 +config ETRAX_NANDFLASH_BUSWIDTH
109 +       int "Buswidth of NAND flash in bytes"
110 +       default "1"
111 +       help
112 +         Width in bytes of the NAND flash (1 or 2).
113 +
114 +config ETRAX_FLASH1_SIZE
115 +       int "FLASH1 size (dec, in MB. 0 = Unknown)"
116 +       default "0"
117 +
118 +# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
119 +source arch/cris/arch/Kconfig
120  
121  endmenu
122  
123 @@ -134,7 +181,8 @@
124  
125  # bring in ETRAX built-in drivers
126  menu "Drivers for built-in interfaces"
127 -source arch/cris/arch-v10/drivers/Kconfig
128 +# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
129 +source arch/cris/arch/drivers/Kconfig
130  
131  endmenu
132  
133 @@ -181,6 +229,10 @@
134  
135  source "sound/Kconfig"
136  
137 +source "drivers/pcmcia/Kconfig"
138 +
139 +source "drivers/pci/Kconfig"
140 +
141  source "drivers/usb/Kconfig"
142  
143  source "arch/cris/Kconfig.debug"
144 diff -urN linux-2.6.19.2.old/arch/cris/Kconfig.debug linux-2.6.19.2.dev/arch/cris/Kconfig.debug
145 --- linux-2.6.19.2.old/arch/cris/Kconfig.debug  2007-01-10 20:10:37.000000000 +0100
146 +++ linux-2.6.19.2.dev/arch/cris/Kconfig.debug  2005-10-31 09:48:02.000000000 +0100
147 @@ -1,14 +1,15 @@
148  menu "Kernel hacking"
149  
150 +source "lib/Kconfig.debug"
151 +
152  #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
153 +
154  config PROFILING
155         bool "Kernel profiling support"
156  
157  config SYSTEM_PROFILER
158         bool "System profiling support"
159  
160 -source "lib/Kconfig.debug"
161 -
162  config ETRAX_KGDB
163         bool "Use kernel GDB debugger"
164         depends on DEBUG_KERNEL
165 diff -urN linux-2.6.19.2.old/arch/cris/Makefile linux-2.6.19.2.dev/arch/cris/Makefile
166 --- linux-2.6.19.2.old/arch/cris/Makefile       2007-01-10 20:10:37.000000000 +0100
167 +++ linux-2.6.19.2.dev/arch/cris/Makefile       2006-11-29 17:05:40.000000000 +0100
168 @@ -1,4 +1,4 @@
169 -# $Id: Makefile,v 1.28 2005/03/17 10:44:37 larsv Exp $
170 +# $Id: Makefile,v 1.41 2006/11/29 16:05:40 ricardw Exp $
171  # cris/Makefile
172  #
173  # This file is included by the global makefile so that you can add your own
174 @@ -10,14 +10,11 @@
175  # License.  See the file "COPYING" in the main directory of this archive
176  # for more details.
177  
178 -# A bug in ld prevents us from having a (constant-value) symbol in a
179 -# "ORIGIN =" or "LENGTH =" expression.
180 -
181  arch-y := v10
182  arch-$(CONFIG_ETRAX_ARCH_V10) := v10
183  arch-$(CONFIG_ETRAX_ARCH_V32) := v32
184  
185 -# No config avaiable for make clean etc
186 +# No config available for make clean etc
187  ifneq ($(arch-y),)
188  SARCH := arch-$(arch-y)
189  else
190 @@ -52,79 +49,58 @@
191  # cris object files path
192  OBJ_ARCH              = $(objtree)/arch/$(ARCH)
193  
194 -target_boot_arch_dir  = $(OBJ_ARCH)/$(SARCH)/boot
195 -target_boot_dir       = $(OBJ_ARCH)/boot
196 -src_boot_dir          = $(SRC_ARCH)/boot
197 -target_compressed_dir = $(OBJ_ARCH)/boot/compressed
198 -src_compressed_dir    = $(SRC_ARCH)/boot/compressed
199 -target_rescue_dir     = $(OBJ_ARCH)/boot/rescue
200 -src_rescue_dir        = $(SRC_ARCH)/boot/rescue
201 -
202 -export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir
203 -
204 -vmlinux.bin: vmlinux
205 -       $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin
206 -
207 -timage: vmlinux.bin
208 -       cat vmlinux.bin cramfs.img >timage
209 -
210 -simimage: timage
211 -       cp vmlinux.bin simvmlinux.bin
212 -
213 -# the following will remake timage without compiling the kernel
214 -# it does of course require that all object files exist...
215 -
216 -cramfs:
217 -## cramfs      - Creates a cramfs image
218 -       mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img
219 -       cat vmlinux.bin cramfs.img >timage
220 -
221 -clinux: vmlinux.bin decompress.bin rescue.bin
222 -
223 -decompress.bin: $(target_boot_dir)
224 -       @$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin
225 -
226 -$(target_rescue_dir)/rescue.bin: $(target_boot_dir)
227 -       @$(MAKE) -f $(src_rescue_dir)/Makefile $(target_rescue_dir)/rescue.bin
228 +boot := arch/$(ARCH)/boot
229 +MACHINE := arch/$(ARCH)/$(SARCH)
230  
231 -zImage: $(target_boot_dir) vmlinux.bin $(target_rescue_dir)/rescue.bin
232 -## zImage     - Compressed kernel (gzip)
233 -       @$(MAKE) -f $(src_boot_dir)/Makefile zImage
234 +all: zImage
235  
236 -$(target_boot_dir): $(target_boot_arch_dir)
237 -       ln -sfn $< $@
238 -
239 -$(target_boot_arch_dir):
240 -       mkdir -p $@
241 -
242 -compressed: zImage
243 -
244 -archmrproper:
245 -archclean:
246 -       @if [ -d arch/$(ARCH)/boot ]; then \
247 -               $(MAKE) $(clean)=arch/$(ARCH)/boot ; \
248 -       fi
249 -       rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img
250 -       rm -rf $(LD_SCRIPT).tmp
251 +zImage Image: vmlinux 
252 +       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
253  
254  archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch
255  
256  # Create some links to make all tools happy
257  $(SRC_ARCH)/.links:
258         @rm -rf $(SRC_ARCH)/drivers
259 -       @ln -sfn $(SRC_ARCH)/$(SARCH)/drivers $(SRC_ARCH)/drivers
260 +       @ln -sfn $(SARCH)/drivers $(SRC_ARCH)/drivers
261         @rm -rf $(SRC_ARCH)/boot
262 -       @ln -sfn $(SRC_ARCH)/$(SARCH)/boot $(SRC_ARCH)/boot
263 +       @ln -sfn $(SARCH)/boot $(SRC_ARCH)/boot
264         @rm -rf $(SRC_ARCH)/lib
265 -       @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
266 -       @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
267 -       @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
268 -       @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
269 +       @ln -sfn $(SARCH)/lib $(SRC_ARCH)/lib
270 +       @rm -rf $(SRC_ARCH)/arch
271 +       @ln -sfn $(SARCH) $(SRC_ARCH)/arch
272 +       @rm -rf $(SRC_ARCH)/kernel/vmlinux.lds.S
273 +       @ln -sfn ../$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
274 +       @rm -rf $(SRC_ARCH)/kernel/asm-offsets.c
275 +       @ln -sfn ../$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
276         @touch $@
277  
278  # Create link to sub arch includes
279  $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
280 -       @echo '  Making $(srctree)/include/asm-$(ARCH)/arch -> $(srctree)/include/asm-$(ARCH)/$(SARCH) symlink'
281 +       @echo '  SYMLINK include/asm-$(ARCH)/arch -> include/asm-$(ARCH)/$(SARCH)'
282         @rm -f include/asm-$(ARCH)/arch
283 -       @ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch
284 +       @ln -sf $(SARCH) $(srctree)/include/asm-$(ARCH)/arch
285         @touch $@
286 +
287 +archclean:
288 +       $(Q)if [ -e arch/$(ARCH)/boot ]; then \
289 +               $(MAKE) $(clean)=arch/$(ARCH)/boot; \
290 +       fi
291 +
292 +CLEAN_FILES += \
293 +       $(MACHINE)/boot/zImage \
294 +       $(SRC_ARCH)/.links \
295 +       $(srctree)/include/asm-$(ARCH)/.arch
296 +
297 +MRPROPER_FILES += \
298 +       $(SRC_ARCH)/drivers \
299 +       $(SRC_ARCH)/boot \
300 +       $(SRC_ARCH)/lib \
301 +       $(SRC_ARCH)/arch \
302 +       $(SRC_ARCH)/kernel/vmlinux.lds.S \
303 +       $(SRC_ARCH)/kernel/asm-offsets.c
304 +
305 +define archhelp
306 +  echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
307 +  echo  '* Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
308 +endef
309 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/README.mm linux-2.6.19.2.dev/arch/cris/arch-v10/README.mm
310 --- linux-2.6.19.2.old/arch/cris/arch-v10/README.mm     2007-01-10 20:10:37.000000000 +0100
311 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/README.mm     2005-08-23 11:44:32.000000000 +0200
312 @@ -3,6 +3,9 @@
313  HISTORY:
314  
315  $Log: README.mm,v $
316 +Revision 1.2  2005/08/23 09:44:32  starvik
317 +extern inline -> static inline. Patch provided by Adrian Bunk <bunk@stusta.de>
318 +
319  Revision 1.1  2001/12/17 13:59:27  bjornw
320  Initial revision
321  
322 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/Makefile
323 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/Makefile 2007-01-10 20:10:37.000000000 +0100
324 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/Makefile 2006-11-29 17:05:40.000000000 +0100
325 @@ -1,13 +1,21 @@
326  #
327 -# arch/cris/boot/Makefile
328 +# arch/cris/arch-v10/boot/Makefile
329  #
330 -target = $(target_boot_dir)
331 -src    = $(src_boot_dir)
332  
333 -zImage: compressed/vmlinuz
334 +OBJCOPY = objcopy-cris
335 +OBJCOPYFLAGS = -O binary --remove-section=.bss
336  
337 -compressed/vmlinuz:
338 -       @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz
339 +subdir- := compressed rescue
340 +targets := Image
341  
342 -clean:
343 -       @$(MAKE) -f $(src)/compressed/Makefile clean
344 +$(obj)/Image: vmlinux FORCE
345 +       $(call if_changed,objcopy)
346 +       @echo '  Kernel: $@ is ready'
347 +
348 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
349 +       $(Q)$(MAKE) $(build)=$(obj)/compressed $@
350 +       $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
351 +
352 +$(obj)/zImage:  $(obj)/compressed/vmlinux
353 +       @cp $< $@
354 +       @echo '  Kernel: $@ is ready'
355 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/Makefile
356 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/Makefile      2007-01-10 20:10:37.000000000 +0100
357 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/Makefile      2006-10-11 17:47:04.000000000 +0200
358 @@ -1,45 +1,34 @@
359  #
360 -# create a compressed vmlinuz image from the binary vmlinux.bin file
361 +# arch/cris/arch-v10/boot/compressed/Makefile
362  #
363 -target = $(target_compressed_dir)
364 -src    = $(src_compressed_dir)
365  
366  CC = gcc-cris -melf $(LINUXINCLUDE)
367  CFLAGS = -O2
368  LD = ld-cris
369 +LDFLAGS = -T $(obj)/decompress.ld
370 +OBJECTS = $(obj)/head.o $(obj)/misc.o
371  OBJCOPY = objcopy-cris
372  OBJCOPYFLAGS = -O binary --remove-section=.bss
373 -OBJECTS = $(target)/head.o $(target)/misc.o
374  
375 -# files to compress
376 -SYSTEM = $(objtree)/vmlinux.bin
377 +quiet_cmd_image = BUILD   $@
378 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
379  
380 -all: $(target_compressed_dir)/vmlinuz
381 +targets := vmlinux piggy.gz decompress.o decompress.bin
382  
383 -$(target)/decompress.bin: $(OBJECTS)
384 -       $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
385 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
386 +$(obj)/decompress.o: $(OBJECTS) FORCE
387 +       $(call if_changed,ld)
388  
389 -# Create vmlinuz image in top-level build directory
390 -$(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
391 -       @echo "  COMPR   vmlinux.bin --> vmlinuz"
392 -       @cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz
393 -       @rm -f piggy.img
394 +$(obj)/decompress.bin: $(obj)/decompress.o FORCE
395 +       $(call if_changed,objcopy)
396  
397 -$(target)/head.o: $(src)/head.S
398 -       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
399 +$(obj)/head.o: $(obj)/head.S .config
400 +       @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
401  
402 -$(target)/misc.o: $(src)/misc.c
403 -       $(CC) -D__KERNEL__ -c $< -o $@
404 +$(obj)/misc.o: $(obj)/misc.c .config
405 +       @$(CC) -D__KERNEL__ -c $< -o $@
406  
407 -# gzip the kernel image
408 -
409 -piggy.img: $(SYSTEM)
410 -       @cat $(SYSTEM) | gzip -f -9 > piggy.img
411 -
412 -$(target):
413 -       mkdir -p $(target)
414 -
415 -clean:
416 -       rm -f piggy.img $(objtree)/vmlinuz
417 +$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
418 +       $(call if_changed,image)
419  
420 +$(obj)/piggy.gz: $(obj)/../Image FORCE
421 +       $(call if_changed,gzip)
422 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/misc.c linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/misc.c
423 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/misc.c        2007-01-10 20:10:37.000000000 +0100
424 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/misc.c        2006-10-13 14:43:10.000000000 +0200
425 @@ -1,7 +1,7 @@
426  /*
427   * misc.c
428   *
429 - * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $
430 + * $Id: misc.c,v 1.7 2006/10/13 12:43:10 starvik Exp $
431   * 
432   * This is a collection of several routines from gzip-1.0.3 
433   * adapted for Linux.
434 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/Makefile
435 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/Makefile  2007-01-10 20:10:37.000000000 +0100
436 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/Makefile  2006-11-30 11:42:39.000000000 +0100
437 @@ -1,56 +1,38 @@
438  #
439 -# Makefile for rescue code
440 +# Makefile for rescue (bootstrap) code
441  #
442 -target = $(target_rescue_dir)
443 -src    = $(src_rescue_dir)
444  
445  CC = gcc-cris -mlinux $(LINUXINCLUDE)
446  CFLAGS = -O2
447 -LD = gcc-cris -mlinux -nostdlib
448 +AFLAGS = -traditional
449 +LD = gcc-cris -mlinux -nostdlib 
450 +LDFLAGS = -T $(obj)/rescue.ld
451  OBJCOPY = objcopy-cris
452  OBJCOPYFLAGS = -O binary --remove-section=.bss
453 +obj-y = head.o
454 +OBJECT = $(obj)/$(obj-y)
455  
456 -all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin
457 +targets := rescue.o rescue.bin
458  
459 -$(target)/rescue.bin: $(target) $(target)/head.o
460 -       $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
461 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
462 -# Place a copy in top-level build directory
463 -       cp -p $(target)/rescue.bin $(objtree)
464 +$(obj)/rescue.o: $(OBJECT) FORCE
465 +       $(call if_changed,ld)
466  
467 -$(target)/testrescue.bin: $(target) $(target)/testrescue.o
468 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin
469 +$(obj)/rescue.bin: $(obj)/rescue.o FORCE
470 +       $(call if_changed,objcopy)
471 +       cp -p $(obj)/rescue.bin $(objtree)
472 +
473 +$(obj)/testrescue.bin: $(obj)/testrescue.o
474 +       $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
475  # Pad it to 784 bytes
476         dd if=/dev/zero of=tmp2423 bs=1 count=784
477         cat tr.bin tmp2423 >testrescue_tmp.bin
478 -       dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784
479 +       dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
480         rm tr.bin tmp2423 testrescue_tmp.bin
481  
482 -$(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o
483 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin
484 +$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
485 +       $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
486  # Pad it to 784 bytes, that's what the rescue loader expects
487         dd if=/dev/zero of=tmp2423 bs=1 count=784
488         cat ktr.bin tmp2423 >kimagerescue_tmp.bin
489 -       dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784
490 +       dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
491         rm ktr.bin tmp2423 kimagerescue_tmp.bin
492 -
493 -$(target):
494 -       mkdir -p $(target)
495 -
496 -$(target)/head.o: $(src)/head.S
497 -       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
498 -
499 -$(target)/testrescue.o: $(src)/testrescue.S
500 -       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
501 -
502 -$(target)/kimagerescue.o: $(src)/kimagerescue.S
503 -       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
504 -
505 -clean:
506 -       rm -f $(target)/*.o $(target)/*.bin
507 -
508 -fastdep:
509 -
510 -modules:
511 -
512 -modules-install:
513 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/head.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/head.S
514 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/head.S    2007-01-10 20:10:37.000000000 +0100
515 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/head.S    2006-10-13 14:43:10.000000000 +0200
516 @@ -1,4 +1,4 @@
517 -/* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $
518 +/* $Id: head.S,v 1.9 2006/10/13 12:43:10 starvik Exp $
519   * 
520   * Rescue code, made to reside at the beginning of the
521   * flash-memory. when it starts, it checks a partition
522 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/kimagerescue.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/kimagerescue.S
523 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/kimagerescue.S    2007-01-10 20:10:37.000000000 +0100
524 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/kimagerescue.S    2006-11-29 17:05:41.000000000 +0100
525 @@ -1,4 +1,4 @@
526 -/* $Id: kimagerescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
527 +/* $Id: kimagerescue.S,v 1.3 2006/11/29 16:05:41 ricardw Exp $
528   * 
529   * Rescue code to be prepended on a kimage and copied to the
530   * rescue serial port.
531 @@ -7,7 +7,7 @@
532   */
533  
534  #define ASSEMBLER_MACROS_ONLY
535 -#include <asm/sv_addr_ag.h>
536 +#include <asm/arch/sv_addr_ag.h>
537  
538  #define CODE_START 0x40004000
539  #define CODE_LENGTH 784
540 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/testrescue.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/testrescue.S
541 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/testrescue.S      2007-01-10 20:10:37.000000000 +0100
542 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/testrescue.S      2006-11-29 17:05:41.000000000 +0100
543 @@ -1,4 +1,4 @@
544 -/* $Id: testrescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
545 +/* $Id: testrescue.S,v 1.2 2006/11/29 16:05:41 ricardw Exp $
546   *
547   * Simple testcode to download by the rescue block.
548   * Just lits some LEDs to show it was downloaded correctly.
549 @@ -7,7 +7,7 @@
550   */
551  
552  #define ASSEMBLER_MACROS_ONLY
553 -#include <asm/sv_addr_ag.h>
554 +#include <asm/arch/sv_addr_ag.h>
555  
556         .text
557  
558 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/defconfig linux-2.6.19.2.dev/arch/cris/arch-v10/defconfig
559 --- linux-2.6.19.2.old/arch/cris/arch-v10/defconfig     2007-01-10 20:10:37.000000000 +0100
560 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/defconfig     2006-01-03 15:48:23.000000000 +0100
561 @@ -106,7 +106,6 @@
562  CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
563  # CONFIG_ETRAX_I2C_EEPROM is not set
564  CONFIG_ETRAX_GPIO=y
565 -CONFIG_ETRAX_PA_BUTTON_BITMASK=02
566  CONFIG_ETRAX_PA_CHANGEABLE_DIR=00
567  CONFIG_ETRAX_PA_CHANGEABLE_BITS=FF
568  CONFIG_ETRAX_PB_CHANGEABLE_DIR=00
569 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Kconfig
570 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Kconfig       2007-01-10 20:10:37.000000000 +0100
571 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Kconfig       2007-01-09 10:29:18.000000000 +0100
572 @@ -6,6 +6,12 @@
573           This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
574           controller.
575  
576 +config ETRAX_NO_PHY
577 +       bool "PHY not present"
578 +       depends on ETRAX_ETHERNET
579 +       help
580 +         Enable if PHY is not present.
581 +
582  choice
583         prompt "Network LED behavior"
584         depends on ETRAX_ETHERNET
585 @@ -90,7 +96,7 @@
586  
587  config ETRAX_SERIAL_PORT0_DMA6_OUT
588         bool "DMA 6"
589 -
590 +       depends on !ETRAX_DEBUG_PORT0
591  endchoice
592  
593  choice
594 @@ -103,7 +109,7 @@
595  
596  config ETRAX_SERIAL_PORT0_DMA7_IN
597         bool "DMA 7"
598 -
599 +       depends on !ETRAX_DEBUG_PORT0
600  endchoice
601  
602  choice
603 @@ -204,7 +210,7 @@
604  
605  config ETRAX_SERIAL_PORT1_DMA8_OUT
606         bool "DMA 8"
607 -
608 +       depends on !ETRAX_DEBUG_PORT1
609  endchoice
610  
611  choice
612 @@ -217,7 +223,7 @@
613  
614  config ETRAX_SERIAL_PORT1_DMA9_IN
615         bool "DMA 9"
616 -
617 +       depends on !ETRAX_DEBUG_PORT1
618  endchoice
619  
620  choice
621 @@ -321,7 +327,7 @@
622  
623  config ETRAX_SERIAL_PORT2_DMA2_OUT
624         bool "DMA 2"
625 -
626 +       depends on !ETRAX_DEBUG_PORT2
627  endchoice
628  
629  choice
630 @@ -334,7 +340,7 @@
631  
632  config ETRAX_SERIAL_PORT2_DMA3_IN
633         bool "DMA 3"
634 -
635 +       depends on !ETRAX_DEBUG_PORT2
636  endchoice
637  
638  choice
639 @@ -435,7 +441,7 @@
640  
641  config ETRAX_SERIAL_PORT3_DMA4_OUT
642         bool "DMA 4"
643 -
644 +       depends on !ETRAX_DEBUG_PORT3
645  endchoice
646  
647  choice
648 @@ -448,7 +454,7 @@
649  
650  config ETRAX_SERIAL_PORT3_DMA5_IN
651         bool "DMA 5"
652 -
653 +       depends on !ETRAX_DEBUG_PORT3
654  endchoice
655  
656  choice
657 @@ -514,8 +520,7 @@
658         bool "RS-485 support"
659         depends on ETRAX_SERIAL
660         help
661 -         Enables support for RS-485 serial communication.  For a primer on
662 -         RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
663 +         Enables support for RS-485 serial communication.
664  
665  config ETRAX_RS485_ON_PA
666         bool "RS-485 mode on PA"
667 @@ -541,6 +546,27 @@
668           loopback.  Not all products are able to do this in software only.
669           Axis 2400/2401 must disable receiver.
670  
671 +config ETRAX_SYNCHRONOUS_SERIAL
672 +      bool "Synchronous serial port driver"
673 +      help
674 +          Select this to enable the synchronous serial port driver.
675 +
676 +config ETRAX_SYNCHRONOUS_SERIAL_PORT0
677 +       bool "Synchronous serial port 0 enabled (sser1)"
678 +       depends on ETRAX_SYNCHRONOUS_SERIAL
679 +
680 +config ETRAX_SYNCHRONOUS_SERIAL0_DMA
681 +       bool "Use DMA for synchronous serial port 0"
682 +       depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
683 +
684 +config ETRAX_SYNCHRONOUS_SERIAL_PORT1
685 +       bool "Synchronous serial port 1 enabled (sser3)"
686 +       depends on ETRAX_SYNCHRONOUS_SERIAL
687 +
688 +config ETRAX_SYNCHRONOUS_SERIAL1_DMA
689 +       bool "Use DMA for synchronous serial port 1"
690 +       depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
691 +
692  config ETRAX_IDE
693         bool "ATA/IDE support"
694         select IDE
695 @@ -604,8 +630,7 @@
696         select MTD
697         select MTD_CFI
698         select MTD_CFI_AMDSTD
699 -       select MTD_OBSOLETE_CHIPS
700 -       select MTD_AMDSTD
701 +       select MTD_JEDECPROBE
702         select MTD_CHAR
703         select MTD_BLOCK
704         select MTD_PARTITIONS
705 @@ -615,6 +640,15 @@
706           This option enables MTD mapping of flash devices.  Needed to use
707           flash memories.  If unsure, say Y.
708  
709 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
710 +       bool "MTD0 is whole boot flash device"
711 +       depends on ETRAX_AXISFLASHMAP
712 +       default N
713 +       help
714 +         When this option is not set, mtd0 refers to the first partition
715 +         on the boot flash device. When set, mtd0 refers to the whole
716 +         device, with mtd1 referring to the first partition etc.
717 +
718  config ETRAX_PTABLE_SECTOR
719         int "Byte-offset of partition table sector"
720         depends on ETRAX_AXISFLASHMAP
721 @@ -715,19 +749,6 @@
722           Remember that you need to setup the port directions appropriately in
723           the General configuration.
724  
725 -config ETRAX_PA_BUTTON_BITMASK
726 -       hex "PA-buttons bitmask"
727 -       depends on ETRAX_GPIO
728 -       default "02"
729 -       help
730 -         This is a bitmask with information about what bits on PA that
731 -         are used for buttons.
732 -         Most products has a so called TEST button on PA1, if that's true
733 -         use 02 here.
734 -         Use 00 if there are no buttons on PA.
735 -         If the bitmask is <> 00 a button driver will be included in the gpio
736 -         driver. ETRAX general I/O support must be enabled.
737 -
738  config ETRAX_PA_CHANGEABLE_DIR
739         hex "PA user changeable dir mask"
740         depends on ETRAX_GPIO
741 @@ -768,6 +789,40 @@
742           Bit set = changeable.
743           You probably want 00 here.
744  
745 +config ETRAX_DEF_R_PORT_G_DIR
746 +        bool "Port G Output"
747 +       help
748 +         CONFIG_ETRAX_DEF_R_PORT_G_DIR:
749 +         Set the direction of specified pins to output.
750 +
751 +config ETRAX_DEF_R_PORT_G0_DIR_OUT
752 +        bool "G0"
753 +        depends on ETRAX_DEF_R_PORT_G_DIR
754 +       help
755 +         CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT:
756 +         Set G0 to output.
757 +
758 +config ETRAX_DEF_R_PORT_G8_15_DIR_OUT
759 +        bool "G8-G15"
760 +        depends on ETRAX_DEF_R_PORT_G_DIR
761 +       help
762 +         CONFIG_ETRAX_DEF_R_PORT_G8_15_DIR_OUT:
763 +         Set G8-G15 to output.
764 +
765 +config ETRAX_DEF_R_PORT_G16_23_DIR_OUT
766 +        bool "G16-G23"
767 +        depends on ETRAX_DEF_R_PORT_G_DIR
768 +       help
769 +         CONFIG_ETRAX_DEF_R_PORT_G16_23_DIR_OUT:
770 +         Set G16-G23 to output.
771 +
772 +config ETRAX_DEF_R_PORT_G24_DIR_OUT
773 +        bool "G24"
774 +        depends on ETRAX_DEF_R_PORT_G_DIR
775 +       help
776 +         CONFIG_ETRAX_DEF_R_PORT_G24_DIR_OUT:
777 +         Set G24 to output.
778 +
779  config ETRAX_RTC
780         bool "Real Time Clock support"
781         depends on ETRAX_ARCH_V10
782 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Makefile
783 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Makefile      2007-01-10 20:10:37.000000000 +0100
784 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Makefile      2005-12-12 10:05:46.000000000 +0100
785 @@ -8,5 +8,5 @@
786  obj-$(CONFIG_ETRAX_GPIO)               += gpio.o
787  obj-$(CONFIG_ETRAX_DS1302)              += ds1302.o
788  obj-$(CONFIG_ETRAX_PCF8563)            += pcf8563.o
789 -
790 +obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL)  += sync_serial.o
791  
792 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/axisflashmap.c
793 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/axisflashmap.c        2007-01-10 20:10:37.000000000 +0100
794 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/axisflashmap.c        2006-11-22 13:26:55.000000000 +0100
795 @@ -11,6 +11,26 @@
796   * partition split defined below.
797   *
798   * $Log: axisflashmap.c,v $
799 + * Revision 1.17  2006/11/22 12:26:55  ricardw
800 + * Added CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE option which when enabled puts mtd0
801 + * as whole device, with first partition at mtd1, etc.
802 + *
803 + * Revision 1.16  2006/10/30 15:17:57  pkj
804 + * Avoid a compiler warning.
805 + *
806 + * Revision 1.15  2006/10/13 12:43:10  starvik
807 + * Merge of 2.6.18
808 + *
809 + * Revision 1.14  2006/08/30 13:20:00  karljope
810 + * Do not use deprecated amd_flash to probe flash memory.
811 + * Probe for flash chip with CFI first and if no chip was found try jedec_probe.
812 + *
813 + * Revision 1.13  2006/01/04 06:09:45  starvik
814 + * Merge of Linux 2.6.15
815 + *
816 + * Revision 1.12  2005/06/21 09:13:06  starvik
817 + * Change const char* to const char[] to save space (from domen@coderock.org).
818 + *
819   * Revision 1.11  2004/11/15 10:27:14  starvik
820   * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>).
821   *
822 @@ -300,6 +320,15 @@
823         },
824  };
825  
826 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
827 +/* Main flash device */
828 +static struct mtd_partition main_partition = {
829 +       .name = "main",
830 +       .size = 0,
831 +       .offset = 0
832 +};
833 +#endif
834 +
835  /*
836   * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
837   * chips in that order (because the amd_flash-driver is faster).
838 @@ -312,12 +341,12 @@
839                 "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
840                map_cs->name, map_cs->size, map_cs->map_priv_1);
841  
842 -#ifdef CONFIG_MTD_AMDSTD
843 -       mtd_cs = do_map_probe("amd_flash", map_cs);
844 -#endif
845  #ifdef CONFIG_MTD_CFI
846 +       mtd_cs = do_map_probe("cfi_probe", map_cs);
847 +#endif
848 +#ifdef CONFIG_MTD_JEDECPROBE
849         if (!mtd_cs) {
850 -               mtd_cs = do_map_probe("cfi_probe", map_cs);
851 +               mtd_cs = do_map_probe("jedec_probe", map_cs);
852         }
853  #endif
854  
855 @@ -396,7 +425,7 @@
856         struct partitiontable_head *ptable_head = NULL;
857         struct partitiontable_entry *ptable;
858         int use_default_ptable = 1; /* Until proven otherwise. */
859 -       const char *pmsg = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
860 +       const char pmsg[] = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
861  
862         if (!(mymtd = flash_probe())) {
863                 /* There's no reason to use this module if no flash chip can
864 @@ -491,6 +520,16 @@
865                 pidx++;
866         }
867  
868 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
869 +       if (mymtd) {
870 +               main_partition.size = mymtd->size;
871 +                err = add_mtd_partitions(mymtd, &main_partition, 1);
872 +               if (err)
873 +                       panic("axisflashmap: Could not initialize "
874 +                             "partition for whole main mtd device!\n");
875 +       }
876 +#endif
877 +
878          if (mymtd) {
879                 if (use_default_ptable) {
880                         printk(KERN_INFO " Using default partition table.\n");
881 @@ -524,7 +563,7 @@
882                 }
883  
884                 printk(KERN_INFO " Adding RAM partition for romfs image:\n");
885 -               printk(pmsg, pidx, romfs_start, romfs_length);
886 +               printk(pmsg, pidx, (unsigned)romfs_start, (unsigned)romfs_length);
887  
888                 err = mtdram_init_device(mtd_ram, (void*)romfs_start, 
889                                          romfs_length, "romfs");
890 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/ds1302.c
891 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/ds1302.c      2007-01-10 20:10:37.000000000 +0100
892 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/ds1302.c      2006-10-27 16:31:23.000000000 +0200
893 @@ -6,136 +6,9 @@
894  *!
895  *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
896  *!
897 -*! $Log: ds1302.c,v $
898 -*! Revision 1.18  2005/01/24 09:11:26  mikaelam
899 -*! Minor changes to get DS1302 RTC chip driver to work
900 -*!
901 -*! Revision 1.17  2005/01/05 06:11:22  starvik
902 -*! No need to do local_irq_disable after local_irq_save.
903 -*!
904 -*! Revision 1.16  2004/12/13 12:21:52  starvik
905 -*! Added I/O and DMA allocators from Linux 2.4
906 -*!
907 -*! Revision 1.14  2004/08/24 06:48:43  starvik
908 -*! Whitespace cleanup
909 -*!
910 -*! Revision 1.13  2004/05/28 09:26:59  starvik
911 -*! Modified I2C initialization to work in 2.6.
912 -*!
913 -*! Revision 1.12  2004/05/14 07:58:03  starvik
914 -*! Merge of changes from 2.4
915 -*!
916 -*! Revision 1.10  2004/02/04 09:25:12  starvik
917 -*! Merge of Linux 2.6.2
918 -*!
919 -*! Revision 1.9  2003/07/04 08:27:37  starvik
920 -*! Merge of Linux 2.5.74
921 -*!
922 -*! Revision 1.8  2003/04/09 05:20:47  starvik
923 -*! Merge of Linux 2.5.67
924 -*!
925 -*! Revision 1.6  2003/01/09 14:42:51  starvik
926 -*! Merge of Linux 2.5.55
927 -*!
928 -*! Revision 1.4  2002/12/11 13:13:57  starvik
929 -*! Added arch/ to v10 specific includes
930 -*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
931 -*!
932 -*! Revision 1.3  2002/11/20 11:56:10  starvik
933 -*! Merge of Linux 2.5.48
934 -*!
935 -*! Revision 1.2  2002/11/18 13:16:06  starvik
936 -*! Linux 2.5 port of latest 2.4 drivers
937 -*!
938 -*! Revision 1.15  2002/10/11 16:14:33  johana
939 -*! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the
940 -*! trcklecharge register.
941 -*!
942 -*! Revision 1.14  2002/10/10 12:15:38  magnusmn
943 -*! Added support for having the RST signal on bit g0
944 -*!
945 -*! Revision 1.13  2002/05/29 15:16:08  johana
946 -*! Removed unused variables.
947 -*!
948 -*! Revision 1.12  2002/04/10 15:35:25  johana
949 -*! Moved probe function closer to init function and marked it __init.
950 -*!
951 -*! Revision 1.11  2001/06/14 12:35:52  jonashg
952 -*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
953 -*!
954 -*! Revision 1.9  2001/06/14 10:00:14  jonashg
955 -*! No need for tempudelay to be inline anymore (had to adjust the usec to
956 -*! loops conversion because of this to make it slow enough to be a udelay).
957 -*!
958 -*! Revision 1.8  2001/06/14 08:06:32  jonashg
959 -*! Made tempudelay delay usecs (well, just a tad more).
960 -*!
961 -*! Revision 1.7  2001/06/13 14:18:11  jonashg
962 -*! Only allow processes with SYS_TIME capability to set time and charge.
963 -*!
964 -*! Revision 1.6  2001/06/12 15:22:07  jonashg
965 -*! * Made init function __init.
966 -*! * Parameter to out_byte() is unsigned char.
967 -*! * The magic number 42 has got a name.
968 -*! * Removed comment about /proc (nothing is exported there).
969 -*!
970 -*! Revision 1.5  2001/06/12 14:35:13  jonashg
971 -*! Gave the module a name and added it to printk's.
972 -*!
973 -*! Revision 1.4  2001/05/31 14:53:40  jonashg
974 -*! Made tempudelay() inline so that the watchdog doesn't reset (see
975 -*! function comment).
976 -*!
977 -*! Revision 1.3  2001/03/26 16:03:06  bjornw
978 -*! Needs linux/config.h
979 -*!
980 -*! Revision 1.2  2001/03/20 19:42:00  bjornw
981 -*! Use the ETRAX prefix on the DS1302 options
982 -*!
983 -*! Revision 1.1  2001/03/20 09:13:50  magnusmn
984 -*! Linux 2.4 port
985 -*!
986 -*! Revision 1.10  2000/07/05 15:38:23  bjornw
987 -*! Dont update kernel time when a RTC_SET_TIME is done
988 -*!
989 -*! Revision 1.9  2000/03/02 15:42:59  macce
990 -*! * Hack to make RTC work on all 2100/2400
991 -*!
992 -*! Revision 1.8  2000/02/23 16:59:18  torbjore
993 -*! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
994 -*!
995 -*! Revision 1.7  2000/01/17 15:51:43  johana
996 -*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
997 -*!
998 -*! Revision 1.6  1999/10/27 13:19:47  bjornw
999 -*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
1000 -*! /dev/rtc calls it now.
1001 -*!
1002 -*! Revision 1.5  1999/10/27 12:39:37  bjornw
1003 -*! Disabled superuser check. Anyone can now set the time.
1004 -*!
1005 -*! Revision 1.4  1999/09/02 13:27:46  pkj
1006 -*! Added shadow for R_PORT_PB_CONFIG.
1007 -*! Renamed port_g_shadow to port_g_data_shadow.
1008 -*!
1009 -*! Revision 1.3  1999/09/02 08:28:06  pkj
1010 -*! Made it possible to select either port PB or the generic port for the RST
1011 -*! signal line to the DS1302 RTC.
1012 -*! Also make sure the RST bit is configured as output on Port PB (if used).
1013 -*!
1014 -*! Revision 1.2  1999/09/01 14:47:20  bjornw
1015 -*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
1016 -*! and set the date. Register as major 121.
1017 -*!
1018 -*! Revision 1.1  1999/09/01 09:45:29  bjornw
1019 -*! Implemented a DS1302 RTC driver.
1020 -*!
1021 -*!
1022  *! ---------------------------------------------------------------------------
1023  *!
1024 -*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004  Axis Communications AB, LUND, SWEDEN
1025 -*!
1026 -*! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $
1027 +*! (C) Copyright 1999-2006 Axis Communications AB, LUND, SWEDEN
1028  *!
1029  *!***************************************************************************/
1030  
1031 @@ -305,14 +178,7 @@
1032  void
1033  ds1302_writereg(int reg, unsigned char val) 
1034  {
1035 -#ifndef CONFIG_ETRAX_RTC_READONLY
1036         int do_writereg = 1;
1037 -#else
1038 -       int do_writereg = 0;
1039 -
1040 -       if (reg == RTC_TRICKLECHARGER)
1041 -               do_writereg = 1;
1042 -#endif
1043  
1044         if (do_writereg) {
1045                 ds1302_wenable();
1046 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/eeprom.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/eeprom.c
1047 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/eeprom.c      2007-01-10 20:10:37.000000000 +0100
1048 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/eeprom.c      2006-10-13 14:43:10.000000000 +0200
1049 @@ -20,6 +20,9 @@
1050  *!                                  in the spin-lock.
1051  *!
1052  *!  $Log: eeprom.c,v $
1053 +*!  Revision 1.13  2006/10/13 12:43:10  starvik
1054 +*!  Merge of 2.6.18
1055 +*!
1056  *!  Revision 1.12  2005/06/19 17:06:46  starvik
1057  *!  Merge of Linux 2.6.12.
1058  *!
1059 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/gpio.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/gpio.c
1060 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/gpio.c        2007-01-10 20:10:37.000000000 +0100
1061 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/gpio.c        2007-02-05 12:54:34.000000000 +0100
1062 @@ -1,4 +1,4 @@
1063 -/* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $
1064 +/* $Id: gpio.c,v 1.28 2007/02/05 11:54:34 pkj Exp $
1065   *
1066   * Etrax general port I/O device
1067   *
1068 @@ -9,6 +9,40 @@
1069   *             Johan Adolfsson  (read/set directions, write, port G)
1070   *
1071   * $Log: gpio.c,v $
1072 + * Revision 1.28  2007/02/05 11:54:34  pkj
1073 + * Merge of Linux 2.6.19
1074 + *
1075 + * Revision 1.27  2006/12/12 11:08:30  edgar
1076 + * In etrax_gpio_wake_up_check(), make flags unsigned long.
1077 + *
1078 + * Revision 1.26  2006/11/02 10:54:29  pkj
1079 + * Restored unique device id for request_irq() which was lost in the
1080 + * merge of 2.6.18.
1081 + *
1082 + * Revision 1.25  2006/10/13 12:43:10  starvik
1083 + * Merge of 2.6.18
1084 + *
1085 + * Revision 1.24  2006/07/13 07:42:20  starvik
1086 + * Set unique device id in request_irq
1087 + *
1088 + * Revision 1.23  2006/06/21 09:38:46  starvik
1089 + * Use correct spinlock macros
1090 + *
1091 + * Revision 1.22  2005/08/29 07:32:16  starvik
1092 + * Merge of 2.6.13
1093 + *
1094 + * Revision 1.21  2005/08/16 17:10:54  edgar
1095 + * dont leave locked spinlocks when returning.
1096 + *
1097 + * Revision 1.20  2005/08/15 13:10:47  orjanf
1098 + * Don't link struct into alarmlist until fully initialized.
1099 + *
1100 + * Revision 1.19  2005/07/13 11:43:11  karljope
1101 + * Corrected typo
1102 + *
1103 + * Revision 1.18  2005/06/21 12:26:53  starvik
1104 + * Improved alarm list locking.
1105 + *
1106   * Revision 1.17  2005/06/19 17:06:46  starvik
1107   * Merge of Linux 2.6.12.
1108   *
1109 @@ -277,7 +311,7 @@
1110         unsigned int mask = 0;
1111         struct gpio_private *priv = (struct gpio_private *)file->private_data;
1112         unsigned long data;
1113 -       spin_lock(&gpio_lock);
1114 +       spin_lock_irq(&gpio_lock);
1115         poll_wait(file, &priv->alarm_wq, wait);
1116         if (priv->minor == GPIO_MINOR_A) {
1117                 unsigned long flags;
1118 @@ -297,15 +331,17 @@
1119                 data = *R_PORT_PB_DATA;
1120         else if (priv->minor == GPIO_MINOR_G)
1121                 data = *R_PORT_G_DATA;
1122 -       else
1123 +       else {
1124 +               spin_unlock_irq(&gpio_lock);
1125                 return 0;
1126 +       }
1127         
1128         if ((data & priv->highalarm) ||
1129             (~data & priv->lowalarm)) {
1130                 mask = POLLIN|POLLRDNORM;
1131         }
1132  
1133 -       spin_unlock(&gpio_lock);
1134 +       spin_unlock_irq(&gpio_lock);
1135         
1136         DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
1137  
1138 @@ -314,10 +350,12 @@
1139  
1140  int etrax_gpio_wake_up_check(void)
1141  {
1142 -       struct gpio_private *priv = alarmlist;
1143 +       struct gpio_private *priv;
1144         unsigned long data = 0;
1145          int ret = 0;
1146 -       spin_lock(&gpio_lock);
1147 +       unsigned long flags;
1148 +       spin_lock_irqsave(&gpio_lock, flags);
1149 +       priv = alarmlist;
1150         while (priv) {
1151                 if (USE_PORTS(priv)) {
1152                         data = *priv->port;
1153 @@ -332,12 +370,12 @@
1154                 }
1155                 priv = priv->next;
1156         }
1157 -       spin_unlock(&gpio_lock);
1158 +       spin_unlock_irqrestore(&gpio_lock, flags);
1159          return ret;
1160  }
1161  
1162  static irqreturn_t
1163 -gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1164 +gpio_poll_timer_interrupt(int irq, void *dev_id)
1165  {
1166         if (gpio_some_alarms) {
1167                 etrax_gpio_wake_up_check();
1168 @@ -347,7 +385,7 @@
1169  }
1170  
1171  static irqreturn_t
1172 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1173 +gpio_pa_interrupt(int irq, void *dev_id)
1174  {
1175         unsigned long tmp;
1176         spin_lock(&gpio_lock);
1177 @@ -376,9 +414,6 @@
1178         struct gpio_private *priv = (struct gpio_private *)file->private_data;
1179         unsigned char data, clk_mask, data_mask, write_msb;
1180         unsigned long flags;
1181 -
1182 -       spin_lock(&gpio_lock);
1183 -
1184         ssize_t retval = count;
1185         if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
1186                 return -EFAULT;
1187 @@ -394,6 +429,7 @@
1188         if (clk_mask == 0 || data_mask == 0) {
1189                 return -EPERM;
1190         }
1191 +       spin_lock_irq(&gpio_lock);
1192         write_msb = priv->write_msb;
1193         D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
1194         while (count--) {
1195 @@ -425,7 +461,7 @@
1196                         }
1197                 }
1198         }
1199 -       spin_unlock(&gpio_lock);
1200 +       spin_unlock_irq(&gpio_lock);
1201         return retval;
1202  }
1203  
1204 @@ -445,13 +481,12 @@
1205  
1206         if (!priv)
1207                 return -ENOMEM;
1208 +       memset(priv, 0, sizeof(*priv));
1209  
1210         priv->minor = p;
1211  
1212 -       /* initialize the io/alarm struct and link it into our alarmlist */
1213 +       /* initialize the io/alarm struct */
1214  
1215 -       priv->next = alarmlist;
1216 -       alarmlist = priv;
1217         if (USE_PORTS(priv)) { /* A and B */
1218                 priv->port = ports[p];
1219                 priv->shadow = shads[p];
1220 @@ -476,6 +511,12 @@
1221  
1222         filp->private_data = (void *)priv;
1223  
1224 +       /* link it into our alarmlist */
1225 +       spin_lock_irq(&gpio_lock);
1226 +       priv->next = alarmlist;
1227 +       alarmlist = priv;
1228 +       spin_unlock_irq(&gpio_lock);
1229 +
1230         return 0;
1231  }
1232  
1233 @@ -485,10 +526,10 @@
1234         struct gpio_private *p;
1235         struct gpio_private *todel;
1236  
1237 -       spin_lock(&gpio_lock);
1238 +       spin_lock_irq(&gpio_lock);
1239  
1240 -        p = alarmlist;
1241 -        todel = (struct gpio_private *)filp->private_data;
1242 +       p = alarmlist;
1243 +       todel = (struct gpio_private *)filp->private_data;
1244  
1245         /* unlink from alarmlist and free the private structure */
1246  
1247 @@ -506,12 +547,13 @@
1248         while (p) {
1249                 if (p->highalarm | p->lowalarm) {
1250                         gpio_some_alarms = 1;
1251 +                       spin_unlock_irq(&gpio_lock);    
1252                         return 0;
1253                 }
1254                 p = p->next;
1255         }
1256         gpio_some_alarms = 0;
1257 -       spin_unlock(&gpio_lock);
1258 +       spin_unlock_irq(&gpio_lock);    
1259         return 0;
1260  }
1261  
1262 @@ -691,6 +733,8 @@
1263                         /* Must update gpio_some_alarms */
1264                         struct gpio_private *p = alarmlist;
1265                         int some_alarms;
1266 +                       spin_lock_irq(&gpio_lock);
1267 +                       p = alarmlist;
1268                         some_alarms = 0;
1269                         while (p) {
1270                                 if (p->highalarm | p->lowalarm) {
1271 @@ -700,6 +744,7 @@
1272                                 p = p->next;
1273                         }
1274                         gpio_some_alarms = some_alarms;
1275 +                       spin_unlock_irq(&gpio_lock);
1276                 }
1277                 break;
1278         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
1279 @@ -937,11 +982,11 @@
1280          * in some tests.
1281          */  
1282         if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
1283 -                       IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) {
1284 +                       IRQF_SHARED | IRQF_DISABLED,"gpio poll", gpio_name)) {
1285                 printk(KERN_CRIT "err: timer0 irq for gpio\n");
1286         }
1287         if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
1288 -                       IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) {
1289 +                       IRQF_SHARED | IRQF_DISABLED,"gpio PA", gpio_name)) {
1290                 printk(KERN_CRIT "err: PA irq for gpio\n");
1291         }
1292         
1293 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/i2c.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/i2c.c
1294 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/i2c.c 2007-01-10 20:10:37.000000000 +0100
1295 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/i2c.c 2006-10-13 14:43:10.000000000 +0200
1296 @@ -11,7 +11,25 @@
1297  *! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff - 
1298  *!                                 don't use PB_I2C if DS1302 uses same bits,
1299  *!                                 use PB.
1300 +*! June 23 2003 Pieter Grimmerink  Added 'i2c_sendnack'. i2c_readreg now
1301 +*!                                 generates nack on last received byte, 
1302 +*!                                 instead of ack.
1303 +*!                                 i2c_getack changed data level while clock
1304 +*!                                 was high, causing DS75 to see  a stop condition
1305 +*!
1306  *! $Log: i2c.c,v $
1307 +*! Revision 1.17  2006/10/13 12:43:10  starvik
1308 +*! Merge of 2.6.18
1309 +*!
1310 +*! Revision 1.16  2005/09/29 13:33:35  bjarne
1311 +*! If "first" should have any purpos it should probably change value....
1312 +*!
1313 +*! Revision 1.15  2005/08/29 07:32:16  starvik
1314 +*! Merge of 2.6.13
1315 +*!
1316 +*! Revision 1.14  2005/06/30 18:07:31  starvik
1317 +*! Added the sendnack patch from 2.4.
1318 +*!
1319  *! Revision 1.13  2005/03/07 13:13:07  starvik
1320  *! Added spinlocks to protect states etc
1321  *!
1322 @@ -84,7 +102,7 @@
1323  *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
1324  *!
1325  *!***************************************************************************/
1326 -/* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */
1327 +/* $Id: i2c.c,v 1.17 2006/10/13 12:43:10 starvik Exp $ */
1328  
1329  /****************** INCLUDE FILES SECTION ***********************************/
1330  
1331 @@ -480,7 +498,7 @@
1332         i2c_delay(CLOCK_HIGH_TIME);
1333         i2c_clk(I2C_CLOCK_LOW);
1334         i2c_delay(CLOCK_LOW_TIME);
1335 -
1336 +       
1337         i2c_dir_in();
1338  }
1339  
1340 @@ -622,7 +640,7 @@
1341                  * last received byte needs to be nacked
1342                  * instead of acked
1343                  */
1344 -               i2c_sendack();
1345 +               i2c_sendnack();
1346                 /*
1347                  * end sequence
1348                  */
1349 @@ -708,6 +726,7 @@
1350         if (!first) {
1351                 return res;
1352         }
1353 +       first = 0;
1354  
1355         /* Setup and enable the Port B I2C interface */
1356  
1357 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/pcf8563.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/pcf8563.c
1358 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/pcf8563.c     2007-01-10 20:10:37.000000000 +0100
1359 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/pcf8563.c     2006-10-27 17:22:12.000000000 +0200
1360 @@ -8,14 +8,13 @@
1361   * low detector are also provided. All address and data are transferred
1362   * serially via two-line bidirectional I2C-bus. Maximum bus speed is
1363   * 400 kbits/s. The built-in word address register is incremented
1364 - * automatically after each written or read bute.
1365 + * automatically after each written or read byte.
1366   *
1367 - * Copyright (c) 2002, Axis Communications AB
1368 + * Copyright (c) 2002-2006, Axis Communications AB
1369   * All rights reserved.
1370   *
1371   * Author: Tobias Anderberg <tobiasa@axis.com>.
1372   *
1373 - * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $
1374   */
1375  
1376  #include <linux/module.h>
1377 @@ -27,93 +26,105 @@
1378  #include <linux/ioctl.h>
1379  #include <linux/delay.h>
1380  #include <linux/bcd.h>
1381 -#include <linux/capability.h>
1382  
1383  #include <asm/uaccess.h>
1384  #include <asm/system.h>
1385  #include <asm/io.h>
1386 -#include <asm/arch/svinto.h>
1387  #include <asm/rtc.h>
1388 +
1389  #include "i2c.h"
1390  
1391 -#define PCF8563_MAJOR 121              /* Local major number. */
1392 -#define DEVICE_NAME "rtc"              /* Name which is registered in /proc/devices. */
1393 -#define PCF8563_NAME "PCF8563"
1394 -#define DRIVER_VERSION "$Revision: 1.11 $"
1395 -
1396 -/* I2C bus slave registers. */
1397 -#define RTC_I2C_READ           0xa3
1398 -#define RTC_I2C_WRITE          0xa2
1399 +#define PCF8563_MAJOR  121     /* Local major number. */
1400 +#define DEVICE_NAME    "rtc"   /* Name which is registered in /proc/devices. */
1401 +#define PCF8563_NAME   "PCF8563"
1402 +#define DRIVER_VERSION "$Revision: 1.18 $"
1403  
1404  /* Two simple wrapper macros, saves a few keystrokes. */
1405  #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
1406  #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
1407  
1408  static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
1409 -       
1410 +
1411  static const unsigned char days_in_month[] =
1412         { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1413  
1414  int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
1415  
1416 +/* Cache VL bit value read at driver init since writing the RTC_SECOND 
1417 + * register clears the VL status.
1418 + */
1419 +static int voltage_low = 0;
1420 +
1421  static struct file_operations pcf8563_fops = {
1422 -       .owner = THIS_MODULE,
1423 -       .ioctl = pcf8563_ioctl,
1424 +       owner: THIS_MODULE,
1425 +       ioctl: pcf8563_ioctl,
1426  };
1427  
1428  unsigned char
1429 -pcf8563_readreg(int reg) 
1430 +pcf8563_readreg(int reg)
1431  {
1432 -       unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
1433 +       unsigned char res = rtc_read(reg);
1434  
1435 -       /* The PCF8563 does not return 0 for unimplemented bits */
1436 -       switch(reg)
1437 -       {
1438 +       /* The PCF8563 does not return 0 for unimplemented bits. */
1439 +       switch (reg) {
1440                 case RTC_SECONDS:
1441                 case RTC_MINUTES:
1442 -                    res &= 0x7f;
1443 -                    break;
1444 +                       res &= 0x7F;
1445 +                       break;
1446                 case RTC_HOURS:
1447                 case RTC_DAY_OF_MONTH:
1448 -                    res &= 0x3f;
1449 -                    break;
1450 +                       res &= 0x3F;
1451 +                       break;
1452 +               case RTC_WEEKDAY:
1453 +                       res &= 0x07;
1454 +                       break;
1455                 case RTC_MONTH:
1456 -                    res = (res & 0x1f) - 1;  /* PCF8563 returns month in range 1-12 */
1457 -                    break;
1458 +                       res &= 0x1F;
1459 +                       break;
1460 +               case RTC_CONTROL1:
1461 +                       res &= 0xA8;
1462 +                       break;
1463 +               case RTC_CONTROL2:
1464 +                       res &= 0x1F;
1465 +                       break;
1466 +               case RTC_CLOCKOUT_FREQ:
1467 +               case RTC_TIMER_CONTROL:
1468 +                       res &= 0x83;
1469 +                       break;
1470         }
1471         return res;
1472  }
1473  
1474  void
1475 -pcf8563_writereg(int reg, unsigned char val) 
1476 +pcf8563_writereg(int reg, unsigned char val)
1477  {
1478 -#ifdef CONFIG_ETRAX_RTC_READONLY
1479 -       if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
1480 -               return;
1481 -#endif
1482 -
1483         rtc_write(reg, val);
1484  }
1485  
1486  void
1487  get_rtc_time(struct rtc_time *tm)
1488  {
1489 -       tm->tm_sec = rtc_read(RTC_SECONDS);
1490 -       tm->tm_min = rtc_read(RTC_MINUTES);
1491 +       tm->tm_sec  = rtc_read(RTC_SECONDS);
1492 +       tm->tm_min  = rtc_read(RTC_MINUTES);
1493         tm->tm_hour = rtc_read(RTC_HOURS);
1494         tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
1495 -       tm->tm_mon = rtc_read(RTC_MONTH);
1496 +       tm->tm_wday = rtc_read(RTC_WEEKDAY);
1497 +       tm->tm_mon  = rtc_read(RTC_MONTH);
1498         tm->tm_year = rtc_read(RTC_YEAR);
1499  
1500 -       if (tm->tm_sec & 0x80)
1501 -               printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
1502 +       if (tm->tm_sec & 0x80) {
1503 +               printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
1504 +                      "information is no longer guaranteed!\n", PCF8563_NAME);
1505 +       }
1506  
1507 -       tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
1508 -       tm->tm_sec &= 0x7f;
1509 -       tm->tm_min &= 0x7f;
1510 -       tm->tm_hour &= 0x3f;
1511 -       tm->tm_mday &= 0x3f;
1512 -       tm->tm_mon &= 0x1f;
1513 +       tm->tm_year  = BCD_TO_BIN(tm->tm_year) +
1514 +                      ((tm->tm_mon & 0x80) ? 100 : 0);
1515 +       tm->tm_sec  &= 0x7F;
1516 +       tm->tm_min  &= 0x7F;
1517 +       tm->tm_hour &= 0x3F;
1518 +       tm->tm_mday &= 0x3F;
1519 +       tm->tm_wday &= 0x07; /* Not coded in BCD. */
1520 +       tm->tm_mon  &= 0x1F;
1521  
1522         BCD_TO_BIN(tm->tm_sec);
1523         BCD_TO_BIN(tm->tm_min);
1524 @@ -126,17 +137,25 @@
1525  int __init
1526  pcf8563_init(void)
1527  {
1528 -       int ret;
1529 +       static int res = 0;
1530 +       static int first = 1;
1531 +
1532 +       if (!first) {
1533 +               return res;
1534 +       }
1535 +       first = 0;
1536  
1537 -       if ((ret = i2c_init())) {
1538 -               printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
1539 -               return ret;
1540 +       /* Initiate the i2c protocol. */
1541 +       res = i2c_init();
1542 +       if (res < 0) {
1543 +               printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
1544 +               return res;
1545         }
1546  
1547         /*
1548          * First of all we need to reset the chip. This is done by
1549 -        * clearing control1, control2 and clk freq, clear the 
1550 -        * Voltage Low bit, and resetting all alarms.
1551 +        * clearing control1, control2 and clk freq and resetting
1552 +        * all alarms.
1553          */
1554         if (rtc_write(RTC_CONTROL1, 0x00) < 0)
1555                 goto err;
1556 @@ -147,41 +166,44 @@
1557         if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
1558                 goto err;
1559  
1560 -       /* Clear the VL bit in the seconds register. */
1561 -       ret = rtc_read(RTC_SECONDS);
1562 -       
1563 -       if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
1564 +       if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
1565                 goto err;
1566 -               
1567 +
1568         /* Reset the alarms. */
1569 -       if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
1570 +       if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
1571                 goto err;
1572 -       
1573 -       if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
1574 +
1575 +       if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
1576                 goto err;
1577 -       
1578 -       if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
1579 +
1580 +       if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
1581                 goto err;
1582 -       
1583 -       if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
1584 +
1585 +       if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
1586                 goto err;
1587 -        
1588 -       /* Check for low voltage, and warn about it.. */
1589 -       if (rtc_read(RTC_SECONDS) & 0x80)
1590 -               printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
1591 -       
1592 -       return 0;
1593 +
1594 +       /* Check for low voltage, and warn about it. */
1595 +       if (rtc_read(RTC_SECONDS) & 0x80) {
1596 +               voltage_low = 1;
1597 +               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1598 +                      "date/time information is no longer guaranteed!\n",
1599 +                      PCF8563_NAME);
1600 +       }
1601 +
1602 +       return res;
1603  
1604  err:
1605         printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
1606 -       return -1;
1607 +       res = -1;
1608 +       return res;
1609  }
1610  
1611  void __exit
1612  pcf8563_exit(void)
1613  {
1614         if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
1615 -               printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
1616 +               printk(KERN_INFO "%s: Unable to unregister device.\n",
1617 +                      PCF8563_NAME);
1618         }
1619  }
1620  
1621 @@ -190,7 +212,8 @@
1622   * POSIX says so!
1623   */
1624  int
1625 -pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
1626 +pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1627 +              unsigned long arg)
1628  {
1629         /* Some sanity checks. */
1630         if (_IOC_TYPE(cmd) != RTC_MAGIC)
1631 @@ -201,123 +224,151 @@
1632  
1633         switch (cmd) {
1634                 case RTC_RD_TIME:
1635 -                       {
1636 -                               struct rtc_time tm;
1637 -
1638 -                               spin_lock(&rtc_lock);
1639 -                               get_rtc_time(&tm);
1640 +               {
1641 +                       struct rtc_time tm;
1642  
1643 -                               if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
1644 -                                       spin_unlock(&rtc_lock);
1645 -                                       return -EFAULT;
1646 -                               }
1647 +                       spin_lock(&rtc_lock);
1648 +                       memset(&tm, 0, sizeof tm);
1649 +                       get_rtc_time(&tm);
1650  
1651 +                       if (copy_to_user((struct rtc_time *) arg, &tm,
1652 +                                        sizeof tm)) {
1653                                 spin_unlock(&rtc_lock);
1654 -                               return 0;
1655 +                               return -EFAULT;
1656                         }
1657 -                       break;
1658 +
1659 +                       spin_unlock(&rtc_lock);
1660 +
1661 +                       return 0;
1662 +               }
1663                 case RTC_SET_TIME:
1664 -                       {
1665 -#ifdef CONFIG_ETRAX_RTC_READONLY
1666 +               {
1667 +                       int leap;
1668 +                       int year;
1669 +                       int century;
1670 +                       struct rtc_time tm;
1671 +
1672 +                       memset(&tm, 0, sizeof tm);
1673 +                       if (!capable(CAP_SYS_TIME))
1674                                 return -EPERM;
1675 -#else
1676 -                               int leap;
1677 -                               int century;
1678 -                               struct rtc_time tm;
1679 -
1680 -                               memset(&tm, 0, sizeof (struct rtc_time));
1681 -                               if (!capable(CAP_SYS_TIME))
1682 -                                       return -EPERM;
1683 -
1684 -                               if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
1685 -                                       return -EFAULT;
1686 -
1687 -                               /* Convert from struct tm to struct rtc_time. */
1688 -                               tm.tm_year += 1900;
1689 -                               tm.tm_mon += 1;
1690 -                               
1691 -                               leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
1692 -
1693 -                               /* Perform some sanity checks. */
1694 -                               if ((tm.tm_year < 1970) ||
1695 -                                   (tm.tm_mon > 12) ||
1696 -                                   (tm.tm_mday == 0) ||
1697 -                                   (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
1698 -                                   (tm.tm_hour >= 24) ||
1699 -                                   (tm.tm_min >= 60) ||
1700 -                                   (tm.tm_sec >= 60))
1701 -                                       return -EINVAL;
1702 -
1703 -                               century = (tm.tm_year >= 2000) ? 0x80 : 0;
1704 -                               tm.tm_year = tm.tm_year % 100;
1705 -
1706 -                               BIN_TO_BCD(tm.tm_year);
1707 -                               BIN_TO_BCD(tm.tm_mday);
1708 -                               BIN_TO_BCD(tm.tm_hour);
1709 -                               BIN_TO_BCD(tm.tm_min);
1710 -                               BIN_TO_BCD(tm.tm_sec);
1711 -                               tm.tm_mon |= century;
1712 -
1713 -                               spin_lock(&rtc_lock);
1714 -                               
1715 -                               rtc_write(RTC_YEAR, tm.tm_year);
1716 -                               rtc_write(RTC_MONTH, tm.tm_mon);
1717 -                               rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
1718 -                               rtc_write(RTC_HOURS, tm.tm_hour);
1719 -                               rtc_write(RTC_MINUTES, tm.tm_min);
1720 -                               rtc_write(RTC_SECONDS, tm.tm_sec);
1721  
1722 -                               spin_unlock(&rtc_lock);
1723 +                       if (copy_from_user(&tm, (struct rtc_time *) arg,
1724 +                                          sizeof tm)) {
1725 +                               return -EFAULT;
1726 +                       }
1727  
1728 -                               return 0;
1729 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
1730 +                       /* Convert from struct tm to struct rtc_time. */
1731 +                       tm.tm_year += 1900;
1732 +                       tm.tm_mon += 1;
1733 +
1734 +                       /*
1735 +                        * Check if tm.tm_year is a leap year. A year is a leap
1736 +                        * year if it is divisible by 4 but not 100, except
1737 +                        * that years divisible by 400 _are_ leap years.
1738 +                        */
1739 +                       year = tm.tm_year;
1740 +                       leap = (tm.tm_mon == 2) && 
1741 +                               ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
1742 +
1743 +                       /* Perform some sanity checks. */
1744 +                       if ((tm.tm_year < 1970) ||
1745 +                           (tm.tm_mon > 12) ||
1746 +                           (tm.tm_mday == 0) ||
1747 +                           (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
1748 +                           (tm.tm_wday >= 7) ||
1749 +                           (tm.tm_hour >= 24) ||
1750 +                           (tm.tm_min >= 60) ||
1751 +                           (tm.tm_sec >= 60)) {
1752 +                               return -EINVAL;
1753                         }
1754  
1755 -               case RTC_VLOW_RD:
1756 -               {
1757 -                       int vl_bit = 0;
1758 +                       century = (tm.tm_year >= 2000) ? 0x80 : 0;
1759 +                       tm.tm_year = tm.tm_year % 100;
1760  
1761 -                       if (rtc_read(RTC_SECONDS) & 0x80) {
1762 -                               vl_bit = 1;
1763 -                               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1764 -                                      "date/time information is no longer guaranteed!\n",
1765 -                                      PCF8563_NAME);
1766 -                       }
1767 -                       if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
1768 -                               return -EFAULT;
1769 +                       BIN_TO_BCD(tm.tm_year);
1770 +                       BIN_TO_BCD(tm.tm_mon);
1771 +                       BIN_TO_BCD(tm.tm_mday);
1772 +                       BIN_TO_BCD(tm.tm_hour);
1773 +                       BIN_TO_BCD(tm.tm_min);
1774 +                       BIN_TO_BCD(tm.tm_sec);
1775 +                       tm.tm_mon |= century;
1776 +
1777 +                       spin_lock(&rtc_lock);
1778 +
1779 +                       rtc_write(RTC_YEAR, tm.tm_year);
1780 +                       rtc_write(RTC_MONTH, tm.tm_mon);
1781 +                       rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
1782 +                       rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
1783 +                       rtc_write(RTC_HOURS, tm.tm_hour);
1784 +                       rtc_write(RTC_MINUTES, tm.tm_min);
1785 +                       rtc_write(RTC_SECONDS, tm.tm_sec);
1786 +
1787 +                       spin_unlock(&rtc_lock);
1788  
1789                         return 0;
1790                 }
1791 +               case RTC_VLOW_RD:
1792 +                       if (voltage_low) {
1793 +                               printk(KERN_WARNING "%s: RTC Voltage Low - "
1794 +                                      "reliable date/time information is no "
1795 +                                      "longer guaranteed!\n", PCF8563_NAME);
1796 +                       }
1797 +
1798 +                       if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
1799 +                               return -EFAULT;
1800 +                       }
1801 +                       
1802 +                       return 0;
1803  
1804                 case RTC_VLOW_SET:
1805                 {
1806 -                       /* Clear the VL bit in the seconds register */
1807 +                       /* Clear the VL bit in the seconds register in case 
1808 +                        * the time has not been set already (which would
1809 +                        * have cleared it). This does not really matter 
1810 +                        * because of the cached voltage_low value but do it
1811 +                        * anyway for consistency. */
1812 +
1813                         int ret = rtc_read(RTC_SECONDS);
1814  
1815                         rtc_write(RTC_SECONDS, (ret & 0x7F));
1816  
1817 +                       /* Clear the cached value. */
1818 +                       voltage_low = 0;
1819 +
1820                         return 0;
1821                 }
1822 -
1823                 default:
1824 -                               return -ENOTTY;
1825 +                       return -ENOTTY;
1826         }
1827  
1828         return 0;
1829  }
1830  
1831 -static int __init
1832 +static int __init 
1833  pcf8563_register(void)
1834  {
1835 -       pcf8563_init();
1836 +       if (pcf8563_init() < 0) {
1837 +               printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
1838 +                      "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
1839 +               return -1;
1840 +       }
1841 +
1842         if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
1843 -               printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
1844 -                      PCF8563_NAME, PCF8563_MAJOR);
1845 +               printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
1846 +                      "device.\n", PCF8563_NAME, PCF8563_MAJOR);
1847                 return -1;
1848         }
1849  
1850 -       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
1851 -        return 0;
1852 +       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
1853 +              DRIVER_VERSION);
1854 +
1855 +       /* Check for low voltage, and warn about it. */
1856 +       if (voltage_low) {
1857 +               printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
1858 +                      "information is no longer guaranteed!\n", PCF8563_NAME);
1859 +       }
1860 +
1861 +       return 0;
1862  }
1863  
1864  module_init(pcf8563_register);
1865 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/sync_serial.c
1866 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/sync_serial.c 1970-01-01 01:00:00.000000000 +0100
1867 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/sync_serial.c 2007-02-05 12:56:34.000000000 +0100
1868 @@ -0,0 +1,1329 @@
1869 +/*  
1870 + * Simple synchronous serial port driver for ETRAX 100LX.
1871 + *
1872 + * Synchronous serial ports are used for continuous streamed data like audio.
1873 + * The default setting for this driver is compatible with the STA 013 MP3
1874 + * decoder. The driver can easily be tuned to fit other audio encoder/decoders
1875 + * and SPI
1876 + *
1877 + * Copyright (c) 2001-2006 Axis Communications AB
1878 + * 
1879 + * Author: Mikael Starvik, Johan Adolfsson
1880 + *
1881 + */
1882 +#include <linux/module.h>
1883 +#include <linux/kernel.h>
1884 +#include <linux/types.h>
1885 +#include <linux/errno.h>
1886 +#include <linux/major.h>
1887 +#include <linux/sched.h>
1888 +#include <linux/slab.h>
1889 +#include <linux/interrupt.h>
1890 +#include <linux/poll.h>
1891 +#include <linux/init.h>
1892 +#include <linux/timer.h>
1893 +#include <asm/irq.h>
1894 +#include <asm/dma.h>
1895 +#include <asm/io.h>
1896 +#include <asm/arch/svinto.h>
1897 +#include <asm/uaccess.h>
1898 +#include <asm/system.h>
1899 +#include <asm/sync_serial.h>
1900 +#include <asm/arch/io_interface_mux.h>
1901 +
1902 +/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
1903 +/*                                                                       */
1904 +/* Three DMA descriptors are linked together. Each DMA descriptor is     */
1905 +/* responsible for port->bufchunk of a common buffer.                    */
1906 +/*                                                                       */
1907 +/* +---------------------------------------------+                       */
1908 +/* |   +----------+   +----------+   +----------+ |                      */
1909 +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+                      */
1910 +/*     +----------+   +----------+   +----------+                        */
1911 +/*         |            |              |                                 */
1912 +/*         v            v              v                                 */
1913 +/*   +-------------------------------------+                             */
1914 +/*   |        BUFFER                       |                             */
1915 +/*   +-------------------------------------+                             */
1916 +/*      |<- data_avail ->|                                               */
1917 +/*    readp          writep                                              */
1918 +/*                                                                       */
1919 +/* If the application keeps up the pace readp will be right after writep.*/
1920 +/* If the application can't keep the pace we have to throw away data.    */ 
1921 +/* The idea is that readp should be ready with the data pointed out by  */
1922 +/* Descr[i] when the DMA has filled in Descr[i+1].                       */
1923 +/* Otherwise we will discard                                            */
1924 +/* the rest of the data pointed out by Descr1 and set readp to the start */
1925 +/* of Descr2                                                             */
1926 +
1927 +#define SYNC_SERIAL_MAJOR 125
1928 +
1929 +/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
1930 +/* words can be handled */
1931 +#define IN_BUFFER_SIZE 12288
1932 +#define IN_DESCR_SIZE 256
1933 +#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
1934 +#define OUT_BUFFER_SIZE 4096
1935 +
1936 +#define DEFAULT_FRAME_RATE 0
1937 +#define DEFAULT_WORD_RATE 7
1938 +
1939 +/* NOTE: Enabling some debug will likely cause overrun or underrun,
1940 + * especially if manual mode is use.
1941 + */
1942 +#define DEBUG(x)
1943 +#define DEBUGREAD(x)
1944 +#define DEBUGWRITE(x)
1945 +#define DEBUGPOLL(x)
1946 +#define DEBUGRXINT(x)
1947 +#define DEBUGTXINT(x)
1948 +
1949 +/* Define some macros to access ETRAX 100 registers */
1950 +#define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
1951 +                                         IO_FIELD_(reg##_, field##_, val)
1952 +#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
1953 +                                         IO_STATE_(reg##_, field##_, _##val)
1954 +
1955 +typedef struct sync_port
1956 +{
1957 +       /* Etrax registers and bits*/
1958 +       const volatile unsigned * const status;
1959 +       volatile unsigned * const ctrl_data;
1960 +       volatile unsigned * const output_dma_first;
1961 +       volatile unsigned char * const output_dma_cmd;
1962 +       volatile unsigned char * const output_dma_clr_irq;
1963 +       volatile unsigned * const input_dma_first;
1964 +       volatile unsigned char * const input_dma_cmd;
1965 +       volatile unsigned * const input_dma_descr;
1966 +       /* 8*4 */       
1967 +       volatile unsigned char * const input_dma_clr_irq;
1968 +       volatile unsigned * const data_out;
1969 +       const volatile unsigned * const data_in;
1970 +       char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
1971 +       char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
1972 +       char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
1973 +
1974 +       char output_dma_bit; /* In R_IRQ_MASK2_RD */
1975 +       /* End of fields initialised in array */
1976 +       char started; /* 1 if port has been started */
1977 +       char port_nbr; /* Port 0 or 1 */
1978 +       char busy; /* 1 if port is busy */
1979 +
1980 +       char enabled;  /* 1 if port is enabled */
1981 +       char use_dma;  /* 1 if port uses dma */
1982 +       char tr_running;
1983 +
1984 +       char init_irqs;
1985 +       
1986 +       unsigned int ctrl_data_shadow; /* Register shadow */
1987 +       volatile unsigned int out_count; /* Remaining bytes for current transfer */
1988 +       unsigned char* outp; /* Current position in out_buffer */
1989 +       /* 16*4 */
1990 +       volatile unsigned char* volatile readp;  /* Next byte to be read by application */
1991 +       volatile unsigned char* volatile writep; /* Next byte to be written by etrax */
1992 +       unsigned int in_buffer_size;
1993 +       unsigned int inbufchunk;
1994 +       struct etrax_dma_descr out_descr __attribute__ ((aligned(32)));
1995 +       struct etrax_dma_descr in_descr[NUM_IN_DESCR] __attribute__ ((aligned(32)));
1996 +       unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
1997 +       unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
1998 +       unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
1999 +       struct etrax_dma_descr* next_rx_desc;
2000 +       struct etrax_dma_descr* prev_rx_desc;
2001 +       int full;
2002 +
2003 +       wait_queue_head_t out_wait_q;
2004 +       wait_queue_head_t in_wait_q;    
2005 +} sync_port;
2006 +
2007 +
2008 +static int etrax_sync_serial_init(void);
2009 +static void initialize_port(int portnbr);
2010 +static inline int sync_data_avail(struct sync_port *port);
2011 +
2012 +static int sync_serial_open(struct inode *, struct file*);
2013 +static int sync_serial_release(struct inode*, struct file*);
2014 +static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
2015 +
2016 +static int sync_serial_ioctl(struct inode*, struct file*,
2017 +                            unsigned int cmd, unsigned long arg);
2018 +static ssize_t sync_serial_write(struct file * file, const char * buf, 
2019 +                                size_t count, loff_t *ppos);
2020 +static ssize_t sync_serial_read(struct file *file, char *buf, 
2021 +                               size_t count, loff_t *ppos);
2022 +
2023 +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
2024 +     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
2025 +    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
2026 +     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
2027 +#define SYNC_SER_DMA
2028 +#endif
2029 +
2030 +static void send_word(sync_port* port);
2031 +static void start_dma(struct sync_port *port, const char* data, int count);
2032 +static void start_dma_in(sync_port* port);
2033 +#ifdef SYNC_SER_DMA
2034 +static irqreturn_t tr_interrupt(int irq, void *dev_id);
2035 +static irqreturn_t rx_interrupt(int irq, void *dev_id);
2036 +#endif
2037 +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
2038 +     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
2039 +    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
2040 +     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
2041 +#define SYNC_SER_MANUAL
2042 +#endif
2043 +#ifdef SYNC_SER_MANUAL
2044 +static irqreturn_t manual_interrupt(int irq, void *dev_id);
2045 +#endif
2046 +
2047 +/* The ports */
2048 +static struct sync_port ports[]=
2049 +{
2050 +       {
2051 +               .status                = R_SYNC_SERIAL1_STATUS,
2052 +               .ctrl_data             = R_SYNC_SERIAL1_CTRL,  
2053 +               .output_dma_first      = R_DMA_CH8_FIRST,
2054 +               .output_dma_cmd        = R_DMA_CH8_CMD,
2055 +               .output_dma_clr_irq    = R_DMA_CH8_CLR_INTR,     
2056 +               .input_dma_first       = R_DMA_CH9_FIRST,
2057 +               .input_dma_cmd         = R_DMA_CH9_CMD,
2058 +               .input_dma_descr       = R_DMA_CH9_DESCR,
2059 +               .input_dma_clr_irq     = R_DMA_CH9_CLR_INTR,
2060 +               .data_out              = R_SYNC_SERIAL1_TR_DATA,
2061 +               .data_in               = R_SYNC_SERIAL1_REC_DATA,
2062 +               .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser1_data),
2063 +               .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),
2064 +               .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),
2065 +               .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),
2066 +               .init_irqs             = 1,
2067 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
2068 +                .use_dma               = 1,
2069 +#else
2070 +                .use_dma               = 0,
2071 +#endif
2072 +       },
2073 +       {
2074 +               .status                = R_SYNC_SERIAL3_STATUS,
2075 +               .ctrl_data             = R_SYNC_SERIAL3_CTRL,
2076 +               .output_dma_first      = R_DMA_CH4_FIRST,
2077 +               .output_dma_cmd        = R_DMA_CH4_CMD,
2078 +               .output_dma_clr_irq    = R_DMA_CH4_CLR_INTR,
2079 +               .input_dma_first       = R_DMA_CH5_FIRST,
2080 +               .input_dma_cmd         = R_DMA_CH5_CMD,
2081 +               .input_dma_descr       = R_DMA_CH5_DESCR,               
2082 +               .input_dma_clr_irq     = R_DMA_CH5_CLR_INTR,
2083 +               .data_out              = R_SYNC_SERIAL3_TR_DATA,
2084 +               .data_in               = R_SYNC_SERIAL3_REC_DATA,
2085 +               .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser3_data),
2086 +               .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),
2087 +               .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),
2088 +               .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),
2089 +               .init_irqs             = 1,
2090 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
2091 +                .use_dma               = 1,
2092 +#else
2093 +                .use_dma               = 0,
2094 +#endif
2095 +       }
2096 +};
2097 +
2098 +/* Register shadows */
2099 +static unsigned sync_serial_prescale_shadow = 0;
2100 +
2101 +#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
2102 +
2103 +static struct file_operations sync_serial_fops = {
2104 +       .owner   = THIS_MODULE,
2105 +       .write   = sync_serial_write,
2106 +       .read    = sync_serial_read,
2107 +       .poll    = sync_serial_poll,
2108 +       .ioctl   = sync_serial_ioctl,
2109 +       .open    = sync_serial_open,
2110 +       .release = sync_serial_release
2111 +};
2112 +
2113 +static int __init etrax_sync_serial_init(void)
2114 +{
2115 +       ports[0].enabled = 0;
2116 +       ports[1].enabled = 0;
2117 +
2118 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2119 +       if (cris_request_io_interface(if_sync_serial_1, "sync_ser1")) {
2120 +               printk(KERN_CRIT "ETRAX100LX sync_serial: Could not allocate IO group for port %d\n", 0);
2121 +               return -EBUSY;
2122 +       }
2123 +#endif
2124 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2125 +       if (cris_request_io_interface(if_sync_serial_3, "sync_ser3")) {
2126 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2127 +               cris_free_io_interface(if_sync_serial_1);
2128 +#endif
2129 +               printk(KERN_CRIT "ETRAX100LX sync_serial: Could not allocate IO group for port %d\n", 1);
2130 +               return -EBUSY;
2131 +       }
2132 +#endif
2133 +       
2134 +       if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) 
2135 +       {
2136 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2137 +               cris_free_io_interface(if_sync_serial_3);
2138 +#endif
2139 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2140 +               cris_free_io_interface(if_sync_serial_1);
2141 +#endif
2142 +               printk("unable to get major for synchronous serial port\n");
2143 +               return -EBUSY;
2144 +       }
2145 +
2146 +       /* Deselect synchronous serial ports while configuring. */
2147 +       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
2148 +       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
2149 +       *R_GEN_CONFIG_II = gen_config_ii_shadow;
2150 +
2151 +       /* Initialize Ports */
2152 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2153 +       ports[0].enabled = 1;
2154 +       SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra);
2155 +       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
2156 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
2157 +       ports[0].use_dma = 1;
2158 +#else
2159 +       ports[0].use_dma = 0;   
2160 +#endif
2161 +       initialize_port(0);
2162 +#endif
2163 +
2164 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2165 +       ports[1].enabled = 1;
2166 +       SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra);
2167 +       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
2168 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
2169 +       ports[1].use_dma = 1;
2170 +#else
2171 +       ports[1].use_dma = 0;
2172 +#endif
2173 +       initialize_port(1);
2174 +#endif
2175 +
2176 +       *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
2177 +
2178 +       /* Set up timing */
2179 +       *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = (
2180 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) | 
2181 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) | 
2182 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) | 
2183 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) | 
2184 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) | 
2185 +         IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, DEFAULT_FRAME_RATE) | 
2186 +         IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) | 
2187 +         IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
2188 +
2189 +       /* Select synchronous ports */
2190 +       *R_GEN_CONFIG_II = gen_config_ii_shadow;
2191 +
2192 +       printk("ETRAX 100LX synchronous serial port driver\n");
2193 +       return 0;
2194 +}
2195 +
2196 +static void __init initialize_port(int portnbr)
2197 +{
2198 +       struct sync_port* port = &ports[portnbr];
2199 +
2200 +       DEBUG(printk("Init sync serial port %d\n", portnbr));
2201 +
2202 +       port->started = 0;    
2203 +       port->port_nbr = portnbr;       
2204 +       port->busy = 0;
2205 +       port->tr_running = 0;
2206 +
2207 +       port->out_count = 0;
2208 +       port->outp = port->out_buffer;
2209 +       
2210 +       port->readp = port->flip;
2211 +       port->writep = port->flip;
2212 +       port->in_buffer_size = IN_BUFFER_SIZE;
2213 +       port->inbufchunk = IN_DESCR_SIZE;
2214 +       port->next_rx_desc = &port->in_descr[0];
2215 +       port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1];
2216 +       port->prev_rx_desc->ctrl = d_eol;
2217 +
2218 +       init_waitqueue_head(&port->out_wait_q);
2219 +       init_waitqueue_head(&port->in_wait_q);
2220 +       
2221 +       port->ctrl_data_shadow =
2222 +         IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz)   | 
2223 +         IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | 
2224 +         IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore)       |
2225 +         IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) |
2226 +         IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal)  |
2227 +         IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word)    |
2228 +         IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on)          |
2229 +         IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal)    |
2230 +         IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped)   |
2231 +         IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb)       |
2232 +         IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable)  |
2233 +         IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit)  |
2234 +         IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8)    |
2235 +         IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8)     |
2236 +         IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled)  |
2237 +         IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg)   |
2238 +         IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)|
2239 +         IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)|
2240 +         IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal)   |
2241 +         IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) |
2242 +         IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)|
2243 +         IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high);
2244 +  
2245 +       if (port->use_dma)
2246 +               port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, on);
2247 +       else
2248 +               port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, off);
2249 +  
2250 +       *port->ctrl_data = port->ctrl_data_shadow;
2251 +}
2252 +
2253 +static inline int sync_data_avail(struct sync_port *port)
2254 +{
2255 +       int avail;
2256 +       unsigned char *start;
2257 +       unsigned char *end;
2258 +       
2259 +       start = (unsigned char*)port->readp; /* cast away volatile */
2260 +       end = (unsigned char*)port->writep;  /* cast away volatile */
2261 +       /* 0123456789  0123456789
2262 +        *  -----      -    -----
2263 +        *  ^rp  ^wp    ^wp ^rp
2264 +        */
2265 +               
2266 +       if (end >= start)
2267 +               avail = end - start;
2268 +       else 
2269 +               avail = port->in_buffer_size - (start - end);
2270 +       return avail;
2271 +}
2272 +
2273 +static inline int sync_data_avail_to_end(struct sync_port *port)
2274 +{
2275 +       int avail;
2276 +       unsigned char *start;
2277 +       unsigned char *end;
2278 +       
2279 +       start = (unsigned char*)port->readp; /* cast away volatile */
2280 +       end = (unsigned char*)port->writep;  /* cast away volatile */
2281 +       /* 0123456789  0123456789
2282 +        *  -----           -----
2283 +        *  ^rp  ^wp    ^wp ^rp
2284 +        */
2285 +               
2286 +       if (end >= start)
2287 +               avail = end - start;
2288 +       else 
2289 +               avail = port->flip + port->in_buffer_size - start;
2290 +       return avail;
2291 +}
2292 +
2293 +
2294 +static int sync_serial_open(struct inode *inode, struct file *file)
2295 +{
2296 +       int dev = MINOR(inode->i_rdev);
2297 +       sync_port* port;
2298 +       int mode;
2299 +       
2300 +       DEBUG(printk("Open sync serial port %d\n", dev)); 
2301 +  
2302 +       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2303 +       {
2304 +               DEBUG(printk("Invalid minor %d\n", dev));
2305 +               return -ENODEV;
2306 +       }
2307 +       port = &ports[dev];
2308 +       /* Allow open this device twice (assuming one reader and one writer) */
2309 +       if (port->busy == 2) 
2310 +       {
2311 +               DEBUG(printk("Device is busy.. \n"));
2312 +               return -EBUSY;
2313 +       }
2314 +       if (port->init_irqs) {
2315 +               if (port->use_dma) {
2316 +                       if (port == &ports[0]){
2317 +#ifdef SYNC_SER_DMA
2318 +                               if(request_irq(24,
2319 +                                              tr_interrupt,
2320 +                                              0,
2321 +                                              "synchronous serial 1 dma tr",
2322 +                                              &ports[0])) {
2323 +                                       printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2324 +                                       return -EBUSY;
2325 +                               } else if(request_irq(25,
2326 +                                                     rx_interrupt,
2327 +                                                     0,
2328 +                                                     "synchronous serial 1 dma rx",
2329 +                                                     &ports[0])) {
2330 +                                       free_irq(24, &port[0]);
2331 +                                       printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2332 +                                       return -EBUSY;
2333 +                               } else if (cris_request_dma(8,
2334 +                                                           "synchronous serial 1 dma tr",
2335 +                                                           DMA_VERBOSE_ON_ERROR,
2336 +                                                           dma_ser1)) {
2337 +                                       free_irq(24, &port[0]);
2338 +                                       free_irq(25, &port[0]);
2339 +                                       printk(KERN_CRIT "Can't allocate sync serial port 1 TX DMA channel");
2340 +                                       return -EBUSY;
2341 +                               } else if (cris_request_dma(9,
2342 +                                                           "synchronous serial 1 dma rec",
2343 +                                                           DMA_VERBOSE_ON_ERROR,
2344 +                                                           dma_ser1)) {
2345 +                                       cris_free_dma(8, NULL);
2346 +                                       free_irq(24, &port[0]);
2347 +                                       free_irq(25, &port[0]);
2348 +                                       printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
2349 +                                       return -EBUSY;
2350 +                               }
2351 +#endif
2352 +                               RESET_DMA(8); WAIT_DMA(8);
2353 +                               RESET_DMA(9); WAIT_DMA(9);
2354 +                               *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
2355 +                                       IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); 
2356 +                               *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do) |
2357 +                                       IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, do); 
2358 +                               *R_IRQ_MASK2_SET =
2359 +                                       IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
2360 +                                       IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
2361 +                       }
2362 +                       else if (port == &ports[1]){
2363 +#ifdef SYNC_SER_DMA
2364 +                               if (request_irq(20,
2365 +                                               tr_interrupt,
2366 +                                               0,
2367 +                                               "synchronous serial 3 dma tr",
2368 +                                               &ports[1])) {
2369 +                                       printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2370 +                                       return -EBUSY;
2371 +                               } else if (request_irq(21,
2372 +                                                      rx_interrupt,
2373 +                                                      0,
2374 +                                                      "synchronous serial 3 dma rx",
2375 +                                                      &ports[1])) {
2376 +                                       free_irq(20, &ports[1]);
2377 +                                       printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2378 +                                       return -EBUSY;
2379 +                               } else if (cris_request_dma(4,
2380 +                                                    "synchronous serial 3 dma tr",
2381 +                                                    DMA_VERBOSE_ON_ERROR,
2382 +                                                    dma_ser3)) {
2383 +                                       free_irq(21, &ports[1]);
2384 +                                       free_irq(20, &ports[1]);
2385 +                                       printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
2386 +                                       return -EBUSY;
2387 +                               } else if (cris_request_dma(5,
2388 +                                                           "synchronous serial 3 dma rec",
2389 +                                                           DMA_VERBOSE_ON_ERROR,
2390 +                                                           dma_ser3)) {
2391 +                                       cris_free_dma(4, NULL);
2392 +                                       free_irq(21, &ports[1]);
2393 +                                       free_irq(20, &ports[1]);
2394 +                                       printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel");
2395 +                                       return -EBUSY;
2396 +                               }
2397 +#endif
2398 +                               RESET_DMA(4); WAIT_DMA(4);
2399 +                               RESET_DMA(5); WAIT_DMA(5);
2400 +                               *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
2401 +                                       IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); 
2402 +                               *R_DMA_CH5_CLR_INTR = IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop, do) |
2403 +                                       IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, do); 
2404 +                               *R_IRQ_MASK2_SET =
2405 +                                       IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
2406 +                                       IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
2407 +                       }
2408 +                       start_dma_in(port);
2409 +                       port->init_irqs = 0;
2410 +               } else { /* !port->use_dma */
2411 +#ifdef SYNC_SER_MANUAL
2412 +                       if (port == &ports[0]) {
2413 +                               if (request_irq(8,
2414 +                                               manual_interrupt,
2415 +                                               IRQF_SHARED | IRQF_DISABLED,
2416 +                                               "synchronous serial manual irq",
2417 +                                               &ports[0])) {
2418 +                                       printk("Can't allocate sync serial manual irq");
2419 +                                       return -EBUSY;
2420 +                               }
2421 +                       } else if (port == &ports[1]) {
2422 +                               if (request_irq(8,
2423 +                                               manual_interrupt,
2424 +                                               IRQF_SHARED | IRQF_DISABLED,
2425 +                                               "synchronous serial manual irq",
2426 +                                               &ports[1])) {
2427 +                                       printk(KERN_CRIT "Can't allocate sync serial manual irq");
2428 +                                       return -EBUSY;
2429 +                               }
2430 +                       }
2431 +                       port->init_irqs = 0;
2432 +#else
2433 +                       panic("sync_serial: Manual mode not supported.\n");
2434 +#endif /* SYNC_SER_MANUAL */
2435 +               }
2436 +       } /* port->init_irqs */
2437 +
2438 +       port->busy++;
2439 +       /* Start port if we use it as input */
2440 +       mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow);
2441 +       if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) ||
2442 +           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) ||
2443 +           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) ||
2444 +           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) {
2445 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2446 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2447 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2448 +               port->started = 1;
2449 +               *port->ctrl_data = port->ctrl_data_shadow;
2450 +               if (!port->use_dma)
2451 +                       *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
2452 +               DEBUG(printk("sser%d rec started\n", dev)); 
2453 +       }
2454 +       return 0;
2455 +}
2456 +
2457 +static int sync_serial_release(struct inode *inode, struct file *file)
2458 +{
2459 +       int dev = MINOR(inode->i_rdev);
2460 +       sync_port* port;
2461 +
2462 +       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2463 +       {
2464 +               DEBUG(printk("Invalid minor %d\n", dev));
2465 +               return -ENODEV;
2466 +       }
2467 +       port = &ports[dev];
2468 +       if (port->busy)
2469 +               port->busy--;
2470 +       if (!port->busy) 
2471 +               *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) |
2472 +                                   (1 << port->transmitter_ready_bit));
2473 +
2474 +       return 0;
2475 +}
2476 +
2477 +
2478 +
2479 +static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
2480 +{
2481 +       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2482 +       unsigned int mask = 0;
2483 +       sync_port* port;
2484 +       DEBUGPOLL( static unsigned int prev_mask = 0; );
2485 +       
2486 +       port = &ports[dev];
2487 +       poll_wait(file, &port->out_wait_q, wait);
2488 +       poll_wait(file, &port->in_wait_q, wait);
2489 +       /* Some room to write */
2490 +       if (port->out_count < OUT_BUFFER_SIZE)
2491 +               mask |=  POLLOUT | POLLWRNORM;
2492 +       /* At least an inbufchunk of data */
2493 +       if (sync_data_avail(port) >= port->inbufchunk)
2494 +               mask |= POLLIN | POLLRDNORM;
2495 +       
2496 +       DEBUGPOLL(if (mask != prev_mask)
2497 +             printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
2498 +                    mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
2499 +             prev_mask = mask;
2500 +             );
2501 +       return mask;
2502 +}
2503 +
2504 +static int sync_serial_ioctl(struct inode *inode, struct file *file,
2505 +                 unsigned int cmd, unsigned long arg)
2506 +{
2507 +       int return_val = 0;
2508 +       unsigned long flags;
2509 +       
2510 +       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2511 +       sync_port* port;
2512 +        
2513 +       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2514 +       {
2515 +               DEBUG(printk("Invalid minor %d\n", dev));
2516 +               return -1;
2517 +       }
2518 +        port = &ports[dev];
2519 +
2520 +       local_irq_save(flags);
2521 +       /* Disable port while changing config */
2522 +       if (dev)
2523 +       {
2524 +               if (port->use_dma) {
2525 +                       RESET_DMA(4); WAIT_DMA(4);
2526 +                        port->tr_running = 0;
2527 +                        port->out_count = 0;
2528 +                        port->outp = port->out_buffer;
2529 +                       *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
2530 +                               IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
2531 +               }
2532 +               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
2533 +       }
2534 +       else
2535 +       {
2536 +               if (port->use_dma) {            
2537 +                       RESET_DMA(8); WAIT_DMA(8);
2538 +                        port->tr_running = 0;
2539 +                        port->out_count = 0;
2540 +                        port->outp = port->out_buffer;
2541 +                       *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
2542 +                               IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);
2543 +               }
2544 +               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
2545 +       }
2546 +       *R_GEN_CONFIG_II = gen_config_ii_shadow;
2547 +       local_irq_restore(flags);
2548 +
2549 +       switch(cmd)
2550 +       {
2551 +       case SSP_SPEED:
2552 +               if (GET_SPEED(arg) == CODEC)
2553 +               {
2554 +                       if (dev)
2555 +                               SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec);
2556 +                       else
2557 +                               SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec);
2558 +                       
2559 +                       SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg));
2560 +                       SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg));
2561 +                       SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg));
2562 +               }
2563 +               else
2564 +               {
2565 +                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg));
2566 +                       if (dev)
2567 +                               SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate);
2568 +                       else
2569 +                               SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate);
2570 +               }
2571 +               break;
2572 +       case SSP_MODE:
2573 +               if (arg > 5)
2574 +                       return -EINVAL;
2575 +               if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)
2576 +                       *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit;
2577 +               else if (!port->use_dma)
2578 +                       *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
2579 +               SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
2580 +               break;
2581 +       case SSP_FRAME_SYNC:
2582 +               if (arg & NORMAL_SYNC)
2583 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
2584 +               else if (arg & EARLY_SYNC)
2585 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early);
2586 +               
2587 +               if (arg & BIT_SYNC)
2588 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit);
2589 +               else if (arg & WORD_SYNC)
2590 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
2591 +               else if (arg & EXTENDED_SYNC)
2592 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended);
2593 +               
2594 +               if (arg & SYNC_ON)
2595 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
2596 +               else if (arg & SYNC_OFF)
2597 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off);
2598 +               
2599 +               if (arg & WORD_SIZE_8)
2600 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
2601 +               else if (arg & WORD_SIZE_12)
2602 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit);
2603 +               else if (arg & WORD_SIZE_16)
2604 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit);
2605 +               else if (arg & WORD_SIZE_24)
2606 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit);
2607 +               else if (arg & WORD_SIZE_32)
2608 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit);
2609 +               
2610 +               if (arg & BIT_ORDER_MSB)
2611 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
2612 +               else if (arg & BIT_ORDER_LSB)
2613 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb);
2614 +               
2615 +               if (arg & FLOW_CONTROL_ENABLE)
2616 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled);
2617 +               else if (arg & FLOW_CONTROL_DISABLE)
2618 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
2619 +               
2620 +               if (arg & CLOCK_NOT_GATED)
2621 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal);
2622 +               else if (arg & CLOCK_GATED)
2623 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated);    
2624 +               
2625 +               break;
2626 +       case SSP_IPOLARITY:
2627 +               /* NOTE!! negedge is considered NORMAL */
2628 +               if (arg & CLOCK_NORMAL)
2629 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
2630 +               else if (arg & CLOCK_INVERT)
2631 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos);
2632 +               
2633 +               if (arg & FRAME_NORMAL)
2634 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal);
2635 +               else if (arg & FRAME_INVERT)
2636 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
2637 +               
2638 +               if (arg & STATUS_NORMAL)
2639 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal);
2640 +               else if (arg & STATUS_INVERT)
2641 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted);
2642 +               break;
2643 +       case SSP_OPOLARITY:
2644 +               if (arg & CLOCK_NORMAL)
2645 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal);
2646 +               else if (arg & CLOCK_INVERT)
2647 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
2648 +               
2649 +               if (arg & FRAME_NORMAL)
2650 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal);
2651 +               else if (arg & FRAME_INVERT)
2652 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
2653 +               
2654 +               if (arg & STATUS_NORMAL)
2655 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal);
2656 +               else if (arg & STATUS_INVERT)
2657 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted);
2658 +               break;
2659 +       case SSP_SPI:
2660 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
2661 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
2662 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
2663 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
2664 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
2665 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
2666 +               if (arg & SPI_SLAVE)
2667 +               {
2668 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
2669 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
2670 +                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT);
2671 +               }
2672 +               else
2673 +               {
2674 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
2675 +                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
2676 +                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT);
2677 +               }
2678 +               break;
2679 +       case SSP_INBUFCHUNK:
2680 +#if 0
2681 +               if (arg > port->in_buffer_size/NUM_IN_DESCR)
2682 +                       return -EINVAL;
2683 +               port->inbufchunk = arg;
2684 +               /* Make sure in_buffer_size is a multiple of inbufchunk */
2685 +               port->in_buffer_size = (port->in_buffer_size/port->inbufchunk) * port->inbufchunk;
2686 +               DEBUG(printk("inbufchunk %i in_buffer_size: %i\n", port->inbufchunk, port->in_buffer_size));
2687 +               if (port->use_dma) {
2688 +                       if (port->port_nbr == 0) {
2689 +                               RESET_DMA(9);
2690 +                               WAIT_DMA(9);
2691 +                       } else {
2692 +                               RESET_DMA(5);
2693 +                               WAIT_DMA(5);
2694 +                       }
2695 +                       start_dma_in(port);
2696 +               }
2697 +#endif
2698 +               break;
2699 +       default:
2700 +               return_val = -1;
2701 +       }
2702 +       /* Make sure we write the config without interruption */
2703 +       local_irq_save(flags);
2704 +       /* Set config and enable port */
2705 +       *port->ctrl_data = port->ctrl_data_shadow;
2706 +       nop(); nop(); nop(); nop();
2707 +       *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow;
2708 +       nop(); nop(); nop(); nop();
2709 +       if (dev)
2710 +               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
2711 +       else
2712 +               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
2713 +
2714 +       *R_GEN_CONFIG_II = gen_config_ii_shadow;
2715 +       /* Reset DMA. At readout from serial port the data could be shifted
2716 +        * one byte if not resetting DMA.
2717 +        */
2718 +       if (port->use_dma) {
2719 +               if (port->port_nbr == 0) {
2720 +                       RESET_DMA(9);
2721 +                       WAIT_DMA(9);
2722 +               } else {
2723 +                       RESET_DMA(5);
2724 +                       WAIT_DMA(5);
2725 +               }
2726 +               start_dma_in(port);
2727 +       }
2728 +       local_irq_restore(flags);
2729 +       return return_val;
2730 +}
2731 +
2732 +
2733 +static ssize_t sync_serial_write(struct file * file, const char * buf, 
2734 +                                 size_t count, loff_t *ppos)
2735 +{
2736 +       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2737 +       DECLARE_WAITQUEUE(wait, current);       
2738 +       sync_port *port;
2739 +       unsigned long flags;
2740 +       unsigned long c, c1;
2741 +       unsigned long free_outp;
2742 +       unsigned long outp;
2743 +       unsigned long out_buffer;
2744 +
2745 +       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2746 +       {
2747 +               DEBUG(printk("Invalid minor %d\n", dev));
2748 +               return -ENODEV;
2749 +       }
2750 +       port = &ports[dev];
2751 +
2752 +       DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
2753 +       /* Space to end of buffer */
2754 +       /* 
2755 +        * out_buffer <c1>012345<-   c    ->OUT_BUFFER_SIZE
2756 +        *            outp^    +out_count
2757 +                               ^free_outp
2758 +        * out_buffer 45<-     c      ->0123OUT_BUFFER_SIZE
2759 +        *             +out_count   outp^
2760 +        *              free_outp
2761 +        *
2762 +        */
2763 +
2764 +       /* Read variables that may be updated by interrupts */
2765 +       local_irq_save(flags);
2766 +       count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE  - port->out_count : count;
2767 +       outp = (unsigned long)port->outp;
2768 +       free_outp = outp + port->out_count;
2769 +       local_irq_restore(flags);
2770 +       out_buffer = (unsigned long)port->out_buffer;
2771 +       
2772 +       /* Find out where and how much to write */
2773 +       if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
2774 +               free_outp -= OUT_BUFFER_SIZE;
2775 +       if (free_outp >= outp)
2776 +               c = out_buffer + OUT_BUFFER_SIZE - free_outp;
2777 +       else
2778 +               c = outp - free_outp;
2779 +       if (c > count)
2780 +               c = count;
2781 +       
2782 +//     DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c));
2783 +       if (copy_from_user((void*)free_outp, buf, c))
2784 +               return -EFAULT;
2785 +
2786 +       if (c != count) {
2787 +               buf += c;
2788 +               c1 = count - c;
2789 +               DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1));
2790 +               if (copy_from_user((void*)out_buffer, buf, c1))
2791 +                       return -EFAULT;
2792 +       }
2793 +       local_irq_save(flags);
2794 +       port->out_count += count;
2795 +       local_irq_restore(flags);
2796 +
2797 +       /* Make sure transmitter/receiver is running */
2798 +       if (!port->started)
2799 +       {
2800 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2801 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2802 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2803 +               port->started = 1;
2804 +       }
2805 +
2806 +       *port->ctrl_data = port->ctrl_data_shadow;
2807 +
2808 +       if (file->f_flags & O_NONBLOCK) {
2809 +               local_irq_save(flags);
2810 +               if (!port->tr_running) {
2811 +                       if (!port->use_dma) {
2812 +                               /* Start sender by writing data */
2813 +                               send_word(port);
2814 +                               /* and enable transmitter ready IRQ */
2815 +                               *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2816 +                       } else {
2817 +                               start_dma(port, (unsigned char* volatile )port->outp, c);
2818 +                       }
2819 +               }
2820 +               local_irq_restore(flags);
2821 +               DEBUGWRITE(printk("w d%d c %lu NB\n",
2822 +                                 port->port_nbr, count));
2823 +               return count;
2824 +       }
2825 +
2826 +       /* Sleep until all sent */
2827 +       
2828 +       add_wait_queue(&port->out_wait_q, &wait);
2829 +       set_current_state(TASK_INTERRUPTIBLE);
2830 +       local_irq_save(flags);
2831 +       if (!port->tr_running) {
2832 +               if (!port->use_dma) {
2833 +                       /* Start sender by writing data */
2834 +                       send_word(port);
2835 +                       /* and enable transmitter ready IRQ */
2836 +                       *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2837 +               } else {
2838 +                       start_dma(port, port->outp, c);
2839 +               }
2840 +       }
2841 +       local_irq_restore(flags);
2842 +       schedule();
2843 +       set_current_state(TASK_RUNNING);
2844 +       remove_wait_queue(&port->out_wait_q, &wait);
2845 +       if (signal_pending(current))
2846 +       {
2847 +               return -EINTR;
2848 +       }
2849 +       DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count));
2850 +       return count;
2851 +}
2852 +
2853 +static ssize_t sync_serial_read(struct file * file, char * buf, 
2854 +                               size_t count, loff_t *ppos)
2855 +{
2856 +       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2857 +       int avail;
2858 +       sync_port *port;
2859 +       unsigned char* start; 
2860 +       unsigned char* end;
2861 +       unsigned long flags;    
2862 +
2863 +       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2864 +       {
2865 +               DEBUG(printk("Invalid minor %d\n", dev));
2866 +               return -ENODEV;
2867 +       }
2868 +       port = &ports[dev];
2869 +
2870 +       DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->flip, port->writep - port->flip, port->in_buffer_size));
2871 +
2872 +       if (!port->started)
2873 +       {
2874 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2875 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2876 +               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2877 +               port->started = 1;
2878 +       }
2879 +       *port->ctrl_data = port->ctrl_data_shadow;
2880 +
2881 +       
2882 +       /* Calculate number of available bytes */
2883 +       /* Save pointers to avoid that they are modified by interrupt */
2884 +       local_irq_save(flags);
2885 +       start = (unsigned char*)port->readp; /* cast away volatile */
2886 +       end = (unsigned char*)port->writep;  /* cast away volatile */
2887 +       local_irq_restore(flags);
2888 +       while ((start == end) && !port->full) /* No data */
2889 +       {
2890 +               if (file->f_flags & O_NONBLOCK)
2891 +               {  
2892 +                       return -EAGAIN;
2893 +               }
2894 +          
2895 +               interruptible_sleep_on(&port->in_wait_q);
2896 +               if (signal_pending(current))
2897 +               {
2898 +                       return -EINTR;
2899 +               }
2900 +               local_irq_save(flags);
2901 +               start = (unsigned char*)port->readp; /* cast away volatile */
2902 +               end = (unsigned char*)port->writep;  /* cast away volatile */
2903 +               local_irq_restore(flags);
2904 +       }
2905 +
2906 +       /* Lazy read, never return wrapped data. */
2907 +       if (port->full)
2908 +               avail = port->in_buffer_size;
2909 +       else if (end > start)
2910 +               avail = end - start;
2911 +       else 
2912 +               avail = port->flip + port->in_buffer_size - start;
2913 +  
2914 +       count = count > avail ? avail : count;
2915 +       if (copy_to_user(buf, start, count))
2916 +               return -EFAULT;
2917 +       /* Disable interrupts while updating readp */
2918 +       local_irq_save(flags);
2919 +       port->readp += count;
2920 +       if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
2921 +               port->readp = port->flip;
2922 +       port->full = 0;
2923 +       local_irq_restore(flags);
2924 +       DEBUGREAD(printk("r %d\n", count));
2925 +       return count;
2926 +}
2927 +
2928 +static void send_word(sync_port* port)
2929 +{
2930 +       switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow))
2931 +       {
2932 +        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
2933 +                port->out_count--;
2934 +                *port->data_out = *port->outp++;
2935 +                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2936 +                        port->outp = port->out_buffer;
2937 +                break;
2938 +       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
2939 +       {
2940 +               int data = (*port->outp++) << 8;
2941 +               data |= *port->outp++;
2942 +               port->out_count-=2;  
2943 +               *port->data_out = data;
2944 +               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2945 +                       port->outp = port->out_buffer;
2946 +       }
2947 +       break;
2948 +       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
2949 +               port->out_count-=2;
2950 +               *port->data_out = *(unsigned short *)port->outp;
2951 +               port->outp+=2;
2952 +               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2953 +                       port->outp = port->out_buffer;
2954 +               break;
2955 +       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
2956 +               port->out_count-=3;
2957 +               *port->data_out = *(unsigned int *)port->outp;
2958 +               port->outp+=3;
2959 +               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2960 +                       port->outp = port->out_buffer;
2961 +               break;
2962 +       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
2963 +               port->out_count-=4;
2964 +               *port->data_out = *(unsigned int *)port->outp;
2965 +               port->outp+=4;
2966 +               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2967 +                       port->outp = port->out_buffer;
2968 +               break;
2969 +       }
2970 +}
2971 +
2972 +
2973 +static void start_dma(struct sync_port* port, const char* data, int count)
2974 +{
2975 +       port->tr_running = 1;
2976 +       port->out_descr.hw_len = 0;
2977 +       port->out_descr.next = 0;
2978 +       port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */
2979 +       port->out_descr.sw_len = count;
2980 +       port->out_descr.buf = virt_to_phys((char*)data);
2981 +       port->out_descr.status = 0;
2982 +
2983 +       *port->output_dma_first = virt_to_phys(&port->out_descr);
2984 +       *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
2985 +       DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
2986 +}
2987 +
2988 +static void start_dma_in(sync_port* port)
2989 +{
2990 +       int i;
2991 +       unsigned long buf;
2992 +       port->writep = port->flip;
2993 +       
2994 +       if (port->writep > port->flip + port->in_buffer_size)
2995 +       {
2996 +               panic("Offset too large in sync serial driver\n");
2997 +               return;
2998 +       }
2999 +       buf = virt_to_phys(port->in_buffer);
3000 +       for (i = 0; i < NUM_IN_DESCR; i++) {
3001 +               port->in_descr[i].sw_len = port->inbufchunk;
3002 +               port->in_descr[i].ctrl = d_int;
3003 +               port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]);
3004 +               port->in_descr[i].buf = buf;
3005 +               port->in_descr[i].hw_len = 0;
3006 +               port->in_descr[i].status = 0;
3007 +               port->in_descr[i].fifo_len = 0;
3008 +               buf += port->inbufchunk;
3009 +               prepare_rx_descriptor(&port->in_descr[i]);
3010 +       }
3011 +       /* Link the last descriptor to the first */
3012 +       port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]);
3013 +       port->in_descr[i-1].ctrl |= d_eol;
3014 +       port->next_rx_desc = &port->in_descr[0];
3015 +       port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1];
3016 +       *port->input_dma_first = virt_to_phys(port->next_rx_desc);
3017 +       *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
3018 +}
3019 +
3020 +#ifdef SYNC_SER_DMA
3021 +static irqreturn_t tr_interrupt(int irq, void *dev_id)
3022 +{
3023 +       unsigned long ireg = *R_IRQ_MASK2_RD;
3024 +       int i;
3025 +       struct etrax_dma_descr *descr;
3026 +       unsigned int sentl;
3027 +       int handled = 0;
3028 +
3029 +       for (i = 0; i < NUMBER_OF_PORTS; i++) 
3030 +       {
3031 +               sync_port *port = &ports[i];
3032 +               if (!port->enabled  || !port->use_dma )
3033 +                       continue;
3034 +
3035 +               if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */
3036 +               {
3037 +                       handled = 1;
3038 +
3039 +                       /* Clear IRQ */
3040 +                       *port->output_dma_clr_irq = 
3041 +                         IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
3042 +                         IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
3043 +
3044 +                       descr = &port->out_descr;
3045 +                       if (!(descr->status & d_stop)) {
3046 +                               sentl = descr->sw_len;
3047 +                       } else 
3048 +                               /* otherwise we find the amount of data sent here */
3049 +                               sentl = descr->hw_len;
3050 +                       port->out_count -= sentl;
3051 +                       port->outp += sentl;
3052 +                       if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
3053 +                               port->outp = port->out_buffer;
3054 +                       if (port->out_count)  {
3055 +                               int c;
3056 +                               c = port->out_buffer + OUT_BUFFER_SIZE - port->outp;
3057 +                               if (c > port->out_count)
3058 +                                       c = port->out_count;
3059 +                               DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c));
3060 +                               start_dma(port, port->outp, c);
3061 +                       } else  {
3062 +                               DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));                              
3063 +                               port->tr_running = 0;
3064 +                       }
3065 +                       wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
3066 +               } 
3067 +       }
3068 +       return IRQ_RETVAL(handled);
3069 +} /* tr_interrupt */
3070 +
3071 +static irqreturn_t rx_interrupt(int irq, void *dev_id)
3072 +{
3073 +       unsigned long ireg = *R_IRQ_MASK2_RD;
3074 +       int i;
3075 +       int handled = 0;
3076 +
3077 +       for (i = 0; i < NUMBER_OF_PORTS; i++) 
3078 +       {
3079 +               sync_port *port = &ports[i];
3080 +
3081 +               if (!port->enabled || !port->use_dma )
3082 +                       continue;
3083 +
3084 +               if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */
3085 +               {
3086 +                       handled = 1;
3087 +                       while (*port->input_dma_descr != virt_to_phys(port->next_rx_desc)) {
3088 +                       
3089 +                               if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
3090 +                                       int first_size = port->flip + port->in_buffer_size - port->writep;
3091 +                                       memcpy(port->writep, phys_to_virt(port->next_rx_desc->buf), first_size);
3092 +                                       memcpy(port->flip, phys_to_virt(port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
3093 +                                       port->writep = port->flip + port->inbufchunk - first_size;
3094 +                               } else {
3095 +                                       memcpy(port->writep, phys_to_virt(port->next_rx_desc->buf), port->inbufchunk);
3096 +                                       port->writep += port->inbufchunk;
3097 +                                       if (port->writep >= port->flip + port->in_buffer_size)
3098 +                                               port->writep = port->flip;
3099 +                               }
3100 +                                if (port->writep == port->readp)
3101 +                                {
3102 +                                 port->full = 1;
3103 +                                }
3104 +                                
3105 +                               prepare_rx_descriptor(port->next_rx_desc);
3106 +                               port->next_rx_desc->ctrl |= d_eol;
3107 +                               port->prev_rx_desc->ctrl &= ~d_eol;
3108 +                               port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc);
3109 +                               port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
3110 +                               wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
3111 +                               *port->input_dma_cmd =  IO_STATE(R_DMA_CH1_CMD, cmd, restart);
3112 +                               /* DMA has reached end of descriptor */
3113 +                               *port->input_dma_clr_irq = 
3114 +                                 IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
3115 +                       }
3116 +               }
3117 +       }
3118 +       
3119 +       return IRQ_RETVAL(handled);
3120 +} /* rx_interrupt */
3121 +#endif /* SYNC_SER_DMA */
3122 +
3123 +#ifdef SYNC_SER_MANUAL
3124 +static irqreturn_t manual_interrupt(int irq, void *dev_id)
3125 +{
3126 +       int i;
3127 +       int handled = 0;
3128 +
3129 +       for (i = 0; i < NUMBER_OF_PORTS; i++)
3130 +       {
3131 +               sync_port* port = &ports[i];
3132 +
3133 +               if (!port->enabled || port->use_dma)
3134 +               {
3135 +                       continue;
3136 +               }
3137 +
3138 +               if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit))      /* Data received? */
3139 +               {
3140 +                       handled = 1;
3141 +                       /* Read data */
3142 +                       switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize))
3143 +                       {
3144 +                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
3145 +                               *port->writep++ = *(volatile char *)port->data_in;
3146 +                               break;
3147 +                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
3148 +                       {
3149 +                               int data = *(unsigned short *)port->data_in;
3150 +                               *port->writep = (data & 0x0ff0) >> 4;
3151 +                               *(port->writep + 1) = data & 0x0f;
3152 +                               port->writep+=2;
3153 +                       }
3154 +                       break;
3155 +                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
3156 +                               *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in;
3157 +                               port->writep+=2;
3158 +                               break;
3159 +                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
3160 +                               *(unsigned int*)port->writep = *port->data_in;
3161 +                               port->writep+=3;
3162 +                               break;
3163 +                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
3164 +                               *(unsigned int*)port->writep = *port->data_in;
3165 +                               port->writep+=4;
3166 +                               break;
3167 +                       }
3168 +
3169 +                       if (port->writep >= port->flip + port->in_buffer_size) /* Wrap? */
3170 +                               port->writep = port->flip;
3171 +                       if (port->writep == port->readp) {
3172 +                               /* receive buffer overrun, discard oldest data
3173 +                                */
3174 +                               port->readp++;
3175 +                               if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
3176 +                                       port->readp = port->flip;
3177 +                       }
3178 +                       if (sync_data_avail(port) >= port->inbufchunk)
3179 +                               wake_up_interruptible(&port->in_wait_q); /* Wake up application */
3180 +               }
3181 +
3182 +               if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */
3183 +               {
3184 +                       if (port->out_count > 0) /* More data to send */
3185 +                               send_word(port);
3186 +                       else /* transmission finished */
3187 +                       {
3188 +                               *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */
3189 +                               wake_up_interruptible(&port->out_wait_q); /* Wake up application */
3190 +                       }
3191 +               }
3192 +       }
3193 +       return IRQ_RETVAL(handled);
3194 +}
3195 +#endif
3196 +
3197 +module_init(etrax_sync_serial_init);
3198 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/debugport.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/debugport.c
3199 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/debugport.c    2007-01-10 20:10:37.000000000 +0100
3200 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/debugport.c    2006-10-30 16:17:57.000000000 +0100
3201 @@ -12,6 +12,34 @@
3202   *    init_etrax_debug()
3203   *
3204   * $Log: debugport.c,v $
3205 + * Revision 1.36  2006/10/30 15:17:57  pkj
3206 + * Avoid a compiler warning.
3207 + *
3208 + * Revision 1.35  2006/10/13 12:43:11  starvik
3209 + * Merge of 2.6.18
3210 + *
3211 + * Revision 1.34  2006/09/29 10:32:01  starvik
3212 + * Don't reference serial driver if not present
3213 + *
3214 + * Revision 1.33  2006/09/08 07:59:29  karljope
3215 + * Makes v10 boot again when watchdog is enabled
3216 + *
3217 + * Revision 1.32  2006/06/20 08:23:36  pkj
3218 + * Reverted incorrect merge.
3219 + *
3220 + * Revision 1.31  2006/05/17 12:22:10  edgar
3221 + * check port before disable ints
3222 + *
3223 + * Revision 1.30  2005/11/15 12:08:42  starvik
3224 + * Set index when no debug port is defined
3225 + *
3226 + * Revision 1.29  2005/08/29 07:32:17  starvik
3227 + * Merge of 2.6.13
3228 + *
3229 + * Revision 1.28  2005/07/02 12:29:35  starvik
3230 + * Use the generic oops_in_progress instead of the raw_printk hack.
3231 + * Moved some functions to achr-independent code.
3232 + *
3233   * Revision 1.27  2005/06/10 10:34:14  starvik
3234   * Real console support
3235   *
3236 @@ -112,6 +140,8 @@
3237  #include <asm/arch/svinto.h>
3238  #include <asm/io.h>             /* Get SIMCOUT. */
3239  
3240 +extern void reset_watchdog(void);
3241 +
3242  struct dbg_port
3243  {
3244    unsigned int index;
3245 @@ -188,7 +218,9 @@
3246    }
3247  };
3248  
3249 +#ifdef CONFIG_ETRAX_SERIAL
3250  extern struct tty_driver *serial_driver;
3251 +#endif
3252  
3253  struct dbg_port* port =
3254  #if defined(CONFIG_ETRAX_DEBUG_PORT0)
3255 @@ -368,11 +400,12 @@
3256  {
3257         int i;
3258         unsigned long flags;
3259 -       local_irq_save(flags);
3260 -
3261 +       
3262          if (!port)
3263                 return;
3264 -
3265 +       
3266 +       local_irq_save(flags);
3267 +       
3268         /* Send data */
3269         for (i = 0; i < len; i++) {
3270                 /* LF -> CRLF */
3271 @@ -386,26 +419,16 @@
3272                         ;
3273                 *port->write = buf[i];
3274         }
3275 -       local_irq_restore(flags);
3276 -}
3277  
3278 -int raw_printk(const char *fmt, ...)
3279 -{
3280 -       static char buf[1024];
3281 -       int printed_len;
3282 -       static int first = 1;
3283 -       if (first) {
3284 -               /* Force reinitialization of the port to get manual mode. */
3285 -               port->started = 0;
3286 -               start_port(port);
3287 -               first = 0;
3288 -       }
3289 -       va_list args;
3290 -       va_start(args, fmt);
3291 -       printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
3292 -       va_end(args);
3293 -       console_write_direct(NULL, buf, strlen(buf));
3294 -       return printed_len;
3295 +       /*
3296 +        * Feed the watchdog, otherwise it will reset the chip during boot. 
3297 +        * The time to send an ordinary boot message line (10-90 chars) 
3298 +        * varies between 1-8ms at 115200. What makes up for the additional 
3299 +        * 90ms that allows the watchdog to bite?
3300 +       */
3301 +       reset_watchdog();
3302 +
3303 +       local_irq_restore(flags);
3304  }
3305  
3306  static void
3307 @@ -500,6 +523,7 @@
3308         return 0;
3309  }
3310  
3311 +
3312  /* This is a dummy serial device that throws away anything written to it.
3313   * This is used when no debug output is wanted.
3314   */
3315 @@ -555,7 +579,13 @@
3316  {
3317         if (port)
3318                 *index = port->index;
3319 +       else
3320 +               *index = 0;
3321 +#ifdef CONFIG_ETRAX_SERIAL
3322          return port ? serial_driver : &dummy_driver;
3323 +#else
3324 +       return &dummy_driver;
3325 +#endif
3326  }
3327  
3328  static struct console sercons = {
3329 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/entry.S linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/entry.S
3330 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/entry.S        2007-01-10 20:10:37.000000000 +0100
3331 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/entry.S        2007-01-09 10:36:17.000000000 +0100
3332 @@ -1,4 +1,4 @@
3333 -/* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $
3334 +/* $Id: entry.S,v 1.38 2007/01/09 09:36:17 starvik Exp $
3335   *
3336   *  linux/arch/cris/entry.S
3337   *
3338 @@ -7,6 +7,41 @@
3339   *  Authors:   Bjorn Wesen (bjornw@axis.com)
3340   *
3341   *  $Log: entry.S,v $
3342 + *  Revision 1.38  2007/01/09 09:36:17  starvik
3343 + *  Corrected kernel_execve
3344 + *
3345 + *  Revision 1.37  2007/01/09 09:29:18  starvik
3346 + *  Merge of Linux 2.6.19
3347 + *
3348 + *  Revision 1.36  2006/12/08 13:08:54  orjanf
3349 + *  Copied from Linux 2.4:
3350 + *  * Return from an pin-generated NMI the same way as for other interrupts.
3351 + *  * Reverse check order between external nmi and watchdog nmi to avoid false
3352 + *    watchdog oops in case of a glitch on the nmi pin.
3353 + *
3354 + *  Revision 1.35  2006/10/13 12:43:11  starvik
3355 + *  Merge of 2.6.18
3356 + *
3357 + *  Revision 1.34  2006/06/25 15:00:09  starvik
3358 + *  Merge of Linux 2.6.17
3359 + *
3360 + *  Revision 1.33  2006/05/19 12:23:09  orjanf
3361 + *  * Moved blocking of ethernet rx/tx irq from ethernet interrupt handler to
3362 + *    low-level asm interrupt handlers.  Fixed in the multiple interrupt handler
3363 + *    also.  Copied from Linux 2.4.
3364 + *
3365 + *  Revision 1.32  2006/03/23 14:53:57  starvik
3366 + *  Corrected signal handling.
3367 + *
3368 + *  Revision 1.31  2006/03/22 09:56:55  starvik
3369 + *  Merge of Linux 2.6.16
3370 + *
3371 + *  Revision 1.30  2005/10/31 08:48:03  starvik
3372 + *  Merge of Linux 2.6.14
3373 + *
3374 + *  Revision 1.29  2005/08/29 07:32:17  starvik
3375 + *  Merge of 2.6.13
3376 + *
3377   *  Revision 1.28  2005/06/20 05:06:30  starvik
3378   *  Remove unnecessary diff to kernel.org tree
3379   *
3380 @@ -500,9 +535,8 @@
3381         ;; deal with pending signals and notify-resume requests
3382  
3383         move.d  $r9, $r10       ; do_notify_resume syscall/irq param
3384 -       moveq   0, $r11         ; oldset param - 0 in this case
3385 -       move.d  $sp, $r12       ; the regs param
3386 -       move.d  $r1, $r13       ; the thread_info_flags parameter
3387 +       move.d  $sp, $r11       ; the regs param
3388 +       move.d  $r1, $r12       ; the thread_info_flags parameter
3389         jsr     do_notify_resume
3390         
3391         ba _Rexit
3392 @@ -653,7 +687,7 @@
3393         ;; special handlers for breakpoint and NMI
3394  hwbreakpoint:
3395         push    $dccr
3396 -       di
3397 +       di      
3398         push    $r10
3399         push    $r11
3400         move.d  [hw_bp_trig_ptr],$r10
3401 @@ -678,13 +712,19 @@
3402         push    $r10            ; push orig_r10
3403         clear.d [$sp=$sp-4]     ; frametype == 0, normal frame
3404  
3405 +       ;; If there is a glitch on the NMI pin shorter than ~100ns 
3406 +       ;; (i.e. non-active by the time we get here) then the nmi_pin bit
3407 +       ;; in R_IRQ_MASK0_RD will already be cleared.  The watchdog_nmi bit
3408 +       ;; is cleared by us however (when feeding the watchdog), which is why
3409 +       ;; we use that bit to determine what brought us here.
3410 +       
3411         move.d  [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog?
3412 -       and.d   0x80000000, $r1
3413 -       beq     wdog
3414 +       and.d   (1<<30), $r1
3415 +       bne     wdog
3416         move.d  $sp, $r10
3417         jsr     handle_nmi
3418         setf m                  ; Enable NMI again
3419 -       retb                    ; Return from NMI
3420 +       ba      _Rexit          ; Return the standard way
3421         nop
3422  wdog:
3423  #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
3424 @@ -774,23 +814,10 @@
3425         movem   $r13, [$sp]
3426         push    $r10            ; push orig_r10
3427         clear.d [$sp=$sp-4]     ; frametype == 0, normal frame
3428 -       
3429 -       moveq   2, $r2          ; first bit we care about is the timer0 irq
3430 -       move.d  [R_VECT_MASK_RD], $r0; read the irq bits that triggered the multiple irq
3431 -       move.d  $r0, [R_VECT_MASK_CLR] ; Block all active IRQs
3432 -1:     
3433 -       btst    $r2, $r0        ; check for the irq given by bit r2
3434 -       bpl     2f
3435 -       move.d  $r2, $r10       ; First argument to do_IRQ
3436 -       move.d  $sp, $r11       ; second argument to do_IRQ
3437 -       jsr     do_IRQ
3438 -2:
3439 -       addq    1, $r2          ; next vector bit
3440 -       cmp.b   32, $r2
3441 -       bne     1b      ; process all irq's up to and including number 31
3442 -       moveq   0, $r9  ; make ret_from_intr realise we came from an ir
3443 -       
3444 -       move.d  $r0, [R_VECT_MASK_SET] ;  Unblock all the IRQs
3445 +
3446 +       move.d  $sp, $r10
3447 +       jsr     do_multiple_IRQ
3448 +
3449         jump    ret_from_intr
3450  
3451  do_sigtrap:
3452 @@ -836,6 +863,13 @@
3453         pop     $r0                     ; Restore r0. 
3454         ba      do_sigtrap              ; SIGTRAP the offending process. 
3455         pop     $dccr                   ; Restore dccr in delay slot.
3456 +
3457 +       .global kernel_execve
3458 +kernel_execve:
3459 +       move.d __NR_execve, $r9
3460 +       break 13
3461 +       ret
3462 +       nop
3463         
3464         .data
3465  
3466 @@ -1135,7 +1169,38 @@
3467         .long sys_add_key
3468         .long sys_request_key
3469         .long sys_keyctl
3470 -
3471 +       .long sys_ioprio_set
3472 +       .long sys_ioprio_get            /* 290 */
3473 +       .long sys_inotify_init
3474 +       .long sys_inotify_add_watch
3475 +       .long sys_inotify_rm_watch
3476 +       .long sys_migrate_pages
3477 +       .long sys_openat                /* 295 */
3478 +       .long sys_mkdirat
3479 +       .long sys_mknodat
3480 +       .long sys_fchownat
3481 +       .long sys_futimesat
3482 +       .long sys_fstatat64             /* 300 */
3483 +       .long sys_unlinkat
3484 +       .long sys_renameat
3485 +       .long sys_linkat
3486 +       .long sys_symlinkat
3487 +       .long sys_readlinkat            /* 305 */
3488 +       .long sys_fchmodat
3489 +       .long sys_faccessat
3490 +       .long sys_pselect6
3491 +       .long sys_ppoll
3492 +       .long sys_unshare               /* 310 */
3493 +       .long sys_set_robust_list
3494 +       .long sys_get_robust_list
3495 +       .long sys_splice
3496 +       .long sys_sync_file_range
3497 +       .long sys_tee                   /* 315 */
3498 +       .long sys_vmsplice
3499 +       .long sys_move_pages
3500 +       .long sys_getcpu
3501 +       .long sys_epoll_pwait
3502 +               
3503          /*
3504           * NOTE!! This doesn't have to be exact - we just have
3505           * to make sure we have _enough_ of the "sys_ni_syscall"
3506 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/fasttimer.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/fasttimer.c
3507 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/fasttimer.c    2007-01-10 20:10:37.000000000 +0100
3508 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/fasttimer.c    2007-02-05 12:54:34.000000000 +0100
3509 @@ -1,97 +1,10 @@
3510 -/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $
3511 +/* 
3512   * linux/arch/cris/kernel/fasttimer.c
3513   *
3514   * Fast timers for ETRAX100/ETRAX100LX
3515   * This may be useful in other OS than Linux so use 2 space indentation...
3516   *
3517 - * $Log: fasttimer.c,v $
3518 - * Revision 1.9  2005/03/04 08:16:16  starvik
3519 - * Merge of Linux 2.6.11.
3520 - *
3521 - * Revision 1.8  2005/01/05 06:09:29  starvik
3522 - * cli()/sti() will be obsolete in 2.6.11.
3523 - *
3524 - * Revision 1.7  2005/01/03 13:35:46  starvik
3525 - * Removed obsolete stuff.
3526 - * Mark fast timer IRQ as not shared.
3527 - *
3528 - * Revision 1.6  2004/05/14 10:18:39  starvik
3529 - * Export fast_timer_list
3530 - *
3531 - * Revision 1.5  2004/05/14 07:58:01  starvik
3532 - * Merge of changes from 2.4
3533 - *
3534 - * Revision 1.4  2003/07/04 08:27:41  starvik
3535 - * Merge of Linux 2.5.74
3536 - *
3537 - * Revision 1.3  2002/12/12 08:26:32  starvik
3538 - * Don't use C-comments inside CVS comments
3539 - *
3540 - * Revision 1.2  2002/12/11 15:42:02  starvik
3541 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
3542 - *
3543 - * Revision 1.1  2002/11/18 07:58:06  starvik
3544 - * Fast timers (from Linux 2.4)
3545 - *
3546 - * Revision 1.5  2002/10/15 06:21:39  starvik
3547 - * Added call to init_waitqueue_head
3548 - *
3549 - * Revision 1.4  2002/05/28 17:47:59  johana
3550 - * Added del_fast_timer()
3551 - *
3552 - * Revision 1.3  2002/05/28 16:16:07  johana
3553 - * Handle empty fast_timer_list
3554 - *
3555 - * Revision 1.2  2002/05/27 15:38:42  johana
3556 - * Made it compile without warnings on Linux 2.4.
3557 - * (includes, wait_queue, PROC_FS and snprintf)
3558 - *
3559 - * Revision 1.1  2002/05/27 15:32:25  johana
3560 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
3561 - *
3562 - * Revision 1.8  2001/11/27 13:50:40  pkj
3563 - * Disable interrupts while stopping the timer and while modifying the
3564 - * list of active timers in timer1_handler() as it may be interrupted
3565 - * by other interrupts (e.g., the serial interrupt) which may add fast
3566 - * timers.
3567 - *
3568 - * Revision 1.7  2001/11/22 11:50:32  pkj
3569 - * * Only store information about the last 16 timers.
3570 - * * proc_fasttimer_read() now uses an allocated buffer, since it
3571 - *   requires more space than just a page even for only writing the
3572 - *   last 16 timers. The buffer is only allocated on request, so
3573 - *   unless /proc/fasttimer is read, it is never allocated.
3574 - * * Renamed fast_timer_started to fast_timers_started to match
3575 - *   fast_timers_added and fast_timers_expired.
3576 - * * Some clean-up.
3577 - *
3578 - * Revision 1.6  2000/12/13 14:02:08  johana
3579 - * Removed volatile for fast_timer_list
3580 - *
3581 - * Revision 1.5  2000/12/13 13:55:35  johana
3582 - * Added DEBUG_LOG, added som cli() and cleanup
3583 - *
3584 - * Revision 1.4  2000/12/05 13:48:50  johana
3585 - * Added range check when writing proc file, modified timer int handling
3586 - *
3587 - * Revision 1.3  2000/11/23 10:10:20  johana
3588 - * More debug/logging possibilities.
3589 - * Moved GET_JIFFIES_USEC() to timex.h and time.c
3590 - *
3591 - * Revision 1.2  2000/11/01 13:41:04  johana
3592 - * Clean up and bugfixes.
3593 - * Created new do_gettimeofday_fast() that gets a timeval struct
3594 - * with time based on jiffies and *R_TIMER0_DATA, uses a table
3595 - * for fast conversion of timer value to microseconds.
3596 - * (Much faster the standard do_gettimeofday() and we don't really
3597 - * wan't to use the true time - we wan't the "uptime" so timers don't screw up
3598 - * when we change the time.
3599 - * TODO: Add efficient support for continuous timers as well.
3600 - *
3601 - * Revision 1.1  2000/10/26 15:49:16  johana
3602 - * Added fasttimer, highresolution timers.
3603 - *
3604 - * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
3605 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
3606   */
3607  
3608  #include <linux/errno.h>
3609 @@ -136,13 +49,13 @@
3610  
3611  #define __INLINE__ inline
3612  
3613 -static int fast_timer_running = 0;
3614 -static int fast_timers_added = 0;
3615 -static int fast_timers_started = 0;
3616 -static int fast_timers_expired = 0;
3617 -static int fast_timers_deleted = 0;
3618 -static int fast_timer_is_init = 0;
3619 -static int fast_timer_ints = 0;
3620 +static unsigned int fast_timer_running = 0;
3621 +static unsigned int fast_timers_added = 0;
3622 +static unsigned int fast_timers_started = 0;
3623 +static unsigned int fast_timers_expired = 0;
3624 +static unsigned int fast_timers_deleted = 0;
3625 +static unsigned int fast_timer_is_init = 0;
3626 +static unsigned int fast_timer_ints = 0;
3627  
3628  struct fast_timer *fast_timer_list = NULL;
3629  
3630 @@ -150,8 +63,8 @@
3631  #define DEBUG_LOG_MAX 128
3632  static const char * debug_log_string[DEBUG_LOG_MAX];
3633  static unsigned long debug_log_value[DEBUG_LOG_MAX];
3634 -static int debug_log_cnt = 0;
3635 -static int debug_log_cnt_wrapped = 0;
3636 +static unsigned int debug_log_cnt = 0;
3637 +static unsigned int debug_log_cnt_wrapped = 0;
3638  
3639  #define DEBUG_LOG(string, value) \
3640  { \
3641 @@ -206,41 +119,25 @@
3642  int timer_delay_settings[NUM_TIMER_STATS];
3643  
3644  /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
3645 -void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
3646 +void __INLINE__ do_gettimeofday_fast(struct fasttime_t *tv)
3647  {
3648 -  unsigned long sec = jiffies;
3649 -  unsigned long usec = GET_JIFFIES_USEC();
3650 -
3651 -  usec += (sec % HZ) * (1000000 / HZ);
3652 -  sec = sec / HZ;
3653 -
3654 -  if (usec > 1000000)
3655 -  {
3656 -    usec -= 1000000;
3657 -    sec++;
3658 -  }
3659 -  tv->tv_sec = sec;
3660 -  tv->tv_usec = usec;
3661 +  tv->tv_jiff = jiffies;
3662 +  tv->tv_usec = GET_JIFFIES_USEC();
3663  }
3664  
3665 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
3666 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
3667  {
3668 -  if (t0->tv_sec < t1->tv_sec)
3669 -  {
3670 +  /* Compare jiffies. Takes care of wrapping */
3671 +  if (time_before(t0->tv_jiff, t1->tv_jiff))
3672      return -1;
3673 -  }
3674 -  else if (t0->tv_sec > t1->tv_sec)
3675 -  {
3676 +  else if (time_after(t0->tv_jiff, t1->tv_jiff))
3677      return 1;
3678 -  }
3679 +
3680 +  /* Compare us */
3681    if (t0->tv_usec < t1->tv_usec)
3682 -  {
3683      return -1;
3684 -  }
3685    else if (t0->tv_usec > t1->tv_usec)
3686 -  {
3687      return 1;
3688 -  }
3689    return 0;
3690  }
3691  
3692 @@ -340,7 +237,7 @@
3693          printk(KERN_WARNING
3694                 "timer name: %s data: 0x%08lX already in list!\n", name, data);
3695          sanity_failed++;
3696 -        return;
3697 +        goto done;
3698        }
3699        else
3700        {
3701 @@ -356,11 +253,11 @@
3702    t->name = name;
3703  
3704    t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
3705 -  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
3706 +  t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
3707    if (t->tv_expires.tv_usec > 1000000)
3708    {
3709      t->tv_expires.tv_usec -= 1000000;
3710 -    t->tv_expires.tv_sec++;
3711 +    t->tv_expires.tv_jiff += HZ;
3712    }
3713  #ifdef FAST_TIMER_LOG
3714    timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
3715 @@ -401,6 +298,7 @@
3716  
3717    D2(printk("start_one_shot_timer: %d us done\n", delay_us));
3718  
3719 +done:
3720    local_irq_restore(flags);
3721  } /* start_one_shot_timer */
3722  
3723 @@ -444,11 +342,18 @@
3724  /* Timer 1 interrupt handler */
3725  
3726  static irqreturn_t
3727 -timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
3728 +timer1_handler(int irq, void *dev_id)
3729  {
3730    struct fast_timer *t;
3731    unsigned long flags;
3732  
3733 +  /* We keep interrupts disabled not only when we modify the 
3734 +   * fast timer list, but any time we hold a reference to a
3735 +   * timer in the list, since del_fast_timer may be called
3736 +   * from (another) interrupt context.  Thus, the only time
3737 +   * when interrupts are enabled is when calling the timer
3738 +   * callback function.
3739 +   */
3740    local_irq_save(flags);
3741  
3742    /* Clear timer1 irq */
3743 @@ -466,16 +371,16 @@
3744    fast_timer_running = 0;
3745    fast_timer_ints++;
3746  
3747 -  local_irq_restore(flags);
3748 -
3749    t = fast_timer_list;
3750    while (t)
3751    {
3752 -    struct timeval tv;
3753 +    struct fasttime_t tv;
3754 +    fast_timer_function_type *f;
3755 +    unsigned long d;
3756  
3757      /* Has it really expired? */
3758      do_gettimeofday_fast(&tv);
3759 -    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
3760 +    D1(printk("t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
3761  
3762      if (timeval_cmp(&t->tv_expires, &tv) <= 0)
3763      {
3764 @@ -486,7 +391,6 @@
3765        fast_timers_expired++;
3766  
3767        /* Remove this timer before call, since it may reuse the timer */
3768 -      local_irq_save(flags);
3769        if (t->prev)
3770        {
3771          t->prev->next = t->next;
3772 @@ -501,11 +405,21 @@
3773        }
3774        t->prev = NULL;
3775        t->next = NULL;
3776 -      local_irq_restore(flags);
3777  
3778 -      if (t->function != NULL)
3779 +      /* Save function callback data before enabling interrupts,
3780 +       * since the timer may be removed and we don't know how it
3781 +       * was allocated (e.g. ->function and ->data may become
3782 +       * overwritten after deletion if the timer was stack-allocated).
3783 +       */
3784 +      f = t->function;
3785 +      d = t->data;
3786 +
3787 +      if (f != NULL)
3788        {
3789 -        t->function(t->data);
3790 +        /* Run the callback function with interrupts enabled. */
3791 +        local_irq_restore(flags);
3792 +        f(d);
3793 +        local_irq_save(flags);
3794        }
3795        else
3796        {
3797 @@ -518,16 +432,19 @@
3798        D1(printk(".\n"));
3799      }
3800  
3801 -    local_irq_save(flags);
3802      if ((t = fast_timer_list) != NULL)
3803      {
3804        /* Start next timer.. */
3805 -      long us;
3806 -      struct timeval tv;
3807 +      long us = 0;
3808 +      struct fasttime_t tv;
3809  
3810        do_gettimeofday_fast(&tv);
3811 -      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
3812 -            t->tv_expires.tv_usec - tv.tv_usec);
3813 +
3814 +      /* time_after_eq takes care of wrapping */
3815 +      if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
3816 +       us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ +
3817 +             t->tv_expires.tv_usec - tv.tv_usec);
3818 +
3819        if (us > 0)
3820        {
3821          if (!fast_timer_running)
3822 @@ -537,7 +454,6 @@
3823  #endif
3824            start_timer1(us);
3825          }
3826 -        local_irq_restore(flags);
3827          break;
3828        }
3829        else
3830 @@ -548,9 +464,10 @@
3831          D1(printk("e! %d\n", us));
3832        }
3833      }
3834 -    local_irq_restore(flags);
3835    }
3836  
3837 +  local_irq_restore(flags);
3838 +
3839    if (!t)
3840    {
3841      D1(printk("t1 stop!\n"));
3842 @@ -575,28 +492,17 @@
3843  void schedule_usleep(unsigned long us)
3844  {
3845    struct fast_timer t;
3846 -#ifdef DECLARE_WAITQUEUE
3847    wait_queue_head_t sleep_wait;
3848    init_waitqueue_head(&sleep_wait);
3849 -  {
3850 -  DECLARE_WAITQUEUE(wait, current);
3851 -#else
3852 -  struct wait_queue *sleep_wait = NULL;
3853 -  struct wait_queue wait = { current, NULL };
3854 -#endif
3855  
3856    D1(printk("schedule_usleep(%d)\n", us));
3857 -  add_wait_queue(&sleep_wait, &wait);
3858 -  set_current_state(TASK_INTERRUPTIBLE);
3859    start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
3860                         "usleep");
3861 -  schedule();
3862 -  set_current_state(TASK_RUNNING);
3863 -  remove_wait_queue(&sleep_wait, &wait);
3864 +  /* Uninterruptible sleep on the fast timer. (The condition is somewhat
3865 +     redundant since the timer is what wakes us up.) */
3866 +  wait_event(sleep_wait, !fast_timer_pending(&t));
3867 +
3868    D1(printk("done schedule_usleep(%d)\n", us));
3869 -#ifdef DECLARE_WAITQUEUE
3870 -  }
3871 -#endif  
3872  }
3873  
3874  #ifdef CONFIG_PROC_FS
3875 @@ -616,7 +522,7 @@
3876    unsigned long flags;
3877    int i = 0;
3878    int num_to_show;
3879 -  struct timeval tv;
3880 +  struct fasttime_t tv;
3881    struct fast_timer *t, *nextt;
3882    static char *bigbuf = NULL;
3883    static unsigned long used;
3884 @@ -624,7 +530,8 @@
3885    if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
3886    {
3887      used = 0;
3888 -    bigbuf[0] = '\0';
3889 +    if (buf)
3890 +           buf[0] = '\0';
3891      return 0;
3892    }
3893  
3894 @@ -646,7 +553,7 @@
3895      used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
3896                      fast_timer_running ? "yes" : "no");
3897      used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
3898 -                    (unsigned long)tv.tv_sec,
3899 +                    (unsigned long)tv.tv_jiff,
3900                      (unsigned long)tv.tv_usec);
3901  #ifdef FAST_TIMER_SANITY_CHECKS
3902      used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
3903 @@ -696,9 +603,9 @@
3904                        "d: %6li us data: 0x%08lX"
3905                        "\n",
3906                        t->name,
3907 -                      (unsigned long)t->tv_set.tv_sec,
3908 +                      (unsigned long)t->tv_set.tv_jiff,
3909                        (unsigned long)t->tv_set.tv_usec,
3910 -                      (unsigned long)t->tv_expires.tv_sec,
3911 +                      (unsigned long)t->tv_expires.tv_jiff,
3912                        (unsigned long)t->tv_expires.tv_usec,
3913                        t->delay_us,
3914                        t->data
3915 @@ -718,9 +625,9 @@
3916                        "d: %6li us data: 0x%08lX"
3917                        "\n",
3918                        t->name,
3919 -                      (unsigned long)t->tv_set.tv_sec,
3920 +                      (unsigned long)t->tv_set.tv_jiff,
3921                        (unsigned long)t->tv_set.tv_usec,
3922 -                      (unsigned long)t->tv_expires.tv_sec,
3923 +                      (unsigned long)t->tv_expires.tv_jiff,
3924                        (unsigned long)t->tv_expires.tv_usec,
3925                        t->delay_us,
3926                        t->data
3927 @@ -738,9 +645,9 @@
3928                        "d: %6li us data: 0x%08lX"
3929                        "\n",
3930                        t->name,
3931 -                      (unsigned long)t->tv_set.tv_sec,
3932 +                      (unsigned long)t->tv_set.tv_jiff,
3933                        (unsigned long)t->tv_set.tv_usec,
3934 -                      (unsigned long)t->tv_expires.tv_sec,
3935 +                      (unsigned long)t->tv_expires.tv_jiff,
3936                        (unsigned long)t->tv_expires.tv_usec,
3937                        t->delay_us,
3938                        t->data
3939 @@ -761,15 +668,15 @@
3940  /*                      " func: 0x%08lX" */
3941                        "\n",
3942                        t->name,
3943 -                      (unsigned long)t->tv_set.tv_sec,
3944 +                      (unsigned long)t->tv_set.tv_jiff,
3945                        (unsigned long)t->tv_set.tv_usec,
3946 -                      (unsigned long)t->tv_expires.tv_sec,
3947 +                      (unsigned long)t->tv_expires.tv_jiff,
3948                        (unsigned long)t->tv_expires.tv_usec,
3949                        t->delay_us,
3950                        t->data
3951  /*                      , t->function */
3952                        );
3953 -      local_irq_disable();
3954 +      local_irq_save(flags);
3955        if (t->next != nextt)
3956        {
3957          printk(KERN_WARNING "timer removed!\n");
3958 @@ -798,7 +705,7 @@
3959  static struct fast_timer tr[10];
3960  static int exp_num[10];
3961  
3962 -static struct timeval tv_exp[100];
3963 +static struct fasttime_t tv_exp[100];
3964  
3965  static void test_timeout(unsigned long data)
3966  {
3967 @@ -836,7 +743,7 @@
3968    int prev_num;
3969    int j;
3970  
3971 -  struct timeval tv, tv0, tv1, tv2;
3972 +  struct fasttime_t tv, tv0, tv1, tv2;
3973  
3974    printk("fast_timer_test() start\n");
3975    do_gettimeofday_fast(&tv);
3976 @@ -849,7 +756,7 @@
3977    {
3978      do_gettimeofday_fast(&tv_exp[j]);
3979    }
3980 -  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
3981 +  printk("fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
3982  
3983    for (j = 0; j < 1000; j++)
3984    {
3985 @@ -859,11 +766,11 @@
3986    for (j = 0; j < 100; j++)
3987    {
3988      printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
3989 -           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
3990 -           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
3991 -           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
3992 -           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
3993 -           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
3994 +           tv_exp[j].tv_jiff,tv_exp[j].tv_usec,
3995 +           tv_exp[j+1].tv_jiff,tv_exp[j+1].tv_usec,
3996 +           tv_exp[j+2].tv_jiff,tv_exp[j+2].tv_usec,
3997 +           tv_exp[j+3].tv_jiff,tv_exp[j+3].tv_usec,
3998 +           tv_exp[j+4].tv_jiff,tv_exp[j+4].tv_usec);
3999      j += 4;
4000    }
4001    do_gettimeofday_fast(&tv0);
4002 @@ -895,9 +802,9 @@
4003      }
4004    }
4005    do_gettimeofday_fast(&tv2);
4006 -  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
4007 -  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
4008 -  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
4009 +  printk("Timers started    %is %06i\n", tv0.tv_jiff, tv0.tv_usec);
4010 +  printk("Timers started at %is %06i\n", tv1.tv_jiff, tv1.tv_usec);
4011 +  printk("Timers done       %is %06i\n", tv2.tv_jiff, tv2.tv_usec);
4012    DP(printk("buf0:\n");
4013       printk(buf0);
4014       printk("buf1:\n");
4015 @@ -919,9 +826,9 @@
4016      printk("%-10s set: %6is %06ius exp: %6is %06ius "
4017             "data: 0x%08X func: 0x%08X\n",
4018             t->name,
4019 -           t->tv_set.tv_sec,
4020 +           t->tv_set.tv_jiff,
4021             t->tv_set.tv_usec,
4022 -           t->tv_expires.tv_sec,
4023 +           t->tv_expires.tv_jiff,
4024             t->tv_expires.tv_usec,
4025             t->data,
4026             t->function
4027 @@ -929,10 +836,10 @@
4028  
4029      printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
4030             t->delay_us,
4031 -           tv_exp[j].tv_sec,
4032 +           tv_exp[j].tv_jiff,
4033             tv_exp[j].tv_usec,
4034             exp_num[j],
4035 -           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
4036 +           (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
4037    }
4038    proc_fasttimer_read(buf5, NULL, 0, 0, 0);
4039    printk("buf5 after all done:\n");
4040 @@ -942,7 +849,7 @@
4041  #endif
4042  
4043  
4044 -void fast_timer_init(void)
4045 +int fast_timer_init(void)
4046  {
4047    /* For some reason, request_irq() hangs when called froom time_init() */
4048    if (!fast_timer_is_init)
4049 @@ -975,4 +882,6 @@
4050      fast_timer_test();
4051  #endif
4052    }
4053 +  return 0;
4054  }
4055 +__initcall(fast_timer_init);
4056 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/head.S linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/head.S
4057 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/head.S 2007-01-10 20:10:37.000000000 +0100
4058 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/head.S 2006-10-20 09:33:26.000000000 +0200
4059 @@ -1,4 +1,4 @@
4060 -/* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $
4061 +/* $Id: head.S,v 1.13 2006/10/20 07:33:26 kjelld Exp $
4062   * 
4063   * Head of the kernel - alter with care
4064   *
4065 @@ -7,6 +7,19 @@
4066   * Authors:    Bjorn Wesen (bjornw@axis.com)
4067   * 
4068   * $Log: head.S,v $
4069 + * Revision 1.13  2006/10/20 07:33:26  kjelld
4070 + * If serial port 2 is used, select it in R_GEN_CONFIG.
4071 + * If serial port 2 is used, setup the control registers for the port.
4072 + * This is done to avoid a puls on the TXD line during start up.
4073 + * This puls could disturbe some units (e.g. some Axis 214 with internal
4074 + * ver. 1.08).
4075 + *
4076 + * Revision 1.12  2006/10/13 12:43:11  starvik
4077 + * Merge of 2.6.18
4078 + *
4079 + * Revision 1.11  2005/08/29 07:32:17  starvik
4080 + * Merge of 2.6.13
4081 + *
4082   * Revision 1.10  2005/06/20 05:12:54  starvik
4083   * Remove unnecessary diff to kernel.org tree
4084   *
4085 @@ -595,11 +608,17 @@
4086  
4087         moveq   0,$r0
4088  
4089 +       ;; Select or disable serial port 2 
4090 +#ifdef CONFIG_ETRAX_SERIAL_PORT2
4091 +       or.d      IO_STATE (R_GEN_CONFIG, ser2, select),$r0
4092 +#else
4093 +       or.d      IO_STATE (R_GEN_CONFIG, ser2, disable),$r0    
4094 +#endif
4095 +       
4096         ;; Init interfaces (disable them).
4097         or.d      IO_STATE (R_GEN_CONFIG, scsi0, disable) \
4098                 | IO_STATE (R_GEN_CONFIG, ata, disable) \
4099                 | IO_STATE (R_GEN_CONFIG, par0, disable) \
4100 -               | IO_STATE (R_GEN_CONFIG, ser2, disable) \
4101                 | IO_STATE (R_GEN_CONFIG, mio, disable) \
4102                 | IO_STATE (R_GEN_CONFIG, scsi1, disable) \
4103                 | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \
4104 @@ -801,6 +820,41 @@
4105                 | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0
4106         move.b  $r0,[R_SERIAL1_TR_CTRL]
4107  
4108 +#ifdef CONFIG_ETRAX_SERIAL_PORT2       
4109 +       ;; setup the serial port 2 at 115200 baud for debug purposes
4110 +       
4111 +       moveq     IO_STATE (R_SERIAL2_XOFF, tx_stop, enable)            \
4112 +               | IO_STATE (R_SERIAL2_XOFF, auto_xoff, disable)         \
4113 +               | IO_FIELD (R_SERIAL2_XOFF, xoff_char, 0),$r0
4114 +       move.d  $r0,[R_SERIAL2_XOFF] 
4115 +
4116 +       ; 115.2kbaud for both transmit and receive
4117 +       move.b    IO_STATE (R_SERIAL2_BAUD, tr_baud, c115k2Hz)          \
4118 +               | IO_STATE (R_SERIAL2_BAUD, rec_baud, c115k2Hz),$r0
4119 +       move.b  $r0,[R_SERIAL2_BAUD]
4120 +
4121 +       ; Set up and enable the serial2 receiver.
4122 +       move.b    IO_STATE (R_SERIAL2_REC_CTRL, dma_err, stop)          \
4123 +               | IO_STATE (R_SERIAL2_REC_CTRL, rec_enable, enable)     \
4124 +               | IO_STATE (R_SERIAL2_REC_CTRL, rts_, active)           \
4125 +               | IO_STATE (R_SERIAL2_REC_CTRL, sampling, middle)       \
4126 +               | IO_STATE (R_SERIAL2_REC_CTRL, rec_stick_par, normal)  \
4127 +               | IO_STATE (R_SERIAL2_REC_CTRL, rec_par, even)          \
4128 +               | IO_STATE (R_SERIAL2_REC_CTRL, rec_par_en, disable)    \
4129 +               | IO_STATE (R_SERIAL2_REC_CTRL, rec_bitnr, rec_8bit),$r0
4130 +       move.b  $r0,[R_SERIAL2_REC_CTRL] 
4131 +       
4132 +       ; Set up and enable the serial2 transmitter.
4133 +       move.b    IO_FIELD (R_SERIAL2_TR_CTRL, txd, 0)                  \
4134 +               | IO_STATE (R_SERIAL2_TR_CTRL, tr_enable, enable)       \
4135 +               | IO_STATE (R_SERIAL2_TR_CTRL, auto_cts, disabled)      \
4136 +               | IO_STATE (R_SERIAL2_TR_CTRL, stop_bits, one_bit)      \
4137 +               | IO_STATE (R_SERIAL2_TR_CTRL, tr_stick_par, normal)    \
4138 +               | IO_STATE (R_SERIAL2_TR_CTRL, tr_par, even)            \
4139 +               | IO_STATE (R_SERIAL2_TR_CTRL, tr_par_en, disable)      \
4140 +               | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0
4141 +       move.b  $r0,[R_SERIAL2_TR_CTRL]
4142 +#endif
4143         
4144  #ifdef CONFIG_ETRAX_SERIAL_PORT3       
4145         ;; setup the serial port 3 at 115200 baud for debug purposes
4146 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/io_interface_mux.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/io_interface_mux.c
4147 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/io_interface_mux.c     2007-01-10 20:10:37.000000000 +0100
4148 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/io_interface_mux.c     2006-10-04 20:21:18.000000000 +0200
4149 @@ -1,10 +1,10 @@
4150  /* IO interface mux allocator for ETRAX100LX.
4151 - * Copyright 2004, Axis Communications AB
4152 - * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
4153 + * Copyright 2004-2006, Axis Communications AB
4154 + * $Id: io_interface_mux.c,v 1.4 2006/10/04 18:21:18 henriken Exp $
4155   */
4156  
4157  
4158 -/* C.f. ETRAX100LX Designer's Reference 20.9 */
4159 +/* C.f. ETRAX100LX Designer's Reference 19.9 */
4160  
4161  #include <linux/kernel.h>
4162  #include <linux/slab.h>
4163 @@ -35,7 +35,7 @@
4164  struct watcher
4165  {
4166         void (*notify)(const unsigned int gpio_in_available,
4167 -                      const unsigned int gpio_out_available,
4168 +                      const unsigned int gpio_out_available, 
4169                        const unsigned char pa_available,
4170                        const unsigned char pb_available);
4171         struct watcher *next;
4172 @@ -45,17 +45,40 @@
4173  struct if_group
4174  {
4175         enum io_if_group        group;
4176 -       unsigned char           used;
4177 -       enum cris_io_interface  owner;
4178 +       // name         - the name of the group 'A' to 'F'
4179 +       char                   *name;
4180 +       // used         - a bit mask of all pins in the group in the order listed
4181 +       //                in in the tables in 19.9.1 to 19.9.6.  Note that no
4182 +       //                distinction is made between in, out and in/out pins.
4183 +       unsigned int            used;
4184  };
4185  
4186  
4187  struct interface
4188  {
4189         enum cris_io_interface   ioif;
4190 +       // name - the name of the interface
4191 +       char                    *name;
4192 +       // groups       - OR'ed together io_if_group flags describing what pin groups
4193 +       //                the interface uses pins in.
4194         unsigned char            groups;
4195 +       // used         - set when the interface is allocated.
4196         unsigned char            used;
4197         char                    *owner;
4198 +       // group_a through group_f      - bit masks describing what pins in the
4199 +       //                                pin groups the interface uses.
4200 +       unsigned int             group_a;
4201 +       unsigned int             group_b;
4202 +       unsigned int             group_c;
4203 +       unsigned int             group_d;
4204 +       unsigned int             group_e;
4205 +       unsigned int             group_f;
4206 +
4207 +       // gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
4208 +       //                                 GPIO ports the interface uses.  This
4209 +       //                                 could be reconstucted using the group_X
4210 +       //                                 masks and a table of what pins the GPIO
4211 +       //                                 ports use, but that would be messy.
4212         unsigned int             gpio_g_in;
4213         unsigned int             gpio_g_out;
4214         unsigned char            gpio_b;
4215 @@ -64,26 +87,32 @@
4216  static struct if_group if_groups[6] = {
4217         {
4218                 .group = group_a,
4219 +               .name = "A",
4220                 .used = 0,
4221         },
4222         {
4223                 .group = group_b,
4224 +               .name = "B",
4225                 .used = 0,
4226         },
4227         {
4228                 .group = group_c,
4229 +               .name = "C",
4230                 .used = 0,
4231         },
4232         {
4233                 .group = group_d,
4234 +               .name = "D",
4235                 .used = 0,
4236         },
4237         {
4238                 .group = group_e,
4239 +               .name = "E",
4240                 .used = 0,
4241         },
4242         {
4243                 .group = group_f,
4244 +               .name = "F",
4245                 .used = 0,
4246         }
4247  };
4248 @@ -94,14 +123,32 @@
4249         /* Begin Non-multiplexed interfaces */
4250         {
4251                 .ioif = if_eth,
4252 +               .name = "ethernet",
4253                 .groups = 0,
4254 +
4255 +               .group_a = 0,
4256 +               .group_b = 0,
4257 +               .group_c = 0,
4258 +               .group_d = 0,
4259 +               .group_e = 0,
4260 +               .group_f = 0,
4261 +
4262                 .gpio_g_in = 0,
4263                 .gpio_g_out = 0,
4264                 .gpio_b = 0
4265         },
4266         {
4267                 .ioif = if_serial_0,
4268 +               .name = "serial_0",
4269                 .groups = 0,
4270 +
4271 +               .group_a = 0,
4272 +               .group_b = 0,
4273 +               .group_c = 0,
4274 +               .group_d = 0,
4275 +               .group_e = 0,
4276 +               .group_f = 0,
4277 +
4278                 .gpio_g_in = 0,
4279                 .gpio_g_out = 0,
4280                 .gpio_b = 0
4281 @@ -109,172 +156,385 @@
4282         /* End Non-multiplexed interfaces */
4283         {
4284                 .ioif = if_serial_1,
4285 +               .name = "serial_1",
4286                 .groups = group_e,
4287 +
4288 +               .group_a = 0,
4289 +               .group_b = 0,
4290 +               .group_c = 0,
4291 +               .group_d = 0,
4292 +               .group_e = 0x0f,
4293 +               .group_f = 0,
4294 +
4295                 .gpio_g_in =  0x00000000,
4296                 .gpio_g_out = 0x00000000,
4297                 .gpio_b = 0x00
4298         },
4299         {
4300                 .ioif = if_serial_2,
4301 +               .name = "serial_2",
4302                 .groups = group_b,
4303 +
4304 +               .group_a = 0,
4305 +               .group_b = 0x0f,
4306 +               .group_c = 0,
4307 +               .group_d = 0,
4308 +               .group_e = 0,
4309 +               .group_f = 0,
4310 +               
4311                 .gpio_g_in =  0x000000c0,
4312                 .gpio_g_out = 0x000000c0,
4313                 .gpio_b = 0x00
4314         },
4315         {
4316                 .ioif = if_serial_3,
4317 +               .name = "serial_3",
4318                 .groups = group_c,
4319 +
4320 +               .group_a = 0,
4321 +               .group_b = 0,
4322 +               .group_c = 0x0f,
4323 +               .group_d = 0,
4324 +               .group_e = 0,
4325 +               .group_f = 0,
4326 +
4327                 .gpio_g_in =  0xc0000000,
4328                 .gpio_g_out = 0xc0000000,
4329                 .gpio_b = 0x00
4330         },
4331         {
4332                 .ioif = if_sync_serial_1,
4333 -               .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3
4334 -                                              can be used simultaneously */
4335 +               .name = "sync_serial_1",
4336 +               .groups = group_e | group_f,
4337 +
4338 +               .group_a = 0,
4339 +               .group_b = 0,
4340 +               .group_c = 0,
4341 +               .group_d = 0,
4342 +               .group_e = 0x0f,
4343 +               .group_f = 0x10,
4344 +
4345                 .gpio_g_in =  0x00000000,
4346                 .gpio_g_out = 0x00000000,
4347                 .gpio_b = 0x10
4348         },
4349         {
4350                 .ioif = if_sync_serial_3,
4351 +               .name = "sync_serial_3",
4352                 .groups = group_c | group_f,
4353 +
4354 +               .group_a = 0,
4355 +               .group_b = 0,
4356 +               .group_c = 0x0f,
4357 +               .group_d = 0,
4358 +               .group_e = 0,
4359 +               .group_f = 0x80,
4360 +
4361                 .gpio_g_in =  0xc0000000,
4362                 .gpio_g_out = 0xc0000000,
4363                 .gpio_b = 0x80
4364         },
4365         {
4366                 .ioif = if_shared_ram,
4367 +               .name = "shared_ram",
4368                 .groups = group_a,
4369 +
4370 +               .group_a = 0x7f8ff,
4371 +               .group_b = 0,
4372 +               .group_c = 0,
4373 +               .group_d = 0,
4374 +               .group_e = 0,
4375 +               .group_f = 0,
4376 +
4377                 .gpio_g_in =  0x0000ff3e,
4378                 .gpio_g_out = 0x0000ff38,
4379                 .gpio_b = 0x00
4380         },
4381         {
4382                 .ioif = if_shared_ram_w,
4383 +               .name = "shared_ram_w",
4384                 .groups = group_a | group_d,
4385 +
4386 +               .group_a = 0x7f8ff,
4387 +               .group_b = 0,
4388 +               .group_c = 0,
4389 +               .group_d = 0xff,
4390 +               .group_e = 0,
4391 +               .group_f = 0,
4392 +               
4393                 .gpio_g_in =  0x00ffff3e,
4394                 .gpio_g_out = 0x00ffff38,
4395                 .gpio_b = 0x00
4396         },
4397         {
4398                 .ioif = if_par_0,
4399 +               .name = "par_0",
4400                 .groups = group_a,
4401 +
4402 +               .group_a = 0x7fbff,
4403 +               .group_b = 0,
4404 +               .group_c = 0,
4405 +               .group_d = 0,
4406 +               .group_e = 0,
4407 +               .group_f = 0,
4408 +
4409                 .gpio_g_in =  0x0000ff3e,
4410                 .gpio_g_out = 0x0000ff3e,
4411                 .gpio_b = 0x00
4412         },
4413         {
4414                 .ioif = if_par_1,
4415 +               .name = "par_1",
4416                 .groups = group_d,
4417 +
4418 +               .group_a = 0,
4419 +               .group_b = 0,
4420 +               .group_c = 0,
4421 +               .group_d = 0x7feff,
4422 +               .group_e = 0,
4423 +               .group_f = 0,
4424 +
4425                 .gpio_g_in =  0x3eff0000,
4426                 .gpio_g_out = 0x3eff0000,
4427                 .gpio_b = 0x00
4428         },
4429         {
4430                 .ioif = if_par_w,
4431 +               .name = "par_w",
4432                 .groups = group_a | group_d,
4433 +
4434 +               .group_a = 0x7fbff,
4435 +               .group_b = 0,
4436 +               .group_c = 0,
4437 +               .group_d = 0xff,
4438 +               .group_e = 0,
4439 +               .group_f = 0,
4440 +               
4441                 .gpio_g_in =  0x00ffff3e,
4442                 .gpio_g_out = 0x00ffff3e,
4443                 .gpio_b = 0x00
4444         },
4445         {
4446                 .ioif = if_scsi8_0,
4447 -               .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1
4448 -                                                         can be used simultaneously */
4449 +               .name = "scsi8_0",
4450 +               .groups = group_a | group_b | group_f,
4451 +
4452 +               .group_a = 0x7ffff,
4453 +               .group_b = 0x0f,
4454 +               .group_c = 0,
4455 +               .group_d = 0,
4456 +               .group_e = 0,
4457 +               .group_f = 0x10,
4458 +
4459                 .gpio_g_in =  0x0000ffff,
4460                 .gpio_g_out = 0x0000ffff,
4461                 .gpio_b = 0x10
4462         },
4463         {
4464                 .ioif = if_scsi8_1,
4465 -               .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1
4466 -                                                         can be used simultaneously */
4467 +               .name = "scsi8_1",
4468 +               .groups = group_c | group_d | group_f, 
4469 +
4470 +               .group_a = 0,
4471 +               .group_b = 0,
4472 +               .group_c = 0x0f,
4473 +               .group_d = 0x7ffff,
4474 +               .group_e = 0,
4475 +               .group_f = 0x80,
4476 +
4477                 .gpio_g_in =  0xffff0000,
4478                 .gpio_g_out = 0xffff0000,
4479                 .gpio_b = 0x80
4480         },
4481         {
4482                 .ioif = if_scsi_w,
4483 +               .name = "scsi_w",
4484                 .groups = group_a | group_b | group_d | group_f,
4485 +
4486 +               .group_a = 0x7ffff,
4487 +               .group_b = 0x0f,
4488 +               .group_c = 0,
4489 +               .group_d = 0x601ff,
4490 +               .group_e = 0,
4491 +               .group_f = 0x90,
4492 +
4493                 .gpio_g_in =  0x01ffffff,
4494                 .gpio_g_out = 0x07ffffff,
4495                 .gpio_b = 0x80
4496         },
4497         {
4498                 .ioif = if_ata,
4499 +               .name = "ata",
4500                 .groups = group_a | group_b | group_c | group_d,
4501 +
4502 +               .group_a = 0x7ffff,
4503 +               .group_b = 0x0f,
4504 +               .group_c = 0x0f,
4505 +               .group_d = 0x7cfff,
4506 +               .group_e = 0,
4507 +               .group_f = 0,
4508 +
4509                 .gpio_g_in =  0xf9ffffff,
4510                 .gpio_g_out = 0xffffffff,
4511                 .gpio_b = 0x80
4512         },
4513         {
4514                 .ioif = if_csp,
4515 -               .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4516 +               .name = "csp",
4517 +               .groups = group_f,
4518 +
4519 +               .group_a = 0,
4520 +               .group_b = 0,
4521 +               .group_c = 0,
4522 +               .group_d = 0,
4523 +               .group_e = 0,
4524 +               .group_f = 0xfc,
4525 +
4526                 .gpio_g_in =  0x00000000,
4527                 .gpio_g_out = 0x00000000,
4528                 .gpio_b = 0xfc
4529         },
4530         {
4531                 .ioif = if_i2c,
4532 -               .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4533 +               .name = "i2c",
4534 +               .groups = group_f,
4535 +
4536 +               .group_a = 0,
4537 +               .group_b = 0,
4538 +               .group_c = 0,
4539 +               .group_d = 0,
4540 +               .group_e = 0,
4541 +               .group_f = 0x03,
4542 +
4543                 .gpio_g_in =  0x00000000,
4544                 .gpio_g_out = 0x00000000,
4545                 .gpio_b = 0x03
4546         },
4547         {
4548                 .ioif = if_usb_1,
4549 +               .name = "usb_1",
4550                 .groups = group_e | group_f,
4551 +
4552 +               .group_a = 0,
4553 +               .group_b = 0,
4554 +               .group_c = 0,
4555 +               .group_d = 0,
4556 +               .group_e = 0x0f,
4557 +               .group_f = 0x2c,
4558 +               
4559                 .gpio_g_in =  0x00000000,
4560                 .gpio_g_out = 0x00000000,
4561                 .gpio_b = 0x2c
4562         },
4563         {
4564                 .ioif = if_usb_2,
4565 +               .name = "usb_2",
4566                 .groups = group_d,
4567 -               .gpio_g_in =  0x0e000000,
4568 -               .gpio_g_out = 0x3c000000,
4569 +
4570 +               .group_a = 0,
4571 +               .group_b = 0,
4572 +               .group_c = 0,
4573 +               .group_d = 0,
4574 +               .group_e = 0x33e00,
4575 +               .group_f = 0,
4576 +               
4577 +               .gpio_g_in =  0x3e000000,
4578 +               .gpio_g_out = 0x0c000000,
4579                 .gpio_b = 0x00
4580         },
4581         /* GPIO pins */
4582         {
4583                 .ioif = if_gpio_grp_a,
4584 +               .name = "gpio_a",
4585                 .groups = group_a,
4586 +
4587 +               .group_a = 0,
4588 +               .group_b = 0,
4589 +               .group_c = 0,
4590 +               .group_d = 0,
4591 +               .group_e = 0,
4592 +               .group_f = 0,
4593 +               
4594                 .gpio_g_in =  0x0000ff3f,
4595                 .gpio_g_out = 0x0000ff3f,
4596                 .gpio_b = 0x00
4597         },
4598         {
4599                 .ioif = if_gpio_grp_b,
4600 +               .name = "gpio_b",
4601                 .groups = group_b,
4602 +
4603 +               .group_a = 0,
4604 +               .group_b = 0,
4605 +               .group_c = 0,
4606 +               .group_d = 0,
4607 +               .group_e = 0,
4608 +               .group_f = 0,
4609 +               
4610                 .gpio_g_in =  0x000000c0,
4611                 .gpio_g_out = 0x000000c0,
4612                 .gpio_b = 0x00
4613         },
4614         {
4615                 .ioif = if_gpio_grp_c,
4616 +               .name = "gpio_c",
4617                 .groups = group_c,
4618 +
4619 +               .group_a = 0,
4620 +               .group_b = 0,
4621 +               .group_c = 0,
4622 +               .group_d = 0,
4623 +               .group_e = 0,
4624 +               .group_f = 0,
4625 +               
4626                 .gpio_g_in =  0xc0000000,
4627                 .gpio_g_out = 0xc0000000,
4628                 .gpio_b = 0x00
4629         },
4630         {
4631                 .ioif = if_gpio_grp_d,
4632 +               .name = "gpio_d",
4633                 .groups = group_d,
4634 +
4635 +               .group_a = 0,
4636 +               .group_b = 0,
4637 +               .group_c = 0,
4638 +               .group_d = 0,
4639 +               .group_e = 0,
4640 +               .group_f = 0,
4641 +               
4642                 .gpio_g_in =  0x3fff0000,
4643                 .gpio_g_out = 0x3fff0000,
4644                 .gpio_b = 0x00
4645         },
4646         {
4647                 .ioif = if_gpio_grp_e,
4648 +               .name = "gpio_e",
4649                 .groups = group_e,
4650 +
4651 +               .group_a = 0,
4652 +               .group_b = 0,
4653 +               .group_c = 0,
4654 +               .group_d = 0,
4655 +               .group_e = 0,
4656 +               .group_f = 0,
4657 +               
4658                 .gpio_g_in =  0x00000000,
4659                 .gpio_g_out = 0x00000000,
4660                 .gpio_b = 0x00
4661         },
4662         {
4663                 .ioif = if_gpio_grp_f,
4664 +               .name = "gpio_f",
4665                 .groups = group_f,
4666 +
4667 +               .group_a = 0,
4668 +               .group_b = 0,
4669 +               .group_c = 0,
4670 +               .group_d = 0,
4671 +               .group_e = 0,
4672 +               .group_f = 0,
4673 +               
4674                 .gpio_g_in =  0x00000000,
4675                 .gpio_g_out = 0x00000000,
4676                 .gpio_b = 0xff
4677 @@ -284,11 +544,13 @@
4678  
4679  static struct watcher *watchers = NULL;
4680  
4681 +// The pins that are free to use in the GPIO ports.
4682  static unsigned int gpio_in_pins =  0xffffffff;
4683  static unsigned int gpio_out_pins = 0xffffffff;
4684  static unsigned char gpio_pb_pins = 0xff;
4685  static unsigned char gpio_pa_pins = 0xff;
4686  
4687 +// Identifiers for the owners of the GPIO pins.
4688  static enum cris_io_interface gpio_pa_owners[8];
4689  static enum cris_io_interface gpio_pb_owners[8];
4690  static enum cris_io_interface gpio_pg_owners[32];
4691 @@ -318,7 +580,7 @@
4692         struct watcher *w = watchers;
4693  
4694         DBG(printk("io_interface_mux: notifying watchers\n"));
4695 -
4696 +       
4697         while (NULL != w) {
4698                 w->notify((const unsigned int)gpio_in_pins,
4699                           (const unsigned int)gpio_out_pins,
4700 @@ -354,37 +616,48 @@
4701  
4702         if (interfaces[ioif].used) {
4703                 local_irq_restore(flags);
4704 -               printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n",
4705 +               printk(KERN_CRIT "cris_io_interface: Cannot allocate interface %s for %s, in use by %s\n",
4706 +                      interfaces[ioif].name,
4707                        device_id,
4708                        interfaces[ioif].owner);
4709                 return -EBUSY;
4710         }
4711  
4712 -       /* Check that all required groups are free before allocating, */
4713 +       /* Check that all required pins in the used groups are free
4714 +        * before allocating. */
4715         group_set = interfaces[ioif].groups;
4716         while (NULL != (grp = get_group(group_set))) {
4717 -               if (grp->used) {
4718 -                       if (grp->group == group_f) {
4719 -                               if ((if_sync_serial_1 ==  ioif) ||
4720 -                                   (if_sync_serial_3 ==  ioif)) {
4721 -                                       if ((grp->owner != if_sync_serial_1) &&
4722 -                                           (grp->owner != if_sync_serial_3)) {
4723 -                                               local_irq_restore(flags);
4724 -                                               return -EBUSY;
4725 -                                       }
4726 -                               } else if ((if_scsi8_0 == ioif) ||
4727 -                                          (if_scsi8_1 == ioif)) {
4728 -                                       if ((grp->owner != if_scsi8_0) &&
4729 -                                           (grp->owner != if_scsi8_1)) {
4730 -                                               local_irq_restore(flags);
4731 -                                               return -EBUSY;
4732 -                                       }
4733 -                               }
4734 -                       } else {
4735 -                               local_irq_restore(flags);
4736 -                               return -EBUSY;
4737 -                       }
4738 +               unsigned int if_group_use = 0;
4739 +               
4740 +               switch(grp->group) {
4741 +               case group_a:
4742 +                       if_group_use = interfaces[ioif].group_a;
4743 +                       break;
4744 +               case group_b:
4745 +                       if_group_use = interfaces[ioif].group_b;
4746 +                       break;
4747 +               case group_c:
4748 +                       if_group_use = interfaces[ioif].group_c;
4749 +                       break;
4750 +               case group_d:
4751 +                       if_group_use = interfaces[ioif].group_d;
4752 +                       break;
4753 +               case group_e:
4754 +                       if_group_use = interfaces[ioif].group_e;
4755 +                       break;
4756 +               case group_f:
4757 +                       if_group_use = interfaces[ioif].group_f;
4758 +                       break;
4759 +               default:
4760 +                       BUG_ON(1);
4761                 }
4762 +
4763 +               if(if_group_use & grp->used) {
4764 +                       local_irq_restore(flags);
4765 +                       printk(KERN_INFO "cris_request_io_interface: group %s needed by %s not available\n", grp->name, interfaces[ioif].name);
4766 +                       return -EBUSY;
4767 +               }
4768 +
4769                 group_set = clear_group_from_set(group_set, grp);
4770         }
4771  
4772 @@ -392,22 +665,16 @@
4773         if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) ||
4774             ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) ||
4775             ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) {
4776 -               printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n",
4777 -                      ioif);
4778 +               local_irq_restore(flags);
4779 +               printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %s\n",
4780 +                      interfaces[ioif].name);
4781                 return -EBUSY;
4782         }
4783  
4784 -       /* All needed I/O pins and pin groups are free, allocate. */
4785 -       group_set = interfaces[ioif].groups;
4786 -       while (NULL != (grp = get_group(group_set))) {
4787 -               grp->used = 1;
4788 -               grp->owner = ioif;
4789 -               group_set = clear_group_from_set(group_set, grp);
4790 -       }
4791 -
4792 +       /* Check which registers need to be reconfigured. */
4793         gens = genconfig_shadow;
4794         gens_ii = gen_config_ii_shadow;
4795 -
4796 +       
4797         set_gen_config = 1;
4798         switch (ioif)
4799         {
4800 @@ -494,9 +761,43 @@
4801                 set_gen_config = 0;
4802                 break;
4803         default:
4804 -               panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
4805 -                     ioif,
4806 -                     device_id);
4807 +               local_irq_restore(flags);
4808 +               printk(KERN_INFO "cris_request_io_interface: Bad interface %u submitted for %s\n",
4809 +                      ioif,
4810 +                      device_id);
4811 +               return -EBUSY;
4812 +       }
4813 +
4814 +       /* All needed I/O pins and pin groups are free, allocate. */
4815 +       group_set = interfaces[ioif].groups;
4816 +       while (NULL != (grp = get_group(group_set))) {
4817 +               unsigned int if_group_use = 0;
4818 +
4819 +               switch(grp->group) {
4820 +               case group_a:
4821 +                       if_group_use = interfaces[ioif].group_a;
4822 +                       break;
4823 +               case group_b:
4824 +                       if_group_use = interfaces[ioif].group_b;
4825 +                       break;
4826 +               case group_c:
4827 +                       if_group_use = interfaces[ioif].group_c;
4828 +                       break;
4829 +               case group_d:
4830 +                       if_group_use = interfaces[ioif].group_d;
4831 +                       break;
4832 +               case group_e:
4833 +                       if_group_use = interfaces[ioif].group_e;
4834 +                       break;
4835 +               case group_f:
4836 +                       if_group_use = interfaces[ioif].group_f;
4837 +                       break;
4838 +               default:
4839 +                       BUG_ON(1);
4840 +               }
4841 +               grp->used |= if_group_use;
4842 +
4843 +               group_set = clear_group_from_set(group_set, grp);
4844         }
4845  
4846         interfaces[ioif].used = 1;
4847 @@ -528,7 +829,7 @@
4848  
4849         DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
4850                    gpio_in_pins, gpio_out_pins, gpio_pb_pins));
4851 -
4852 +       
4853         local_irq_restore(flags);
4854  
4855         notify_watchers();
4856 @@ -559,43 +860,36 @@
4857         }
4858         group_set = interfaces[ioif].groups;
4859         while (NULL != (grp = get_group(group_set))) {
4860 -               if (grp->group == group_f) {
4861 -                       switch (ioif)
4862 -                       {
4863 -                       case if_sync_serial_1:
4864 -                               if ((grp->owner == if_sync_serial_1) &&
4865 -                                   interfaces[if_sync_serial_3].used) {
4866 -                                       grp->owner = if_sync_serial_3;
4867 -                               } else
4868 -                                       grp->used = 0;
4869 -                               break;
4870 -                       case if_sync_serial_3:
4871 -                               if ((grp->owner == if_sync_serial_3) &&
4872 -                                   interfaces[if_sync_serial_1].used) {
4873 -                                       grp->owner = if_sync_serial_1;
4874 -                               } else
4875 -                                       grp->used = 0;
4876 -                               break;
4877 -                       case if_scsi8_0:
4878 -                               if ((grp->owner == if_scsi8_0) &&
4879 -                                   interfaces[if_scsi8_1].used) {
4880 -                                       grp->owner = if_scsi8_1;
4881 -                               } else
4882 -                                       grp->used = 0;
4883 -                               break;
4884 -                       case if_scsi8_1:
4885 -                               if ((grp->owner == if_scsi8_1) &&
4886 -                                   interfaces[if_scsi8_0].used) {
4887 -                                       grp->owner = if_scsi8_0;
4888 -                               } else
4889 -                                       grp->used = 0;
4890 -                               break;
4891 -                       default:
4892 -                               grp->used = 0;
4893 -                       }
4894 -               } else {
4895 -                       grp->used = 0;
4896 +               unsigned int if_group_use = 0;
4897 +
4898 +               switch(grp->group) {
4899 +               case group_a:
4900 +                       if_group_use = interfaces[ioif].group_a;
4901 +                       break;
4902 +               case group_b:
4903 +                       if_group_use = interfaces[ioif].group_b;
4904 +                       break;
4905 +               case group_c:
4906 +                       if_group_use = interfaces[ioif].group_c;
4907 +                       break;
4908 +               case group_d:
4909 +                       if_group_use = interfaces[ioif].group_d;
4910 +                       break;
4911 +               case group_e:
4912 +                       if_group_use = interfaces[ioif].group_e;
4913 +                       break;
4914 +               case group_f:
4915 +                       if_group_use = interfaces[ioif].group_f;
4916 +                       break;
4917 +               default:
4918 +                       BUG_ON(1);
4919                 }
4920 +
4921 +               if ((grp->used & if_group_use) != if_group_use) {
4922 +                       BUG_ON(1);
4923 +               }
4924 +               grp->used = grp->used & ~if_group_use;
4925 +
4926                 group_set = clear_group_from_set(group_set, grp);
4927         }
4928         interfaces[ioif].used = 0;
4929 @@ -784,7 +1078,7 @@
4930  
4931         for (i = start_bit; i <= stop_bit; i++) {
4932                 owners[i] = if_unclaimed;
4933 -       }
4934 +       }       
4935         local_irq_restore(flags);
4936         notify_watchers();
4937  
4938 @@ -821,7 +1115,7 @@
4939  }
4940  
4941  void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
4942 -                                                    const unsigned int gpio_out_available,
4943 +                                                    const unsigned int gpio_out_available, 
4944                                                       const unsigned char pa_available,
4945                                                      const unsigned char pb_available))
4946  {
4947 @@ -870,7 +1164,7 @@
4948  
4949  module_init(cris_io_interface_init);
4950  
4951 -
4952 +                                      
4953  EXPORT_SYMBOL(cris_request_io_interface);
4954  EXPORT_SYMBOL(cris_free_io_interface);
4955  EXPORT_SYMBOL(cris_io_interface_allocate_pins);
4956 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/irq.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/irq.c
4957 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/irq.c  2007-01-10 20:10:37.000000000 +0100
4958 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/irq.c  2006-10-30 16:17:03.000000000 +0100
4959 @@ -1,4 +1,4 @@
4960 -/* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $
4961 +/* $Id: irq.c,v 1.9 2006/10/30 15:17:03 pkj Exp $
4962   *
4963   *     linux/arch/cris/kernel/irq.c
4964   *
4965 @@ -12,7 +12,9 @@
4966   */
4967  
4968  #include <asm/irq.h>
4969 +#include <asm/current.h>
4970  #include <linux/irq.h>
4971 +#include <linux/interrupt.h>
4972  #include <linux/kernel.h>
4973  #include <linux/init.h>
4974  
4975 @@ -75,8 +77,8 @@
4976  BUILD_IRQ(13, 0x2000)
4977  void mmu_bus_fault(void);      /* IRQ 14 is the bus fault interrupt */
4978  void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
4979 -BUILD_IRQ(16, 0x10000)
4980 -BUILD_IRQ(17, 0x20000)
4981 +BUILD_IRQ(16, 0x10000 | 0x20000)  /* ethernet tx interrupt needs to block rx */
4982 +BUILD_IRQ(17, 0x20000 | 0x10000)  /* ...and vice versa */
4983  BUILD_IRQ(18, 0x40000)
4984  BUILD_IRQ(19, 0x80000)
4985  BUILD_IRQ(20, 0x100000)
4986 @@ -147,6 +149,55 @@
4987  void do_sigtrap(void); /* from entry.S */
4988  void gdb_handle_breakpoint(void); /* from entry.S */
4989  
4990 +extern void do_IRQ(int irq, struct pt_regs * regs);
4991 +
4992 +/* Handle multiple IRQs */
4993 +void do_multiple_IRQ(struct pt_regs* regs)
4994 +{
4995 +       int bit;
4996 +       unsigned masked;
4997 +       unsigned mask;
4998 +       unsigned ethmask = 0;
4999 +       
5000 +       /* Get interrupts to mask and handle */
5001 +       mask = masked = *R_VECT_MASK_RD;
5002 +       
5003 +       /* Never mask timer IRQ */
5004 +       mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));
5005 +
5006 +       /* 
5007 +        * If either ethernet interrupt (rx or tx) is active then block 
5008 +        * the other one too. Unblock afterwards also.
5009 +        */
5010 +       if (mask & 
5011 +           (IO_STATE(R_VECT_MASK_RD, dma0, active) |
5012 +            IO_STATE(R_VECT_MASK_RD, dma1, active))) {
5013 +               ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
5014 +                          IO_MASK(R_VECT_MASK_RD, dma1));
5015 +       }
5016 +
5017 +       /* Block them */
5018 +       *R_VECT_MASK_CLR = (mask | ethmask);
5019 +
5020 +       /* An extra irq_enter here to prevent softIRQs to run after
5021 +        * each do_IRQ. This will decrease the interrupt latency. 
5022 +        */
5023 +       irq_enter();
5024 +
5025 +       /* Handle all IRQs */
5026 +       for (bit = 2; bit < 32; bit++) {
5027 +               if (masked & (1 << bit)) {
5028 +                       do_IRQ(bit, regs);
5029 +               }
5030 +       }
5031 +
5032 +       /* This irq_exit() will trigger the soft IRQs. */
5033 +       irq_exit();
5034 +
5035 +       /* Unblock the IRQs again */
5036 +       *R_VECT_MASK_SET = (masked | ethmask);
5037 +}
5038 +
5039  /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
5040     setting the irq vector table.
5041  */
5042 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/kgdb.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/kgdb.c
5043 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/kgdb.c 2007-01-10 20:10:37.000000000 +0100
5044 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/kgdb.c 2006-03-22 10:56:55.000000000 +0100
5045 @@ -18,6 +18,10 @@
5046  *! Jul 21 1999  Bjorn Wesen     eLinux port
5047  *!
5048  *! $Log: kgdb.c,v $
5049 +*! Revision 1.7  2006/03/22 09:56:55  starvik
5050 +*! Merge of Linux 2.6.16
5051 +*!
5052 +*!
5053  *! Revision 1.6  2005/01/14 10:12:17  starvik
5054  *! KGDB on separate port.
5055  *! Console fixes from 2.4.
5056 @@ -75,7 +79,7 @@
5057  *!
5058  *!---------------------------------------------------------------------------
5059  *!
5060 -*! $Id: kgdb.c,v 1.6 2005/01/14 10:12:17 starvik Exp $
5061 +*! $Id: kgdb.c,v 1.7 2006/03/22 09:56:55 starvik Exp $
5062  *!
5063  *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
5064  *!
5065 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/process.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/process.c
5066 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/process.c      2007-01-10 20:10:37.000000000 +0100
5067 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/process.c      2006-10-13 14:43:11.000000000 +0200
5068 @@ -1,4 +1,4 @@
5069 -/* $Id: process.c,v 1.12 2004/12/27 11:18:32 starvik Exp $
5070 +/* $Id: process.c,v 1.14 2006/10/13 12:43:11 starvik Exp $
5071   * 
5072   *  linux/arch/cris/kernel/process.c
5073   *
5074 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/ptrace.c
5075 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/ptrace.c       2007-01-10 20:10:37.000000000 +0100
5076 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/ptrace.c       2006-10-30 16:17:57.000000000 +0100
5077 @@ -66,6 +66,7 @@
5078  ptrace_disable(struct task_struct *child)
5079  {
5080         /* Todo - pending singlesteps? */
5081 +       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
5082  }
5083  
5084  /* 
5085 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/setup.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/setup.c
5086 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/setup.c        2007-01-10 20:10:37.000000000 +0100
5087 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/setup.c        2006-10-13 14:43:11.000000000 +0200
5088 @@ -1,4 +1,4 @@
5089 -/*
5090 +/*  
5091   *
5092   *  linux/arch/cris/arch-v10/kernel/setup.c
5093   *
5094 @@ -13,6 +13,7 @@
5095  #include <linux/seq_file.h>
5096  #include <linux/proc_fs.h>
5097  #include <linux/delay.h>
5098 +#include <linux/param.h>
5099  
5100  #ifdef CONFIG_PROC_FS
5101  #define HAS_FPU                0x0001
5102 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/signal.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/signal.c
5103 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/signal.c       2007-01-10 20:10:37.000000000 +0100
5104 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/signal.c       2006-03-22 10:56:55.000000000 +0100
5105 @@ -41,7 +41,7 @@
5106   */
5107  #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
5108  
5109 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
5110 +void do_signal(int canrestart, struct pt_regs *regs);
5111  
5112  /*
5113   * Atomically swap in the new signal mask, and wait for a signal.  Define 
5114 @@ -52,68 +52,16 @@
5115  sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 
5116                 long srp, struct pt_regs *regs)
5117  {
5118 -       sigset_t saveset;
5119 -
5120         mask &= _BLOCKABLE;
5121         spin_lock_irq(&current->sighand->siglock);
5122 -       saveset = current->blocked;
5123 -       siginitset(&current->blocked, mask);
5124 -       recalc_sigpending();
5125 -       spin_unlock_irq(&current->sighand->siglock);
5126 -
5127 -       regs->r10 = -EINTR;
5128 -       while (1) {
5129 -               current->state = TASK_INTERRUPTIBLE;
5130 -               schedule();
5131 -               if (do_signal(0, &saveset, regs))
5132 -                       /* We will get here twice: once to call the signal
5133 -                          handler, then again to return from the
5134 -                          sigsuspend system call.  When calling the
5135 -                          signal handler, R10 holds the signal number as
5136 -                          set through do_signal.  The sigsuspend call
5137 -                          will return with the restored value set above;
5138 -                          always -EINTR.  */
5139 -                       return regs->r10;
5140 -       }
5141 -}
5142 -
5143 -/* Define dummy arguments to be able to reach the regs argument.  (Note that
5144 - * this arrangement relies on size_t occupying one register.)
5145 - */
5146 -int
5147 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13, 
5148 -                  long mof, long srp, struct pt_regs *regs)
5149 -{
5150 -       sigset_t saveset, newset;
5151 -
5152 -       /* XXX: Don't preclude handling different sized sigset_t's.  */
5153 -       if (sigsetsize != sizeof(sigset_t))
5154 -               return -EINVAL;
5155 -
5156 -       if (copy_from_user(&newset, unewset, sizeof(newset)))
5157 -               return -EFAULT;
5158 -       sigdelsetmask(&newset, ~_BLOCKABLE);
5159 -
5160 -       spin_lock_irq(&current->sighand->siglock);
5161 -       saveset = current->blocked;
5162 -       current->blocked = newset;
5163 +       current->saved_sigmask = current->blocked;
5164 +        siginitset(&current->blocked, mask);
5165         recalc_sigpending();
5166         spin_unlock_irq(&current->sighand->siglock);
5167 -
5168 -       regs->r10 = -EINTR;
5169 -       while (1) {
5170 -               current->state = TASK_INTERRUPTIBLE;
5171 -               schedule();
5172 -               if (do_signal(0, &saveset, regs))
5173 -                       /* We will get here twice: once to call the signal
5174 -                          handler, then again to return from the
5175 -                          sigsuspend system call.  When calling the
5176 -                          signal handler, R10 holds the signal number as
5177 -                          set through do_signal.  The sigsuspend call
5178 -                          will return with the restored value set above;
5179 -                          always -EINTR.  */
5180 -                       return regs->r10;
5181 -       }
5182 +       current->state = TASK_INTERRUPTIBLE;
5183 +       schedule();
5184 +       set_thread_flag(TIF_RESTORE_SIGMASK);
5185 +       return -ERESTARTNOHAND;
5186  }
5187  
5188  int 
5189 @@ -353,8 +301,8 @@
5190   * user-mode trampoline.
5191   */
5192  
5193 -static void setup_frame(int sig, struct k_sigaction *ka,
5194 -                       sigset_t *set, struct pt_regs * regs)
5195 +static int setup_frame(int sig, struct k_sigaction *ka,
5196 +                      sigset_t *set, struct pt_regs * regs)
5197  {
5198         struct sigframe __user *frame;
5199         unsigned long return_ip;
5200 @@ -402,14 +350,15 @@
5201  
5202         wrusp((unsigned long)frame);
5203  
5204 -       return;
5205 +       return 0;
5206  
5207  give_sigsegv:
5208         force_sigsegv(sig, current);
5209 +       return -EFAULT;
5210  }
5211  
5212 -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
5213 -                          sigset_t *set, struct pt_regs * regs)
5214 +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
5215 +                         sigset_t *set, struct pt_regs * regs)
5216  {
5217         struct rt_sigframe __user *frame;
5218         unsigned long return_ip;
5219 @@ -466,21 +415,24 @@
5220  
5221         wrusp((unsigned long)frame);
5222  
5223 -       return;
5224 +       return 0;
5225  
5226  give_sigsegv:
5227         force_sigsegv(sig, current);
5228 +       return -EFAULT;
5229  }
5230  
5231  /*
5232   * OK, we're invoking a handler
5233   */    
5234  
5235 -static inline void
5236 +static inline int
5237  handle_signal(int canrestart, unsigned long sig,
5238               siginfo_t *info, struct k_sigaction *ka,
5239                sigset_t *oldset, struct pt_regs * regs)
5240  {
5241 +       int ret;
5242 +
5243         /* Are we from a system call? */
5244         if (canrestart) {
5245                 /* If so, check system call restarting.. */
5246 @@ -510,19 +462,20 @@
5247  
5248         /* Set up the stack frame */
5249         if (ka->sa.sa_flags & SA_SIGINFO)
5250 -               setup_rt_frame(sig, ka, info, oldset, regs);
5251 +               ret = setup_rt_frame(sig, ka, info, oldset, regs);
5252         else
5253 -               setup_frame(sig, ka, oldset, regs);
5254 +               ret = setup_frame(sig, ka, oldset, regs);
5255  
5256 -       if (ka->sa.sa_flags & SA_ONESHOT)
5257 -               ka->sa.sa_handler = SIG_DFL;
5258 +       if (ret == 0) {
5259 +               spin_lock_irq(&current->sighand->siglock);
5260 +               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
5261 +               if (!(ka->sa.sa_flags & SA_NODEFER))
5262 +                     sigaddset(&current->blocked,sig);
5263 +                recalc_sigpending();
5264 +                spin_unlock_irq(&current->sighand->siglock);
5265 +       }
5266  
5267 -       spin_lock_irq(&current->sighand->siglock);
5268 -       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
5269 -       if (!(ka->sa.sa_flags & SA_NODEFER))
5270 -               sigaddset(&current->blocked,sig);
5271 -       recalc_sigpending();
5272 -       spin_unlock_irq(&current->sighand->siglock);
5273 +       return ret;
5274  }
5275  
5276  /*
5277 @@ -537,12 +490,13 @@
5278   * mode below.
5279   */
5280  
5281 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
5282 +void do_signal(int canrestart, struct pt_regs *regs)
5283  {
5284         siginfo_t info;
5285         int signr;
5286          struct k_sigaction ka;
5287 -
5288 +        sigset_t *oldset;
5289 +        
5290         /*
5291          * We want the common case to go fast, which
5292          * is why we may in certain cases get here from
5293 @@ -550,16 +504,26 @@
5294          * if so.
5295          */
5296         if (!user_mode(regs))
5297 -               return 1;
5298 +               return;
5299  
5300 -       if (!oldset)
5301 +        if (test_thread_flag(TIF_RESTORE_SIGMASK))
5302 +               oldset = &current->saved_sigmask;
5303 +       else
5304                 oldset = &current->blocked;
5305  
5306         signr = get_signal_to_deliver(&info, &ka, regs, NULL);
5307         if (signr > 0) {
5308                 /* Whee!  Actually deliver the signal.  */
5309 -               handle_signal(canrestart, signr, &info, &ka, oldset, regs);
5310 -               return 1;
5311 +               if (handle_signal(canrestart, signr, &info, &ka, oldset, regs)) {
5312 +                       /* a signal was successfully delivered; the saved
5313 +                        * sigmask will have been stored in the signal frame,
5314 +                        * and will be restored by sigreturn, so we can simply
5315 +                        * clear the TIF_RESTORE_SIGMASK flag */
5316 +                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
5317 +                               clear_thread_flag(TIF_RESTORE_SIGMASK);
5318 +               }
5319 +
5320 +               return;
5321         }
5322  
5323         /* Did we come from a system call? */
5324 @@ -575,5 +539,11 @@
5325                         regs->irp -= 2;
5326                 }
5327         }
5328 -       return 0;
5329 +
5330 +       /* if there's no signal to deliver, we just put the saved sigmask
5331 +        * back */
5332 +       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
5333 +               clear_thread_flag(TIF_RESTORE_SIGMASK);
5334 +               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
5335 +       }
5336  }
5337 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/time.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/time.c
5338 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/time.c 2007-01-10 20:10:37.000000000 +0100
5339 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/time.c 2007-01-09 10:29:18.000000000 +0100
5340 @@ -1,4 +1,4 @@
5341 -/* $Id: time.c,v 1.5 2004/09/29 06:12:46 starvik Exp $
5342 +/* $Id: time.c,v 1.10 2007/01/09 09:29:18 starvik Exp $
5343   *
5344   *  linux/arch/cris/arch-v10/kernel/time.c
5345   *
5346 @@ -20,6 +20,7 @@
5347  #include <asm/io.h>
5348  #include <asm/delay.h>
5349  #include <asm/rtc.h>
5350 +#include <asm/irq_regs.h>
5351  
5352  /* define this if you need to use print_timestamp */
5353  /* it will make jiffies at 96 hz instead of 100 hz though */
5354 @@ -202,8 +203,9 @@
5355  extern void cris_do_profile(struct pt_regs *regs);
5356  
5357  static inline irqreturn_t
5358 -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5359 +timer_interrupt(int irq, void *dev_id)
5360  {
5361 +       struct pt_regs* regs = get_irq_regs();
5362         /* acknowledge the timer irq */
5363  
5364  #ifdef USE_CASCADE_TIMERS
5365 @@ -222,9 +224,11 @@
5366  #endif
5367  
5368         /* reset watchdog otherwise it resets us! */
5369 -
5370         reset_watchdog();
5371         
5372 +        /* Update statistics. */
5373 +       update_process_times(user_mode(regs));
5374 +
5375         /* call the real timer interrupt handler */
5376  
5377         do_timer(1);
5378 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/traps.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/traps.c
5379 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/traps.c        2007-01-10 20:10:37.000000000 +0100
5380 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/traps.c        2006-12-11 14:04:24.000000000 +0100
5381 @@ -1,13 +1,10 @@
5382 -/* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $
5383 +/*
5384 + * Helper functions for trap handlers
5385   *
5386 - *  linux/arch/cris/arch-v10/traps.c
5387 + * Copyright (C) 2000-2006, Axis Communications AB.
5388   *
5389 - *  Heler functions for trap handlers
5390 - * 
5391 - *  Copyright (C) 2000-2002 Axis Communications AB
5392 - *
5393 - *  Authors:   Bjorn Wesen
5394 - *            Hans-Peter Nilsson
5395 + * Authors:   Bjorn Wesen
5396 + *            Hans-Peter Nilsson
5397   *
5398   */
5399  
5400 @@ -15,124 +12,118 @@
5401  #include <asm/uaccess.h>
5402  #include <asm/arch/sv_addr_ag.h>
5403  
5404 -extern int raw_printk(const char *fmt, ...);
5405 -
5406 -void 
5407 -show_registers(struct pt_regs * regs)
5408 +void
5409 +show_registers(struct pt_regs *regs)
5410  {
5411 -       /* We either use rdusp() - the USP register, which might not
5412 -          correspond to the current process for all cases we're called,
5413 -          or we use the current->thread.usp, which is not up to date for
5414 -          the current process.  Experience shows we want the USP
5415 -          register.  */
5416 +       /*
5417 +        * It's possible to use either the USP register or current->thread.usp.
5418 +        * USP might not correspond to the current process for all cases this
5419 +        * function is called, and current->thread.usp isn't up to date for the
5420 +        * current process. Experience shows that using USP is the way to go.
5421 +        */
5422         unsigned long usp = rdusp();
5423  
5424 -       raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
5425 -              regs->irp, regs->srp, regs->dccr, usp, regs->mof );
5426 -       raw_printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
5427 +       printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
5428 +              regs->irp, regs->srp, regs->dccr, usp, regs->mof);
5429 +
5430 +       printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
5431                regs->r0, regs->r1, regs->r2, regs->r3);
5432 -       raw_printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
5433 +
5434 +       printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
5435                regs->r4, regs->r5, regs->r6, regs->r7);
5436 -       raw_printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
5437 +
5438 +       printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
5439                regs->r8, regs->r9, regs->r10, regs->r11);
5440 -       raw_printk("r12: %08lx r13: %08lx oR10: %08lx  sp: %08lx\n",
5441 -              regs->r12, regs->r13, regs->orig_r10, regs);
5442 -       raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
5443 -       raw_printk("Process %s (pid: %d, stackpage=%08lx)\n",
5444 +
5445 +       printk("r12: %08lx r13: %08lx oR10: %08lx  sp: %08lx\n",
5446 +              regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs);
5447 +
5448 +       printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
5449 +
5450 +       printk("Process %s (pid: %d, stackpage=%08lx)\n",
5451                current->comm, current->pid, (unsigned long)current);
5452  
5453         /*
5454 -         * When in-kernel, we also print out the stack and code at the
5455 -         * time of the fault..
5456 -         */
5457 -        if (! user_mode(regs)) {
5458 -               int i;
5459 +        * When in-kernel, we also print out the stack and code at the
5460 +        * time of the fault..
5461 +        */
5462 +       if (!user_mode(regs)) {
5463 +               int i;
5464  
5465 -                show_stack(NULL, (unsigned long*)usp);
5466 +               show_stack(NULL, (unsigned long *)usp);
5467  
5468 -               /* Dump kernel stack if the previous dump wasn't one.  */
5469 +               /*
5470 +                * If the previous stack-dump wasn't a kernel one, dump the
5471 +                * kernel stack now.
5472 +                */
5473                 if (usp != 0)
5474 -                       show_stack (NULL, NULL);
5475 +                       show_stack(NULL, NULL);
5476  
5477 -                raw_printk("\nCode: ");
5478 -                if(regs->irp < PAGE_OFFSET)
5479 -                        goto bad;
5480 -
5481 -               /* Often enough the value at regs->irp does not point to
5482 -                  the interesting instruction, which is most often the
5483 -                  _previous_ instruction.  So we dump at an offset large
5484 -                  enough that instruction decoding should be in sync at
5485 -                  the interesting point, but small enough to fit on a row
5486 -                  (sort of).  We point out the regs->irp location in a
5487 -                  ksymoops-friendly way by wrapping the byte for that
5488 -                  address in parentheses.  */
5489 -                for(i = -12; i < 12; i++)
5490 -                {
5491 -                        unsigned char c;
5492 -                        if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
5493 -bad:
5494 -                                raw_printk(" Bad IP value.");
5495 -                                break;
5496 -                        }
5497 +               printk("\nCode: ");
5498 +
5499 +               if (regs->irp < PAGE_OFFSET)
5500 +                       goto bad_value;
5501 +
5502 +               /*
5503 +                * Quite often the value at regs->irp doesn't point to the
5504 +                * interesting instruction, which often is the previous
5505 +                * instruction. So dump at an offset large enough that the
5506 +                * instruction decoding should be in sync at the interesting
5507 +                * point, but small enough to fit on a row. The regs->irp
5508 +                * location is pointed out in a ksymoops-friendly way by
5509 +                * wrapping the byte for that address in parenthesises.
5510 +                */
5511 +               for (i = -12; i < 12; i++) {
5512 +                       unsigned char c;
5513 +
5514 +                       if (__get_user(c, &((unsigned char *)regs->irp)[i])) {
5515 +bad_value:
5516 +                               printk(" Bad IP value.");
5517 +                               break;
5518 +                       }
5519  
5520                         if (i == 0)
5521 -                         raw_printk("(%02x) ", c);
5522 +                               printk("(%02x) ", c);
5523                         else
5524 -                         raw_printk("%02x ", c);
5525 -                }
5526 -               raw_printk("\n");
5527 -        }
5528 +                               printk("%02x ", c);
5529 +               }
5530 +               printk("\n");
5531 +       }
5532  }
5533  
5534 -/* Called from entry.S when the watchdog has bitten
5535 - * We print out something resembling an oops dump, and if
5536 - * we have the nice doggy development flag set, we halt here
5537 - * instead of rebooting.
5538 - */
5539 -
5540 -extern void reset_watchdog(void);
5541 -extern void stop_watchdog(void);
5542 -
5543 -
5544  void
5545 -watchdog_bite_hook(struct pt_regs *regs)
5546 +arch_enable_nmi(void)
5547  {
5548 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5549 -       local_irq_disable();
5550 -       stop_watchdog();
5551 -       show_registers(regs);
5552 -       while(1) /* nothing */;
5553 -#else
5554 -       show_registers(regs);
5555 -#endif 
5556 +       asm volatile ("setf m");
5557  }
5558  
5559 -/* This is normally the 'Oops' routine */
5560 -void 
5561 -die_if_kernel(const char * str, struct pt_regs * regs, long err)
5562 +extern void (*nmi_handler)(struct pt_regs*);
5563 +void handle_nmi(struct pt_regs* regs)
5564  {
5565 -       if(user_mode(regs))
5566 -               return;
5567 -
5568 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5569 -       /* This printout might take too long and trigger the 
5570 -        * watchdog normally. If we're in the nice doggy
5571 -        * development mode, stop the watchdog during printout.
5572 -        */
5573 -       stop_watchdog();
5574 -#endif
5575 -
5576 -       raw_printk("%s: %04lx\n", str, err & 0xffff);
5577 -
5578 -       show_registers(regs);
5579 +  if (nmi_handler)
5580 +    nmi_handler(regs);
5581  
5582 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5583 -       reset_watchdog();
5584 -#endif
5585 -       do_exit(SIGSEGV);
5586 +  /* Wait until nmi is no longer active. (We enable NMI immediately after
5587 +     returning from this function, and we don't want it happening while
5588 +     exiting from the NMI interrupt handler.) */
5589 +  while(*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active)); 
5590  }
5591  
5592 -void arch_enable_nmi(void)
5593 +#ifdef CONFIG_DEBUG_BUGVERBOSE
5594 +void
5595 +handle_BUG(struct pt_regs *regs)
5596  {
5597 -  asm volatile("setf m");
5598 +       struct bug_frame f;
5599 +       unsigned char c;
5600 +       unsigned long irp = regs->irp;
5601 +
5602 +       if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f))
5603 +               return;
5604 +       if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
5605 +               return;
5606 +       if (__get_user(c, f.filename))
5607 +               f.filename = "<bad filename>";
5608 +
5609 +       printk("kernel BUG at %s:%d!\n", f.filename, f.line);
5610  }
5611 +#endif
5612 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksum.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksum.S
5613 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksum.S        2007-01-10 20:10:37.000000000 +0100
5614 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksum.S        2005-08-16 12:38:52.000000000 +0200
5615 @@ -1,4 +1,4 @@
5616 -/* $Id: checksum.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
5617 +/* $Id: checksum.S,v 1.2 2005/08/16 10:38:52 edgar Exp $
5618   * A fast checksum routine using movem
5619   * Copyright (c) 1998-2001 Axis Communications AB
5620   *
5621 @@ -61,8 +61,6 @@
5622         
5623         ax
5624         addq    0,$r12
5625 -       ax                      ; do it again, since we might have generated a carry
5626 -       addq    0,$r12
5627  
5628         subq    10*4,$r11
5629         bge     _mloop
5630 @@ -88,10 +86,6 @@
5631         lsrq    16,$r13         ; r13 = checksum >> 16
5632         and.d   $r9,$r12                ; checksum = checksum & 0xffff
5633         add.d   $r13,$r12               ; checksum += r13
5634 -       move.d  $r12,$r13               ; do the same again, maybe we got a carry last add
5635 -       lsrq    16,$r13
5636 -       and.d   $r9,$r12
5637 -       add.d   $r13,$r12
5638  
5639  _no_fold:
5640         cmpq    2,$r11
5641 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksumcopy.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksumcopy.S
5642 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksumcopy.S    2007-01-10 20:10:37.000000000 +0100
5643 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksumcopy.S    2005-08-16 12:38:52.000000000 +0200
5644 @@ -1,4 +1,4 @@
5645 -/* $Id: checksumcopy.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
5646 +/* $Id: checksumcopy.S,v 1.2 2005/08/16 10:38:52 edgar Exp $
5647   * A fast checksum+copy routine using movem
5648   * Copyright (c) 1998, 2001 Axis Communications AB
5649   *
5650 @@ -67,8 +67,6 @@
5651         
5652         ax
5653         addq    0,$r13
5654 -       ax                      ; do it again, since we might have generated a carry
5655 -       addq    0,$r13
5656  
5657         subq    10*4,$r12
5658         bge     _mloop
5659 @@ -91,10 +89,6 @@
5660         lsrq    16,$r9          ; r0 = checksum >> 16
5661         and.d   0xffff,$r13     ; checksum = checksum & 0xffff
5662         add.d   $r9,$r13        ; checksum += r0
5663 -       move.d  $r13,$r9        ; do the same again, maybe we got a carry last add
5664 -       lsrq    16,$r9
5665 -       and.d   0xffff,$r13
5666 -       add.d   $r9,$r13
5667         
5668  _no_fold:
5669         cmpq    2,$r12
5670 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/dram_init.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/dram_init.S
5671 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/dram_init.S       2007-01-10 20:10:37.000000000 +0100
5672 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/dram_init.S       2006-10-13 14:43:11.000000000 +0200
5673 @@ -1,4 +1,4 @@
5674 -/* $Id: dram_init.S,v 1.4 2003/09/22 09:21:59 starvik Exp $
5675 +/* $Id: dram_init.S,v 1.5 2006/10/13 12:43:11 starvik Exp $
5676   * 
5677   * DRAM/SDRAM initialization - alter with care
5678   * This file is intended to be included from other assembler files
5679 @@ -11,6 +11,9 @@
5680   * Authors:  Mikael Starvik (starvik@axis.com) 
5681   * 
5682   * $Log: dram_init.S,v $
5683 + * Revision 1.5  2006/10/13 12:43:11  starvik
5684 + * Merge of 2.6.18
5685 + *
5686   * Revision 1.4  2003/09/22 09:21:59  starvik
5687   * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx
5688   * so we need to mask off 12 bits.
5689 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/mm/fault.c linux-2.6.19.2.dev/arch/cris/arch-v10/mm/fault.c
5690 --- linux-2.6.19.2.old/arch/cris/arch-v10/mm/fault.c    2007-01-10 20:10:37.000000000 +0100
5691 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/mm/fault.c    2006-12-11 12:32:10.000000000 +0100
5692 @@ -73,7 +73,7 @@
5693         /* leave it to the MM system fault handler */
5694         if (miss)
5695                 do_page_fault(address, regs, 0, writeac);
5696 -        else
5697 +        else   
5698                 do_page_fault(address, regs, 1, we);
5699  
5700          /* Reload TLB with new entry to avoid an extra miss exception.
5701 @@ -84,12 +84,13 @@
5702         local_irq_disable();
5703         pmd = (pmd_t *)(pgd + pgd_index(address));
5704         if (pmd_none(*pmd))
5705 -               return;
5706 +               goto exit;
5707         pte = *pte_offset_kernel(pmd, address);
5708         if (!pte_present(pte))
5709 -               return;
5710 +               goto exit;
5711         *R_TLB_SELECT = select;
5712         *R_TLB_HI = cause;
5713         *R_TLB_LO = pte_val(pte);
5714 +exit:
5715         local_irq_restore(flags);
5716  }
5717 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/mm/tlb.c linux-2.6.19.2.dev/arch/cris/arch-v10/mm/tlb.c
5718 --- linux-2.6.19.2.old/arch/cris/arch-v10/mm/tlb.c      2007-01-10 20:10:37.000000000 +0100
5719 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/mm/tlb.c      2006-08-07 12:08:35.000000000 +0200
5720 @@ -179,23 +179,26 @@
5721  switch_mm(struct mm_struct *prev, struct mm_struct *next,
5722           struct task_struct *tsk)
5723  {
5724 -       /* make sure we have a context */
5725 +       if (prev != next) {
5726 +               /* make sure we have a context */
5727 +               get_mmu_context(next);
5728 +
5729 +               /* remember the pgd for the fault handlers
5730 +                * this is similar to the pgd register in some other CPU's.
5731 +                * we need our own copy of it because current and active_mm
5732 +                * might be invalid at points where we still need to derefer
5733 +                * the pgd.
5734 +                */
5735  
5736 -       get_mmu_context(next);
5737 +               per_cpu(current_pgd, smp_processor_id()) = next->pgd;
5738  
5739 -       /* remember the pgd for the fault handlers
5740 -        * this is similar to the pgd register in some other CPU's.
5741 -        * we need our own copy of it because current and active_mm
5742 -        * might be invalid at points where we still need to derefer
5743 -        * the pgd.
5744 -        */
5745 -
5746 -       per_cpu(current_pgd, smp_processor_id()) = next->pgd;
5747 -
5748 -       /* switch context in the MMU */
5749 +               /* switch context in the MMU */
5750         
5751 -       D(printk("switching mmu_context to %d (%p)\n", next->context, next));
5752 +               D(printk("switching mmu_context to %d (%p)\n",
5753 +                        next->context, next));
5754  
5755 -       *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT, page_id, next->context.page_id);
5756 +               *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT,
5757 +                                         page_id, next->context.page_id);
5758 +       }
5759  }
5760  
5761 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v32/Kconfig
5762 --- linux-2.6.19.2.old/arch/cris/arch-v32/Kconfig       2007-01-10 20:10:37.000000000 +0100
5763 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/Kconfig       2007-01-09 10:29:18.000000000 +0100
5764 @@ -1,23 +1,66 @@
5765 +source drivers/cpufreq/Kconfig
5766 +
5767  config ETRAX_DRAM_VIRTUAL_BASE
5768         hex
5769         depends on ETRAX_ARCH_V32
5770         default "c0000000"
5771  
5772 -config ETRAX_LED1G
5773 -       string "First green LED bit"
5774 +choice
5775 +       prompt "Nbr of Ethernet LED groups"
5776         depends on ETRAX_ARCH_V32
5777 +       default ETRAX_NBR_LED_GRP_ONE
5778 +       help
5779 +         Select how many Ethernet LED groups that can be used. Usually one per Ethernet
5780 +         interface is a good choice.
5781 +
5782 +config ETRAX_NBR_LED_GRP_ZERO
5783 +       bool "Use zero LED groups"
5784 +       help
5785 +         Select this if you do not want any Ethernet LEDs.
5786 +
5787 +config ETRAX_NBR_LED_GRP_ONE
5788 +       bool "Use one LED group"
5789 +       help
5790 +         Select this if you want one Ethernet LED group. This LED group can be used for
5791 +         one or more Ethernet interfaces. However, it is recomended that each Ethernet 
5792 +         interface use a dedicated LED group.
5793 +
5794 +config ETRAX_NBR_LED_GRP_TWO
5795 +       bool "Use two LED groups"
5796 +       help
5797 +         Select this if you want two Ethernet LED groups. This is the best choice if you
5798 +         have more than one Ethernet interface and would like to have separate LEDs for
5799 +         the interfaces.
5800 +
5801 +endchoice
5802 +
5803 +config ETRAX_LED_G_NET0
5804 +       string "Ethernet LED group 0 green LED bit"
5805 +       depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
5806         default "PA3"
5807         help
5808 -         Bit to use for the first green LED (network LED).
5809 -         Most Axis products use bit A3 here.
5810 +         Bit to use for the green LED in Ethernet LED group 0.
5811  
5812 -config ETRAX_LED1R
5813 -       string "First red LED bit"
5814 -       depends on ETRAX_ARCH_V32
5815 +config ETRAX_LED_R_NET0
5816 +       string "Ethernet LED group 0 red LED bit"
5817 +       depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
5818         default "PA4"
5819         help
5820 -         Bit to use for the first red LED (network LED).
5821 -         Most Axis products use bit A4 here.
5822 +         Bit to use for the red LED in Ethernet LED group 0.
5823 +
5824 +config ETRAX_LED_G_NET1
5825 +       string "Ethernet group 1 green LED bit"
5826 +       depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
5827 +       default ""
5828 +       help
5829 +         Bit to use for the green LED in Ethernet LED group 1.
5830 +
5831 +config ETRAX_LED_R_NET1
5832 +       string "Ethernet group 1 red LED bit"
5833 +       depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
5834 +       default ""
5835 +       help
5836 +         Bit to use for the red LED in Ethernet LED group 1.
5837  
5838  config ETRAX_LED2G
5839         string "Second green LED bit"
5840 @@ -294,3 +337,22 @@
5841         help
5842           Configures the initial data for the general port E bits.  Most
5843           products should use 00000 here.
5844 +
5845 +config ETRAX_DEF_GIO_PV_OE
5846 +       hex "GIO_PV_OE"
5847 +       depends on ETRAX_VIRTUAL_GPIO
5848 +       default "0000"
5849 +       help
5850 +         Configures the direction of virtual general port V bits. 1 is out,
5851 +         0 is in. This is often totally different depending on the product
5852 +         used. These bits are used for all kinds of stuff. If you don't know
5853 +         what to use, it is always safe to put all as inputs, although
5854 +         floating inputs isn't good.
5855 +
5856 +config ETRAX_DEF_GIO_PV_OUT
5857 +       hex "GIO_PV_OUT"
5858 +       depends on ETRAX_VIRTUAL_GPIO
5859 +       default "0000"
5860 +       help
5861 +         Configures the initial data for the virtual general port V bits.
5862 +         Most products should use 0000 here.
5863 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/Makefile
5864 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/Makefile 2007-01-10 20:10:37.000000000 +0100
5865 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/Makefile 2006-11-29 17:05:41.000000000 +0100
5866 @@ -1,14 +1,21 @@
5867  #
5868  # arch/cris/arch-v32/boot/Makefile
5869  #
5870 -target = $(target_boot_dir)
5871 -src    = $(src_boot_dir)
5872  
5873 -zImage: compressed/vmlinuz
5874 +OBJCOPY = objcopy-cris
5875 +OBJCOPYFLAGS = -O binary -R .note -R .comment
5876  
5877 -compressed/vmlinuz: $(objtree)/vmlinux
5878 -       @$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz
5879 +subdir- := compressed rescue
5880 +targets := Image
5881  
5882 -clean:
5883 -       rm -f zImage tools/build compressed/vmlinux.out
5884 -       @$(MAKE) -f $(src)/compressed/Makefile clean
5885 +$(obj)/Image: vmlinux FORCE
5886 +       $(call if_changed,objcopy)
5887 +       @echo '  Kernel: $@ is ready'
5888 +
5889 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
5890 +       $(Q)$(MAKE) $(build)=$(obj)/compressed $@
5891 +       $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
5892 +
5893 +$(obj)/zImage:  $(obj)/compressed/vmlinux
5894 +       @cp $< $@
5895 +       @echo '  Kernel: $@ is ready'
5896 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/Makefile
5897 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/Makefile      2007-01-10 20:10:37.000000000 +0100
5898 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/Makefile      2006-11-29 17:05:42.000000000 +0100
5899 @@ -1,41 +1,29 @@
5900  #
5901 -# lx25/arch/cris/arch-v32/boot/compressed/Makefile
5902 +# arch/cris/arch-v32/boot/compressed/Makefile
5903  #
5904 -# create a compressed vmlinux image from the original vmlinux files and romfs
5905 -#
5906 -
5907 -target = $(target_compressed_dir)
5908 -src    = $(src_compressed_dir)
5909  
5910  CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include
5911  CFLAGS = -O2
5912  LD = gcc-cris -mlinux -march=v32 -nostdlib
5913 +LDFLAGS = -T $(obj)/decompress.ld
5914 +obj-y = head.o misc.o
5915 +OBJECTS = $(obj)/head.o $(obj)/misc.o
5916  OBJCOPY = objcopy-cris
5917  OBJCOPYFLAGS = -O binary --remove-section=.bss
5918 -OBJECTS = $(target)/head.o $(target)/misc.o
5919 -
5920 -# files to compress
5921 -SYSTEM = $(objtree)/vmlinux.bin
5922 -
5923 -all: vmlinuz
5924 -
5925 -$(target)/decompress.bin: $(OBJECTS)
5926 -       $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
5927 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
5928  
5929 -$(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
5930 -       cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz
5931 -       rm -f piggy.img
5932 -       cp $(objtree)/vmlinuz $(src)
5933 +quiet_cmd_image = BUILD   $@
5934 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
5935  
5936 -$(target)/head.o: $(src)/head.S
5937 -       $(CC) -D__ASSEMBLY__ -c $< -o $@
5938 +targets := vmlinux piggy.gz decompress.o decompress.bin
5939  
5940 -# gzip the kernel image
5941 +$(obj)/decompress.o: $(OBJECTS) FORCE
5942 +       $(call if_changed,ld)
5943  
5944 -piggy.img: $(SYSTEM)
5945 -       cat $(SYSTEM) | gzip -f -9 > piggy.img
5946 +$(obj)/decompress.bin: $(obj)/decompress.o FORCE
5947 +       $(call if_changed,objcopy)
5948  
5949 -clean:
5950 -       rm -f piggy.img $(objtree)/vmlinuz vmlinuz.o decompress.o decompress.bin $(OBJECTS)
5951 +$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
5952 +       $(call if_changed,image)
5953  
5954 +$(obj)/piggy.gz: $(obj)/../Image FORCE
5955 +       $(call if_changed,gzip)
5956 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/README linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/README
5957 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/README        2007-01-10 20:10:37.000000000 +0100
5958 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/README        2003-08-21 11:37:03.000000000 +0200
5959 @@ -5,14 +5,14 @@
5960  This can be slightly confusing because it's a process with many steps.
5961  
5962  The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
5963 -by that makefile into text and data binary files, vmlinux.text and
5964 +by that makefile into text and data binary files, vmlinux.text and 
5965  vmlinux.data.
5966  
5967  Those files together with a ROM filesystem can be catted together and
5968  burned into a flash or executed directly at the DRAM origin.
5969  
5970  They can also be catted together and compressed with gzip, which is what
5971 -happens in this makefile. Together they make up piggy.img.
5972 +happens in this makefile. Together they make up piggy.img. 
5973  
5974  The decompressor is built into the file decompress.o. It is turned into
5975  the binary file decompress.bin, which is catted together with piggy.img
5976 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/decompress.ld linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/decompress.ld
5977 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/decompress.ld 2007-01-10 20:10:37.000000000 +0100
5978 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/decompress.ld 2003-08-21 11:57:56.000000000 +0200
5979 @@ -1,7 +1,7 @@
5980  /*#OUTPUT_FORMAT(elf32-us-cris) */
5981  OUTPUT_ARCH (crisv32)
5982  
5983 -MEMORY
5984 +MEMORY 
5985         {
5986         dram : ORIGIN = 0x40700000,
5987                LENGTH = 0x00100000
5988 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/head.S
5989 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/head.S        2007-01-10 20:10:37.000000000 +0100
5990 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/head.S        2007-01-09 10:29:20.000000000 +0100
5991 @@ -2,19 +2,19 @@
5992   *  Code that sets up the DRAM registers, calls the
5993   *  decompressor to unpack the piggybacked kernel, and jumps.
5994   *
5995 - *  Copyright (C) 1999 - 2003, Axis Communications AB
5996 + *  Copyright (C) 1999 - 2006, Axis Communications AB
5997   */
5998  
5999  #define ASSEMBLER_MACROS_ONLY
6000  #include <asm/arch/hwregs/asm/reg_map_asm.h>
6001  #include <asm/arch/hwregs/asm/gio_defs_asm.h>
6002  #include <asm/arch/hwregs/asm/config_defs_asm.h>
6003 -
6004 +       
6005  #define RAM_INIT_MAGIC 0x56902387
6006  #define COMMAND_LINE_MAGIC 0x87109563
6007  
6008         ;; Exported symbols
6009 -
6010 +       
6011         .globl  input_data
6012  
6013         .text
6014 @@ -29,53 +29,16 @@
6015                REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
6016         move.d $r0, [$r1]
6017  
6018 -       ;; If booting from NAND flash we first have to copy some
6019 -       ;; data from NAND flash to internal RAM to get the code
6020 -       ;; that initializes the SDRAM. Lets copy 20 KB. This
6021 -       ;; code executes at 0x38010000 if booting from NAND and
6022 -       ;; we are guaranted that at least 0x200 bytes are good so
6023 -       ;; lets start from there. The first 8192 bytes in the nand
6024 -       ;; flash is spliced with zeroes and is thus 16384 bytes.
6025 -       move.d 0x38010200, $r10
6026 -       move.d 0x14200, $r11    ; Start offset in NAND flash 0x10200 + 16384
6027 -       move.d 0x5000, $r12     ; Length of copy
6028 -
6029 -       ;; Before this code the tools add a partitiontable so the PC
6030 -       ;; has an offset from the linked address.
6031 -offset1:
6032 -       lapcq  ., $r13          ; get PC
6033 -       add.d   first_copy_complete-offset1, $r13
6034 -
6035 -#include "../../lib/nand_init.S"
6036 -
6037 -first_copy_complete:
6038 -       ;; Initialze the DRAM registers.
6039 +       ;; Initialize the DRAM registers.
6040         cmp.d   RAM_INIT_MAGIC, $r8     ; Already initialized?
6041         beq     dram_init_finished
6042         nop
6043  
6044  #include "../../lib/dram_init.S"
6045 -
6046 +       
6047  dram_init_finished:
6048 -       lapcq  ., $r13          ; get PC
6049 -       add.d   second_copy_complete-dram_init_finished, $r13
6050 -
6051 -       move.d REG_ADDR(config, regi_config, r_bootsel), $r0
6052 -       move.d [$r0], $r0
6053 -       and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
6054 -       cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
6055 -       bne second_copy_complete ; No NAND boot
6056 -       nop
6057 -
6058 -       ;; Copy 2MB from NAND flash to SDRAM (at 2-4MB into the SDRAM)
6059 -       move.d 0x40204000, $r10
6060 -       move.d 0x8000, $r11
6061 -       move.d 0x200000, $r12
6062 -       ba copy_nand_to_ram
6063 -       nop
6064 -second_copy_complete:
6065 -
6066 -       ;; Initiate the PA port.
6067 +       
6068 +       ;; Initiate the GIO ports.
6069         move.d  CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
6070         move.d  REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
6071         move.d  $r0, [$r1]
6072 @@ -84,57 +47,74 @@
6073         move.d  REG_ADDR(gio, regi_gio, rw_pa_oe), $r1
6074         move.d  $r0, [$r1]
6075  
6076 +       move.d  CONFIG_ETRAX_DEF_GIO_PB_OUT, $r0
6077 +       move.d  REG_ADDR(gio, regi_gio, rw_pb_dout), $r1
6078 +       move.d  $r0, [$r1]
6079 +
6080 +       move.d  CONFIG_ETRAX_DEF_GIO_PB_OE, $r0
6081 +       move.d  REG_ADDR(gio, regi_gio, rw_pb_oe), $r1
6082 +       move.d  $r0, [$r1]
6083 +
6084 +       move.d  CONFIG_ETRAX_DEF_GIO_PC_OUT, $r0
6085 +       move.d  REG_ADDR(gio, regi_gio, rw_pc_dout), $r1
6086 +       move.d  $r0, [$r1]
6087 +
6088 +       move.d  CONFIG_ETRAX_DEF_GIO_PC_OE, $r0
6089 +       move.d  REG_ADDR(gio, regi_gio, rw_pc_oe), $r1
6090 +       move.d  $r0, [$r1]
6091 +
6092 +       move.d  CONFIG_ETRAX_DEF_GIO_PD_OUT, $r0
6093 +       move.d  REG_ADDR(gio, regi_gio, rw_pd_dout), $r1
6094 +       move.d  $r0, [$r1]
6095 +
6096 +       move.d  CONFIG_ETRAX_DEF_GIO_PD_OE, $r0
6097 +       move.d  REG_ADDR(gio, regi_gio, rw_pd_oe), $r1
6098 +       move.d  $r0, [$r1]
6099 +
6100 +       move.d  CONFIG_ETRAX_DEF_GIO_PE_OUT, $r0
6101 +       move.d  REG_ADDR(gio, regi_gio, rw_pe_dout), $r1
6102 +       move.d  $r0, [$r1]
6103 +
6104 +       move.d  CONFIG_ETRAX_DEF_GIO_PE_OE, $r0
6105 +       move.d  REG_ADDR(gio, regi_gio, rw_pe_oe), $r1
6106 +       move.d  $r0, [$r1]
6107 +
6108         ;; Setup the stack to a suitably high address.
6109 -       ;; We assume 8 MB is the minimum DRAM and put
6110 +       ;; We assume 8 MB is the minimum DRAM and put 
6111         ;; the SP at the top for now.
6112  
6113         move.d  0x40800000, $sp
6114  
6115 -       ;; Figure out where the compressed piggyback image is
6116 -       ;; in the flash (since we wont try to copy it to DRAM
6117 -       ;; before unpacking). It is at _edata, but in flash.
6118 +       ;; Figure out where the compressed piggyback image is.
6119 +       ;; It is either in [NOR] flash (we don't want to copy it 
6120 +       ;; to DRAM before unpacking), or copied to DRAM
6121 +       ;; by the [NAND] flash boot loader.
6122 +       ;; The piggyback image is at _edata, but relative to where the
6123 +       ;; image is actually located in memory, not where it is linked 
6124 +       ;; (the decompressor is linked at 0x40700000+ and runs there).
6125         ;; Use (_edata - herami) as offset to the current PC.
6126  
6127 -       move.d REG_ADDR(config, regi_config, r_bootsel), $r0
6128 -       move.d [$r0], $r0
6129 -       and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
6130 -       cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
6131 -       beq hereami2
6132 -       nop
6133 -hereami:
6134 +hereami:       
6135         lapcq   ., $r5          ; get PC
6136         and.d   0x7fffffff, $r5 ; strip any non-cache bit
6137 -       move.d  $r5, $r0        ; save for later - flash address of 'herami'
6138 +       move.d  $r5, $r0        ; source address of 'herami'
6139         add.d   _edata, $r5
6140         sub.d   hereami, $r5    ; r5 = flash address of '_edata'
6141         move.d  hereami, $r1    ; destination
6142 -       ba 2f
6143 -       nop
6144 -hereami2:
6145 -       lapcq   ., $r5          ; get PC
6146 -       and.d   0x00ffffff, $r5 ; strip any non-cache bit
6147 -       move.d  $r5, $r6
6148 -       or.d    0x40200000, $r6
6149 -       move.d  $r6, $r0        ; save for later - flash address of 'herami'
6150 -       add.d   _edata, $r5
6151 -       sub.d   hereami2, $r5   ; r5 = flash address of '_edata'
6152 -       add.d   0x40200000, $r5
6153 -       move.d  hereami2, $r1   ; destination
6154 -2:
6155 -       ;; Copy text+data to DRAM
6156  
6157 +       ;; Copy text+data to DRAM
6158 +       
6159         move.d  _edata, $r2     ; end destination
6160 -1:     move.w  [$r0+], $r3
6161 -       move.w  $r3, [$r1+]
6162 -       cmp.d   $r2, $r1
6163 +1:     move.w  [$r0+], $r3     ; from herami+ source
6164 +       move.w  $r3, [$r1+]     ; to hereami+ destination (linked address)
6165 +       cmp.d   $r2, $r1        ; finish when destination == _edata
6166         bcs     1b
6167         nop
6168 -
6169 -       move.d  input_data, $r0 ; for the decompressor
6170 +       move.d  input_data, $r0 ; for the decompressor  
6171         move.d  $r5, [$r0]      ; for the decompressor
6172  
6173         ;; Clear the decompressors BSS (between _edata and _end)
6174 -
6175 +       
6176         moveq   0, $r0
6177         move.d  _edata, $r1
6178         move.d  _end, $r2
6179 @@ -144,40 +124,47 @@
6180         nop
6181  
6182         ;;  Save command line magic and address.
6183 -       move.d  _cmd_line_magic, $r12
6184 -       move.d  $r10, [$r12]
6185 -       move.d  _cmd_line_addr, $r12
6186 -       move.d  $r11, [$r12]
6187 -
6188 +       move.d  _cmd_line_magic, $r0
6189 +       move.d  $r10, [$r0]
6190 +       move.d  _cmd_line_addr, $r0
6191 +       move.d  $r11, [$r0]
6192 +
6193 +       ;;  Save boot source indicator
6194 +       move.d  _boot_source, $r0
6195 +       move.d  $r12, [$r0]
6196 +       
6197         ;; Do the decompression and save compressed size in _inptr
6198  
6199         jsr     decompress_kernel
6200         nop
6201  
6202 +       ;; Restore boot source indicator
6203 +       move.d  _boot_source, $r12
6204 +       move.d  [$r12], $r12
6205 +
6206         ;; Restore command line magic and address.
6207         move.d  _cmd_line_magic, $r10
6208         move.d  [$r10], $r10
6209         move.d  _cmd_line_addr, $r11
6210         move.d  [$r11], $r11
6211 -
6212 +       
6213         ;; Put start address of root partition in r9 so the kernel can use it
6214         ;; when mounting from flash
6215         move.d  input_data, $r0
6216         move.d  [$r0], $r9              ; flash address of compressed kernel
6217         move.d  inptr, $r0
6218         add.d   [$r0], $r9              ; size of compressed kernel
6219 -       cmp.d   0x40200000, $r9
6220 -       blo     enter_kernel
6221 -       nop
6222 -       sub.d   0x40200000, $r9
6223 -       add.d   0x4000, $r9
6224 -
6225 -enter_kernel:
6226 +       cmp.d   0x40000000, $r9         ; image in DRAM ?
6227 +       blo     enter_kernel            ; no, must be [NOR] flash, jump
6228 +       nop                             ; delay slot
6229 +       and.d   0x001fffff, $r9         ; assume compressed kernel was < 2M
6230 +               
6231 +enter_kernel:          
6232         ;; Enter the decompressed kernel
6233         move.d  RAM_INIT_MAGIC, $r8     ; Tell kernel that DRAM is initialized
6234         jump    0x40004000      ; kernel is linked to this address
6235         nop
6236 -
6237 +       
6238         .data
6239  
6240  input_data:
6241 @@ -185,8 +172,8 @@
6242  _cmd_line_magic:
6243         .dword 0
6244  _cmd_line_addr:
6245 +       .dword 0        
6246 +_boot_source:
6247         .dword 0
6248 -is_nand_boot:
6249 -       .dword  0
6250 -
6251 +       
6252  #include "../../lib/hw_settings.S"
6253 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/misc.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/misc.c
6254 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/misc.c        2007-01-10 20:10:37.000000000 +0100
6255 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/misc.c        2006-11-03 11:35:51.000000000 +0100
6256 @@ -1,15 +1,15 @@
6257  /*
6258   * misc.c
6259   *
6260 - * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $
6261 - *
6262 - * This is a collection of several routines from gzip-1.0.3
6263 + * $Id: misc.c,v 1.12 2006/11/03 10:35:51 pkj Exp $
6264 + * 
6265 + * This is a collection of several routines from gzip-1.0.3 
6266   * adapted for Linux.
6267   *
6268   * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
6269   * puts by Nick Holloway 1993, better puts by Martin Mares 1995
6270   * adoptation for Linux/CRIS Axis Communications AB, 1999
6271 - *
6272 + * 
6273   */
6274  
6275  /* where the piggybacked kernel image expects itself to live.
6276 @@ -20,11 +20,11 @@
6277  
6278  #define KERNEL_LOAD_ADR 0x40004000
6279  
6280 -
6281  #include <linux/types.h>
6282  #include <asm/arch/hwregs/reg_rdwr.h>
6283  #include <asm/arch/hwregs/reg_map.h>
6284  #include <asm/arch/hwregs/ser_defs.h>
6285 +#include <asm/arch/hwregs/pinmux_defs.h>
6286  
6287  /*
6288   * gzip declarations
6289 @@ -66,8 +66,8 @@
6290  #define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
6291  #define RESERVED     0xC0 /* bit 6,7:   reserved */
6292  
6293 -#define get_byte() inbuf[inptr++]
6294 -
6295 +#define get_byte() inbuf[inptr++]      
6296 +       
6297  /* Diagnostic functions */
6298  #ifdef DEBUG
6299  #  define Assert(cond,msg) {if(!(cond)) error(msg);}
6300 @@ -96,20 +96,20 @@
6301  static long bytes_out = 0;
6302  static uch *output_data;
6303  static unsigned long output_ptr = 0;
6304 -
6305
6306  static void *malloc(int size);
6307  static void free(void *where);
6308  static void error(char *m);
6309  static void gzip_mark(void **);
6310  static void gzip_release(void **);
6311 -
6312
6313  static void puts(const char *);
6314  
6315  /* the "heap" is put directly after the BSS ends, at end */
6316 -
6317 +  
6318  extern int _end;
6319  static long free_mem_ptr = (long)&_end;
6320 -
6321
6322  #include "../../../../../lib/inflate.c"
6323  
6324  static void *malloc(int size)
6325 @@ -152,7 +152,7 @@
6326                 rs = REG_RD(ser, regi_ser, rs_stat_din);
6327         }
6328         while (!rs.tr_rdy);/* Wait for tranceiver. */
6329 -
6330 +       
6331         REG_WR(ser, regi_ser, rw_dout, dout);
6332  }
6333  
6334 @@ -209,9 +209,9 @@
6335      ulg c = crc;         /* temporary variable */
6336      unsigned n;
6337      uch *in, *out, ch;
6338 -
6339 +    
6340      in = window;
6341 -    out = &output_data[output_ptr];
6342 +    out = &output_data[output_ptr]; 
6343      for (n = 0; n < outcnt; n++) {
6344             ch = *out++ = *in++;
6345             c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
6346 @@ -225,9 +225,9 @@
6347  static void
6348  error(char *x)
6349  {
6350 -       puts("\n\n");
6351 +       puts("\r\n\n");
6352         puts(x);
6353 -       puts("\n\n -- System halted\n");
6354 +       puts("\r\n\n -- System halted\n");
6355  
6356         while(1);       /* Halt */
6357  }
6358 @@ -246,13 +246,13 @@
6359         reg_ser_rw_rec_ctrl rec_ctrl;
6360         reg_ser_rw_tr_baud_div tr_baud;
6361         reg_ser_rw_rec_baud_div rec_baud;
6362 -
6363 +       
6364         /* Turn off XOFF. */
6365         xoff = REG_RD(ser, regi_ser, rw_xoff);
6366 -
6367 +       
6368         xoff.chr = 0;
6369         xoff.automatic = regk_ser_no;
6370 -
6371 +       
6372         REG_WR(ser, regi_ser, rw_xoff, xoff);
6373  
6374         /* Set baudrate and stopbits. */
6375 @@ -260,19 +260,21 @@
6376         rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
6377         tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
6378         rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
6379 -
6380 +       
6381         tr_ctrl.stop_bits = 1;  /* 2 stop bits. */
6382 -
6383 -       /*
6384 -        * The baudrate setup is a bit fishy, but in the end the tranceiver is
6385 -        * set to 4800 and the receiver to 115200. The magic value is
6386 -        * 29.493 MHz.
6387 +       tr_ctrl.en = 1; /* enable transmitter */
6388 +       rec_ctrl.en = 1; /* enabler receiver */
6389 +       
6390 +       /* 
6391 +        * The baudrate setup used to be a bit fishy, but now transmitter and
6392 +        * receiver are both set to the intended baud rate, 115200.
6393 +        * The magic value is 29.493 MHz.
6394          */
6395         tr_ctrl.base_freq = regk_ser_f29_493;
6396         rec_ctrl.base_freq = regk_ser_f29_493;
6397 -       tr_baud.div = (29493000 / 8) / 4800;
6398 +       tr_baud.div = (29493000 / 8) / 115200;
6399         rec_baud.div = (29493000 / 8) / 115200;
6400 -
6401 +       
6402         REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
6403         REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
6404         REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
6405 @@ -283,22 +285,28 @@
6406  decompress_kernel()
6407  {
6408         char revision;
6409 -
6410 +       reg_pinmux_rw_hwprot hwprot;
6411 +       
6412         /* input_data is set in head.S */
6413         inbuf = input_data;
6414 -
6415 +       
6416 +       hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
6417  #ifdef CONFIG_ETRAX_DEBUG_PORT0
6418         serial_setup(regi_ser0);
6419  #endif
6420  #ifdef CONFIG_ETRAX_DEBUG_PORT1
6421 +       hwprot.ser1 = regk_pinmux_yes;
6422         serial_setup(regi_ser1);
6423  #endif
6424  #ifdef CONFIG_ETRAX_DEBUG_PORT2
6425 +       hwprot.ser2 = regk_pinmux_yes;
6426         serial_setup(regi_ser2);
6427  #endif
6428  #ifdef CONFIG_ETRAX_DEBUG_PORT3
6429 +       hwprot.ser3 = regk_pinmux_yes;
6430         serial_setup(regi_ser3);
6431  #endif
6432 +       REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
6433  
6434         setup_normal_output_buffer();
6435  
6436 @@ -307,11 +315,11 @@
6437         __asm__ volatile ("move $vr,%0" : "=rm" (revision));
6438         if (revision < 32)
6439         {
6440 -               puts("You need an ETRAX FS to run Linux 2.6/crisv32.\n");
6441 +               puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
6442                 while(1);
6443         }
6444  
6445 -       puts("Uncompressing Linux...\n");
6446 +       puts("Uncompressing Linux...\r\n");
6447         gunzip();
6448 -       puts("Done. Now booting the kernel.\n");
6449 +       puts("Done. Now booting the kernel.\r\n");
6450  }
6451 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/Makefile
6452 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/Makefile  2007-01-10 20:10:37.000000000 +0100
6453 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/Makefile  2007-01-17 14:24:50.000000000 +0100
6454 @@ -1,36 +1,29 @@
6455  #
6456 -# Makefile for rescue code
6457 +# Makefile for rescue (bootstrap) code
6458  #
6459 -target = $(target_rescue_dir)
6460 -src    = $(src_rescue_dir)
6461  
6462  CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
6463  CFLAGS = -O2
6464 -LD = gcc-cris -mlinux -march=v32 -nostdlib
6465 +LD = gcc-cris -mlinux -march=v32 -nostdlib 
6466 +LDFLAGS = -T $(obj)/rescue.ld
6467 +LDPOSTFLAGS = -lgcc
6468  OBJCOPY = objcopy-cris
6469  OBJCOPYFLAGS = -O binary --remove-section=.bss
6470 -
6471 -all: $(target)/rescue.bin
6472 -
6473 -rescue: rescue.bin
6474 -       # do nothing
6475 -
6476 -$(target)/rescue.bin: $(target) $(target)/head.o
6477 -       $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
6478 -       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
6479 -       cp -p $(target)/rescue.bin $(objtree)
6480 -
6481 -$(target):
6482 -       mkdir -p $(target)
6483 -
6484 -$(target)/head.o: $(src)/head.S
6485 -       $(CC) -D__ASSEMBLY__ -c $< -o $*.o
6486 -
6487 -clean:
6488 -       rm -f $(target)/*.o $(target)/*.bin
6489 -
6490 -fastdep:
6491 -
6492 -modules:
6493 -
6494 -modules-install:
6495 +obj-y = head.o bootload.o crisv32_nand.o nand_base.o nand_ids.o nand_ecc.o \
6496 +        lib.o
6497 +OBJECTS = $(obj)/head.o $(obj)/bootload.o \
6498 +         $(obj)/crisv32_nand.o $(obj)/nand_base.o \
6499 +          $(obj)/nand_ids.o $(obj)/nand_ecc.o \
6500 +         $(obj)/lib.o $(obj)/../../lib/lib.a
6501 +
6502 +targets := rescue.o rescue.bin
6503 +
6504 +quiet_cmd_ldlibgcc = LD      $@
6505 +cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
6506 +
6507 +$(obj)/rescue.o: $(OBJECTS) FORCE
6508 +       $(call if_changed,ldlibgcc)
6509 +
6510 +$(obj)/rescue.bin: $(obj)/rescue.o FORCE
6511 +       $(call if_changed,objcopy)
6512 +       cp -p $(obj)/rescue.bin $(objtree)
6513 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/bootload.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/bootload.c
6514 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/bootload.c        1970-01-01 01:00:00.000000000 +0100
6515 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/bootload.c        2006-11-28 11:05:39.000000000 +0100
6516 @@ -0,0 +1,277 @@
6517 +/*
6518 + * bootload.c
6519 + * Simple boot loader for NAND chips on Etrax FS
6520 + *
6521 + * $Id: bootload.c,v 1.8 2006/11/28 10:05:39 ricardw Exp $
6522 + * 
6523 + */
6524 +
6525 +#include <linux/types.h>
6526 +#include <linux/delay.h>
6527 +
6528 +#include "mtd.h"
6529 +#include "nand.h"
6530 +
6531 +#include <asm/arch/hwregs/reg_rdwr.h>
6532 +#include <asm/arch/hwregs/reg_map.h>
6533 +#include <asm/arch/hwregs/pinmux_defs.h>
6534 +
6535 +#include "lib.h"
6536 +
6537 +#define BOOT_ADDR  (CONFIG_ETRAX_PTABLE_SECTOR + 0x40200000)
6538 +
6539 +/* bits for nand_rw() `cmd'; or together as needed */
6540 +
6541 +#define NANDRW_READ            0x01
6542 +#define NANDRW_WRITE           0x00
6543 +#define NANDRW_JFFS2           0x02
6544 +#define NANDRW_JFFS2_SKIP      0x04
6545 +
6546 +#define ROUND_DOWN(value, boundary)      ((value) & (~((boundary)-1)))
6547 +
6548 +/* set $r8 to RAM_INIT_MAGIC, $r12 to NAND_BOOT_MAGIC then jump */
6549 +#define BOOT(addr)  __asm__ volatile (" \
6550 +       move.d 0x56902387, $r8\n\
6551 +       move.d 0x9A9DB001, $r12\n\
6552 +       jump %0\n\
6553 +       nop\n\
6554 +       " : : "r" (addr))
6555 +
6556 +#define D(x) 
6557 +
6558 +extern struct mtd_info *crisv32_nand_flash_probe(void);
6559 +
6560 +extern int _end, _bss, _edata;
6561 +
6562 +/* 
6563 + * NAND read/write from U-Boot 1.4.4
6564 + * Modified for newer mtd and use of mtd interface instead of nand directly.
6565 + *
6566 + * cmd: 0: NANDRW_WRITE                        write, fail on bad block
6567 + *     1: NANDRW_READ                  read, fail on bad block
6568 + *     2: NANDRW_WRITE | NANDRW_JFFS2  write, skip bad blocks
6569 + *     3: NANDRW_READ | NANDRW_JFFS2   read, data all 0xff for bad blocks
6570 + *      7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
6571 + */
6572 +static int
6573 +nand_rw (struct mtd_info* mtd, int cmd,
6574 +        size_t start, size_t len,
6575 +        size_t *retlen, u_char * buf)
6576 +{
6577 +       int ret = 0, n, total = 0;
6578 +
6579 +       /* eblk (once set) is the start of the erase block containing the
6580 +        * data being processed.
6581 +        */
6582 +       size_t eblk = ~0;       /* force mismatch on first pass */
6583 +       size_t erasesize = mtd->erasesize;
6584 +
6585 +       while (len) {
6586 +               if ((start & (-erasesize)) != eblk) {
6587 +                       /* have crossed into new erase block, deal with
6588 +                        * it if it is marked bad.
6589 +                        */
6590 +                       eblk = start & (-erasesize); /* start of block */
6591 +                       D(
6592 +                         puts("New block ");
6593 +                         putx(eblk);
6594 +                         putnl();
6595 +                        )
6596 +                       if (mtd->block_isbad(mtd, eblk)) {
6597 +                               if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
6598 +                                       while (len > 0 &&
6599 +                                              start - eblk < erasesize) {
6600 +                                               *(buf++) = 0xff;
6601 +                                               ++start;
6602 +                                               ++total;
6603 +                                               --len;
6604 +                                       }
6605 +                                       continue;
6606 +                               } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
6607 +                                       start += erasesize;
6608 +                                       continue;
6609 +                               } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
6610 +                                       /* skip bad block */
6611 +                                       start += erasesize;
6612 +                                       continue;
6613 +                               } else {
6614 +                                       ret = 1;
6615 +                                       break;
6616 +                               }
6617 +                       }
6618 +               }
6619 +               /* The ECC will not be calculated correctly if
6620 +                  less than 512 is written or read */
6621 +               /* Is request at least 512 bytes AND it starts on a proper boundry */
6622 +               if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
6623 +                       puts("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\r\n");
6624 +
6625 +#if 0
6626 +               buf = (void *) 0x38008000; /* to fixed address, for testing */
6627 +#endif
6628 +
6629 +               if (cmd & NANDRW_READ) {
6630 +                       ret = mtd->read_ecc(mtd, start, 
6631 +                                           min(len, eblk + erasesize - start),
6632 +                                           (size_t *)&n, (u_char*)buf, 
6633 +                                           NULL, NULL);
6634 +               } else {
6635 +                       ret = mtd->write_ecc(mtd, start,
6636 +                                            min(len, eblk + erasesize - start),
6637 +                                            (size_t *)&n, (u_char*)buf, 
6638 +                                            NULL, NULL);
6639 +               }
6640 +
6641 +               if (ret) {
6642 +                       break;
6643 +               }
6644 +
6645 +               start  += n;
6646 +               buf   += n;
6647 +               total += n;
6648 +               len   -= n;
6649 +       }
6650 +       if (retlen)
6651 +               *retlen = total;
6652 +
6653 +       return ret;
6654 +}
6655 +
6656 +
6657 +void
6658 +bootload()
6659 +{
6660 +       char revision;
6661 +       struct mtd_info *mtd;
6662 +
6663 +       serial_init();
6664 +
6665 +       __asm__ volatile ("move $vr,%0" : "=rm" (revision));
6666 +       if (revision < 32)
6667 +       {
6668 +               puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
6669 +               while(1);
6670 +       }
6671 +
6672 +       puts("\r\n\nETRAX FS NAND boot loader\r\n");
6673 +       puts("=========================\r\n");
6674 +       puts("Rev 1, " __DATE__ " " __TIME__ "\r\n");
6675 +
6676 +       puts("CPU revision: ");
6677 +       putx(revision);
6678 +       putnl();
6679 +
6680 +       puts("Bootloader main at ") ;
6681 +       putx((int) bootload);
6682 +       putnl();
6683 +
6684 +       puts("Data end: ");
6685 +       putx((long) &_edata);
6686 +       putnl();
6687 +
6688 +       puts("Bss: ");
6689 +       putx((long) &_bss);
6690 +       putnl();
6691 +
6692 +       puts("Heap: ");
6693 +       putx((long) &_end);
6694 +       putnl();
6695 +
6696 +#if 0 /* loop calibration */
6697 +       volatile int i;
6698 +       puts ("10000 loops...");
6699 +       for (i = 0; i < 10000; i++)
6700 +               udelay(1000);
6701 +       puts("done\r\n");
6702 +#endif
6703 +
6704 +       puts("Identifying nand chip...\r\n");
6705 +       mtd = crisv32_nand_flash_probe();
6706 +       puts("Done.\r\n");
6707 +       
6708 +       if (mtd) {
6709 +               puts("Chip identified. ");
6710 +#if 0 /* print chip parameters */
6711 +               if (mtd->name)
6712 +                       puts(mtd->name);
6713 +
6714 +               puts("\r\ntype: ");
6715 +               putx(mtd->type);
6716 +               puts("\r\nflags: ");
6717 +               putx(mtd->flags);
6718 +               puts("\r\nsize: ");
6719 +               putx(mtd->size);
6720 +               puts("\r\nerasesize: ");
6721 +               putx(mtd->erasesize);
6722 +               puts("\r\noobblock: ");
6723 +               putx(mtd->oobblock);
6724 +               puts("\r\noobsize: ");
6725 +               putx(mtd->oobsize);
6726 +               puts("\r\necctype: ");
6727 +               putx(mtd->ecctype);
6728 +               puts("\r\neccsize: ");
6729 +               putx(mtd->eccsize);
6730 +#endif
6731 +               putnl();
6732 +
6733 +               puts("Bad blocks:\r\n");
6734 +
6735 +               int i;
6736 +               for (i = 0; i < mtd->size; i += mtd->erasesize) {
6737 +                       if (mtd->block_isbad(mtd, i)) {
6738 +                               putx(i);
6739 +                               putnl();
6740 +                       }
6741 +               }
6742 +
6743 +#if 0 /* print oob parameters */
6744 +               puts("Oob info:\r\n");
6745 +               puts("useecc: ");
6746 +               putx(mtd->oobinfo.useecc);
6747 +               puts("\r\neccbytes: ");
6748 +               putx(mtd->oobinfo.eccbytes);
6749 +               puts("\r\neccpos: ");
6750 +               for (i = 0; i < mtd->oobinfo.eccbytes; i++) {
6751 +                       putx(mtd->oobinfo.eccpos[i]);
6752 +                       putc(' ');
6753 +               }
6754 +               putnl();
6755 +#endif
6756 +
6757 +               puts("Bootload in progress...");
6758 +               int res, copied;
6759 +               res = nand_rw(mtd, 
6760 +                             NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, 
6761 +                             CONFIG_ETRAX_PTABLE_SECTOR, 
6762 +                             0x200000, /* 2 megs */
6763 +                             &copied, 
6764 +                             (void *) BOOT_ADDR);
6765 +
6766 +               puts("complete, status ");
6767 +               putx(res);
6768 +               puts(", loaded ");
6769 +               putx(copied);
6770 +               puts(" bytes\r\n");
6771 +#if 1
6772 +               puts("Data in DRAM:\r\n");
6773 +               putx(* (int *) (BOOT_ADDR + 0));
6774 +               putc(' ');
6775 +               putx(* (int *) (BOOT_ADDR + 4));
6776 +               putc(' ');
6777 +               putx(* (int *) (BOOT_ADDR + 8));
6778 +               putnl();
6779 +#endif
6780 +
6781 +               if (res) 
6782 +                       error("Corrupt data in NAND flash.");
6783 +               else
6784 +               {
6785 +                       puts("Booting...\r\n");
6786 +                       BOOT(BOOT_ADDR);
6787 +               }
6788 +       } else
6789 +               error("No NAND flash chip found to boot from.");
6790 +
6791 +       while (1)
6792 +               ; /* hang around until hell freezes over */
6793 +}
6794 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/crisv32_nand.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/crisv32_nand.c
6795 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/crisv32_nand.c    1970-01-01 01:00:00.000000000 +0100
6796 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/crisv32_nand.c    2006-11-21 15:40:02.000000000 +0100
6797 @@ -0,0 +1,157 @@
6798 +/*
6799 + * Taken from arch/cris/arch-v32/drivers/nandflash.c
6800 + * and modified to use for boot loader.
6801 + *
6802 + *  Copyright (c) 2004
6803 + *
6804 + *  Derived from drivers/mtd/nand/spia.c
6805 + *       Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
6806 + * 
6807 + * $Id: crisv32_nand.c,v 1.2 2006/11/21 14:40:02 ricardw Exp $
6808 + *
6809 + * This program is free software; you can redistribute it and/or modify
6810 + * it under the terms of the GNU General Public License version 2 as
6811 + * published by the Free Software Foundation.
6812 + *
6813 + */
6814 +
6815 +#include "mtd.h"
6816 +#include "nand.h"
6817 +
6818 +#if 0
6819 +#include <linux/mtd/partitions.h>
6820 +#endif
6821 +
6822 +#if 0
6823 +#include <asm/arch/memmap.h>
6824 +#endif
6825 +
6826 +#include <asm/arch/hwregs/reg_map.h>
6827 +#include <asm/arch/hwregs/reg_rdwr.h>
6828 +#include <asm/arch/hwregs/gio_defs.h>
6829 +#include <asm/arch/hwregs/bif_core_defs.h>
6830 +
6831 +#include "lib.h"
6832 +
6833 +/* Hardware */
6834 +
6835 +#define CE_BIT 4
6836 +#define CLE_BIT 5
6837 +#define ALE_BIT 6
6838 +#define BY_BIT 7
6839 +
6840 +#define NAND_RD_ADDR 0x90000000 /* read address */
6841 +#define NAND_WR_ADDR 0x94000000 /* write address */
6842 +
6843 +static struct mtd_info *crisv32_mtd = NULL;
6844 +
6845 +/* 
6846 + *     hardware specific access to control-lines
6847 + */
6848 +static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
6849 +{
6850 +       unsigned long flags;
6851 +       reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
6852 +
6853 +       switch(cmd){
6854 +               case NAND_CTL_SETCLE: 
6855 +                    dout.data |= (1<<CLE_BIT);
6856 +                    break;
6857 +               case NAND_CTL_CLRCLE: 
6858 +                    dout.data &= ~(1<<CLE_BIT);
6859 +                    break;
6860 +               case NAND_CTL_SETALE:
6861 +                    dout.data |= (1<<ALE_BIT);
6862 +                    break;
6863 +               case NAND_CTL_CLRALE: 
6864 +                    dout.data &= ~(1<<ALE_BIT);
6865 +                    break;
6866 +               case NAND_CTL_SETNCE:
6867 +                    dout.data &= ~(1<<CE_BIT);
6868 +                    break;
6869 +               case NAND_CTL_CLRNCE:
6870 +                    dout.data |= (1<<CE_BIT);
6871 +                    break;
6872 +       }
6873 +       REG_WR(gio, regi_gio, rw_pa_dout, dout);
6874 +#if 0 
6875 +       /* read from gpio reg to flush pipeline.
6876 +        * doesn't seem to be necessary.
6877 +        */
6878 +       (void) REG_RD(gio, regi_gio, rw_pa_dout); /* gpio sync */
6879 +#endif
6880 +}
6881 +
6882 +/*
6883 + *     read device ready pin
6884 + */
6885 +int crisv32_device_ready(struct mtd_info *mtd)
6886 +{
6887 +       reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din);
6888 +       return ((din.data & (1 << BY_BIT)) >> BY_BIT);
6889 +}
6890 +
6891 +/*
6892 + * Main initialization routine
6893 + */
6894 +struct mtd_info* crisv32_nand_flash_probe (void)
6895 +{
6896 +       reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
6897 +       reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe);
6898 +       struct nand_chip *this;
6899 +       int err = 0;
6900 +
6901 +       /* Allocate memory for MTD device structure and private data */
6902 +       crisv32_mtd = malloc (sizeof(struct mtd_info) + sizeof (struct nand_chip));
6903 +       if (!crisv32_mtd) {
6904 +               puts ("Unable to allocate CRISv32 NAND MTD device structure.\r\n");
6905 +               err = -ENOMEM;
6906 +               return NULL;
6907 +       }
6908 +
6909 +       /* Get pointer to private data */
6910 +       this = (struct nand_chip *) (&crisv32_mtd[1]);
6911 +
6912 +       pa_oe.oe |= 1 << CE_BIT;
6913 +       pa_oe.oe |= 1 << ALE_BIT;
6914 +       pa_oe.oe |= 1 << CLE_BIT;
6915 +       pa_oe.oe &= ~ (1 << BY_BIT);
6916 +       REG_WR(gio, regi_gio, rw_pa_oe, pa_oe);
6917 +
6918 +       bif_cfg.gated_csp0 = regk_bif_core_rd;
6919 +       bif_cfg.gated_csp1 = regk_bif_core_wr;
6920 +       REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
6921 +
6922 +       /* Initialize structures */
6923 +       memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info));
6924 +       memset((char *) this, 0, sizeof(struct nand_chip));
6925 +
6926 +       /* Link the private data with the MTD structure */
6927 +       crisv32_mtd->priv = this;
6928 +
6929 +       /* Set address of NAND IO lines */
6930 +       this->IO_ADDR_R = (void *) NAND_RD_ADDR;
6931 +       this->IO_ADDR_W = (void *) NAND_WR_ADDR;
6932 +       this->hwcontrol = crisv32_hwcontrol;
6933 +       this->dev_ready = crisv32_device_ready;
6934 +       /* 20 us command delay time */
6935 +       this->chip_delay = 20;          
6936 +       this->eccmode = NAND_ECC_SOFT;
6937 +
6938 +#if 0 /* don't use BBT in boot loader */
6939 +       /* Enable the following for a flash based bad block table */
6940 +       this->options = NAND_USE_FLASH_BBT;
6941 +#endif
6942 +       /* don't scan for BBT */
6943 +       this->options = NAND_SKIP_BBTSCAN;
6944 +
6945 +       /* Scan to find existance of the device */
6946 +       if (nand_scan (crisv32_mtd, 1)) {
6947 +               err = -ENXIO;
6948 +               puts ("nand_scan failed\r\n");
6949 +               free (crisv32_mtd);
6950 +               return NULL;
6951 +       }
6952 +       
6953 +       return crisv32_mtd;
6954 +}
6955 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/head.S
6956 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/head.S    2007-01-10 20:10:37.000000000 +0100
6957 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/head.S    2007-01-31 16:52:19.000000000 +0100
6958 @@ -1,14 +1,85 @@
6959 -/* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $
6960 - *
6961 - * This used to be the rescue code but now that is handled by the
6962 - * RedBoot based RFL instead. Nothing to see here, move along.
6963 +/* $Id: head.S,v 1.16 2007/01/31 15:52:19 pkj Exp $
6964 + * 
6965 + * Simple boot loader which can also handle NAND chips.
6966   */
6967  
6968 -#include <asm/arch/hwregs/reg_map_asm.h>
6969 -#include <asm/arch/hwregs/config_defs_asm.h>
6970 +#include <asm/arch/hwregs/asm/reg_map_asm.h>
6971 +#include <asm/arch/hwregs/asm/config_defs_asm.h>
6972 +
6973 +#define RAM_INIT_MAGIC 0x56902387
6974 +#define NAND_BOOT_MAGIC 0x9A9DB001
6975 +
6976 +;; Debugging. Normally all these are set to 0.
6977 +#define LEDS (0)
6978 +#define LEDTEST (0)
6979 +#define FLASH_LEDS_INSTEAD_OF_BOOT (0)
6980 +#define SERIAL_DUMP (0)
6981 +#define SERIAL_PORT (0)
6982 +#define SERIAL_RECEIVE (0)
6983 +
6984 +#if LEDS
6985 +#include <asm/arch/hwregs/asm/gio_defs_asm.h>
6986 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
6987 +#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
6988 +#endif
6989 +
6990 +#if SERIAL_DUMP
6991 +#include <asm/arch/hwregs/asm/ser_defs_asm.h>
6992 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
6993 +#endif
6994 +
6995 +
6996 +#if (SERIAL_PORT == 0)
6997 +#define regi_serial regi_ser0
6998 +#endif
6999 +#if (SERIAL_PORT == 1)
7000 +#define regi_serial regi_ser1
7001 +#endif
7002 +
7003 +;; Macros
7004 +
7005 +#if LEDS
7006 +.macro SAY x
7007 +       orq 31, $r9
7008 +       and.d ~(\x), $r9
7009 +       move.d $r9, [$r8]
7010 +.endm
7011 +#else
7012 +.macro SAY x
7013 +       ;; nothing
7014 +.endm
7015 +#endif
7016 +
7017 +#if SERIAL_DUMP
7018 +.macro DISPLAY x
7019 +       move.d \x, $r6  ; save value
7020 +       moveq 28, $r5 ; counter / shift amount
7021 +8:
7022 +       move.d $r6, $r3 ; fetch value
7023 +       bsr nybbleout
7024 +       lsr.d $r5, $r3 ; shift nybble we want (delay slot)
7025 +       subq 4, $r5  ; count down bits
7026 +       bpl 8b ; loop
7027 +       nop
7028 +       bsr serout
7029 +       moveq 13, $r3 ; delay slot
7030 +       bsr serout
7031 +       moveq 10, $r3 ; delay slot
7032 +.endm
7033 +#else
7034 +.macro         DISPLAY x
7035 +       ;; nothing
7036 +.endm
7037 +#endif
7038 +
7039 +
7040 +;; Code
7041  
7042         .text
7043 +start:
7044  
7045 +       ;; TODO: Add code for Ronny's search-for-good-block boot rom algorithm
7046 +       
7047         ;; Start clocks for used blocks.
7048         move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
7049         move.d [$r1], $r0
7050 @@ -17,22 +88,258 @@
7051                REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
7052         move.d $r0, [$r1]
7053  
7054 -       ;; Copy 68KB NAND flash to Internal RAM (if NAND boot)
7055 -       move.d 0x38004000, $r10
7056 -       move.d 0x8000, $r11
7057 -       move.d 0x11000, $r12
7058 -       move.d copy_complete, $r13
7059 -       and.d  0x000fffff, $r13
7060 -       or.d   0x38000000, $r13
7061 +
7062 +#if LEDS
7063 +       ;; set up for led control on PB 0..4
7064 +       move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r8 ; output reg
7065 +       move.d [$r8], $r9 ; shadow
7066 +
7067 +       ;; set up pinmux
7068 +       move.d REG_ADDR(pinmux, regi_pinmux, rw_pb_gio), $r2
7069 +       move.d [$r2], $r3
7070 +        orq 31, $r3
7071 +       move.d $r3, [$r2]
7072 +
7073 +       ;; set up GPIO
7074 +       ;; set to outputs
7075 +       move.d REG_ADDR(gio, regi_gio, rw_pb_oe), $r2
7076 +       move.d [$r2], $r3
7077 +       orq 31, $r3
7078 +       move.d $r3, [$r2]
7079 +
7080 +
7081 +#if LEDTEST
7082 +               ;; led test
7083 +
7084 +       moveq 0, $r1 ; led 5-bit binary counter
7085 +1:
7086 +       or.d 31, $r9
7087 +       xor $r1, $r9
7088 +       move.d $r9, [$r8]
7089 +       addq 1, $r1
7090 +
7091 +       move.d 100000000, $r2 ; delay loop (100e6 => 1s @200Mc)
7092 +2:
7093 +       bne 2b
7094 +       subq 1, $r2
7095 +
7096 +       ba 1b ; loop
7097 +       nop
7098 +#endif
7099 +
7100 +#endif
7101 +
7102 +
7103 +check_nand_boot:
7104 +       ;; Check boot source by checking highest nybble of PC:
7105 +       ;; If we're running at address 0x0XXXXXXX, we're in flash/eprom/sram
7106 +       ;; If we're running at address 0x38000000, we're in internal RAM,
7107 +       ;; so we're most likely coming from NAND.
7108 +       ;; If we're running at address 0x40000000, we're in SDRAM,
7109 +       ;; so we've most likely been started by some sort of bootstrapper
7110 +       ;; e.g. fsboot, which in turn implies NAND, else we would be booting
7111 +       ;; normally at 0x0XXXXXXX
7112 +
7113 +       SAY 1
7114 +
7115 +here:
7116 +       lapcq   ., $r0          ; get PC
7117 +       sub.d   (here-start), $r0 ; offset from here
7118 +       beq     normal_boot     ; running at address 0 - normal boot
7119 +       move.d  $r0, $r13       ; save offset for later (unused delay slot)
7120 +       lsrq    28, $r0         ; get highest nybble
7121 +
7122 +       SAY 2
7123 +
7124 +       ;; Prepare to copy 128KB of the NAND flash to internal RAM
7125 +       move.d  0x38000200, $r10 ; dest in internal RAM
7126 +       move.d  0x1fe00, $r12   ; #bytes
7127 +       cmpq    4, $r0          ; running in RAM => started by fsboot
7128 +       bhs     copy_from_ram
7129 +       movu.w 0x0200, $r11     ; source in flash (byte address) (DELAY SLOT)
7130  
7131  #include "../../lib/nand_init.S"
7132  
7133 -       ;; No NAND found
7134 +#if LEDS
7135 +       ;; must set up registers again (clobbered by nand_init)
7136 +       move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r8 ; output reg
7137 +       move.d [$r8], $r9 ; shadow
7138 +#endif
7139 +
7140 +       SAY 3
7141 +
7142 +       ba      copy_complete
7143 +       nop
7144 +
7145 +        ; Since the code above has to reside within the first 256 bytes of 
7146 +        ; NAND flash, verify that the code so far hasn't gone past this
7147 +       ; limit. If you're considering removing this, you haven't 
7148 +       ; properly understood the problem; see nand_init.S for details.
7149 +       .org PAGE_SIZE_ADDRESSES        ; from nand_init.S
7150 +       .org PAGE_SIZE_BYTES            ; from nand_init.S
7151 +
7152 +normal_boot:
7153 +       SAY 4
7154 +
7155 +       ;; Normal NOR boot
7156         move.d  CONFIG_ETRAX_PTABLE_SECTOR, $r10
7157 -       jump    $r10 ; Jump to decompresser
7158 +       jump    $r10                    ; Jump to decompresser 
7159 +       nop
7160 +                               
7161 +copy_from_ram:
7162 +       add.d   $r13, $r11              ; mem offs + src offs -> src addr
7163 +1:
7164 +       move.d  [$r11+], $r0            ; read source
7165 +       subq    4, $r12                 ; 4 bytes at a time
7166 +       bne     1b                      ; loop until done
7167 +       move.d  $r0, [$r10+]            ; write dest (DELAY SLOT)
7168 +       jump    copy_complete           ; jump to internal RAM
7169 +       nop                             ; delay slot
7170 +
7171 +copy_complete: 
7172 +       SAY 5
7173 +
7174 +#if FLASH_LEDS_INSTEAD_OF_BOOT
7175 +
7176 +flash:
7177 +
7178 +               ;; led test
7179 +
7180 +       moveq 0, $r1 ; led binary counter
7181 +1:
7182 +       or.d 31, $r9
7183 +       xor $r1, $r9
7184 +       move.d $r9, [$r8]
7185 +       addq 1, $r1
7186 +
7187 +       move.d 100000000, $r2 ; delay loop (100e6 => 1s)
7188 +2:
7189 +       bne 2b
7190 +       subq 1, $r2
7191 +
7192 +       ba 1b ; loop forever
7193         nop
7194 +#endif
7195  
7196 -copy_complete:
7197 -       move.d  0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10
7198 -       jump    $r10 ; Jump to decompresser
7199 +
7200 +#if SERIAL_DUMP
7201 +       ;; dump memory to serial port
7202 +
7203 +#if (SERIAL_PORT == 1)
7204 +       ;; set up serial-1 pins
7205 +       move.d REG_ADDR(pinmux, regi_pinmux, rw_hwprot), $r1
7206 +       move.d [$r1], $r0
7207 +       or.d REG_STATE(pinmux, rw_hwprot, ser1, yes), $r0
7208 +       move.d $r0, [$r1]
7209 +#endif
7210 +
7211 +       ;; rw_xoff: chr and automatic = 0
7212 +       move.d REG_ADDR(ser, regi_serial, rw_xoff), $r1
7213 +       move.d [$r1], $r0
7214 +       and.d ~(REG_MASK(ser, rw_xoff, automatic) | REG_MASK(ser, rw_xoff, chr)), $r0
7215 +       move.d $r0, [$r1]
7216 +
7217 +       ;; tr control
7218 +       move.d REG_ADDR(ser, regi_serial, rw_tr_ctrl), $r1
7219 +       move.d [$r1], $r0
7220 +       and.d ~(REG_MASK(ser, rw_tr_ctrl, base_freq) | REG_MASK(ser, rw_tr_ctrl, stop_bits)), $r0
7221 +       or.d REG_STATE(ser, rw_tr_ctrl, stop_bits, bits2) | REG_STATE(ser, rw_tr_ctrl, base_freq, f29_493) | REG_STATE(ser, rw_tr_ctrl, en, yes), $r0
7222 +       move.d $r0, [$r1]
7223 +
7224 +       ;; tr baud
7225 +       move.d REG_ADDR(ser, regi_serial, rw_tr_baud_div), $r1
7226 +       move.d [$r1], $r0
7227 +       move.w (29493000 / 8) / 115200, $r0
7228 +       move.d $r0, [$r1]
7229 +
7230 +#if SERIAL_RECEIVE
7231 +       ;; rec control
7232 +       move.d REG_ADDR(ser, regi_serial, rw_rec_ctrl), $r1
7233 +       move.d [$r1], $r0
7234 +       and.d ~(REG_MASK(ser, rw_rec_ctrl, base_freq)), $r0
7235 +       or.d REG_STATE(ser, rw_rec_ctrl, base_freq, f29_493) | REG_STATE(ser, rw_tr_ctrl, en, yes), $r0
7236 +       move.d $r0, [$r1]
7237 +
7238 +       ;; rec baud
7239 +       move.d REG_ADDR(ser, regi_serial, rw_rec_baud_div), $r1
7240 +       move.d [$r1], $r0
7241 +       move.w (29493000 / 8) / 115200, $r0
7242 +       move.d $r0, [$r1]
7243 +#endif
7244 +
7245 +       ;; dump memory
7246 +
7247 +       move.d 0x38000000, $r5 ; pointer
7248 +
7249 +       bsr serout
7250 +       moveq 13, $r3
7251 +       bsr serout
7252 +       moveq 10, $r3
7253 +       bsr serout
7254 +       moveq 10, $r3
7255 +
7256 +1:
7257 +       movu.b [$r5+], $r3 ; get value
7258 +       move.d $r3, $r6 ; save
7259 +
7260 +       bsr nybbleout
7261 +       lsrq 4, $r3 ; high nybble (delay slot)
7262 +
7263 +       move.d $r6, $r3 ; restore
7264 +       bsr nybbleout
7265 +       andq 15, $r3 ; delay slot
7266 +
7267 +       movu.b 32, $r3
7268 +       bsr serout
7269         nop
7270 +
7271 +       move.d $r5, $r3
7272 +       andq 15, $r3
7273 +       bne 1b
7274 +       nop
7275 +
7276 +       bsr serout
7277 +       moveq 13, $r3 ; delay slot
7278 +       bsr serout 
7279 +       moveq 10, $r3 ; delay slot
7280 +
7281 +       ba 1b ; loop forever
7282 +       nop
7283 +
7284 +nybbleout:
7285 +       cmpq 10, $r3
7286 +       blo 1f
7287 +       addq 48, $r3 ; delay slot
7288 +       addq 7, $r3
7289 +1:
7290 +serout:
7291 +       move.d REG_ADDR(ser, regi_serial, rs_stat_din), $r1
7292 +       move.d REG_ADDR(ser, regi_serial, rw_dout), $r2
7293 +2:
7294 +       move.d [$r1], $r4
7295 +       btstq REG_BIT(ser, rs_stat_din, tr_rdy), $r4
7296 +       bpl 2b
7297 +       nop
7298 +       ret
7299 +       move.d $r3, [$r2] ; delay slot
7300 +
7301 +#endif
7302 +
7303 +;; Init DRAM
7304 +
7305 +#include "../../lib/dram_init.S"
7306 +       move.d  RAM_INIT_MAGIC, $r8     ; tell kernel boot loader dram init'd
7307 +       move.d  NAND_BOOT_MAGIC, $r12   ; booted from NAND flash
7308 +
7309 +;; TODO: Clear .bss (not needed yet because size of .bss is zero)
7310 +;; TODO: Change .ld script so that BSS is in DRAM?
7311 +
7312 +;; Ok, time to do something. Continue with boot loader in C.
7313 +;; Must set up minimal C environment first though.
7314 +
7315 +       move.d  0x38020000, $sp ; stack pointer at top of internal RAM
7316 +
7317 +       move.d  bootload, $r10
7318 +       jump    $r10                    ; Jump to boot loader
7319 +       nop
7320 +
7321 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.c
7322 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.c     1970-01-01 01:00:00.000000000 +0100
7323 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.c     2006-11-03 11:35:52.000000000 +0100
7324 @@ -0,0 +1,243 @@
7325 +/*
7326 + * lib.c
7327 + * Small practical functions for boot loader
7328 + * malloc/free
7329 + * memcpy/memset
7330 + * writeb/writew/readb/readw
7331 + * putc/puts/putnybble/putx
7332 + * error/error2/BUG
7333 + * serial_init
7334 + *
7335 + * $Id: lib.c,v 1.4 2006/11/03 10:35:52 pkj Exp $
7336 + * 
7337 + */
7338 +
7339 +#include <linux/types.h>
7340 +#include <asm/arch/hwregs/reg_rdwr.h>
7341 +#include <asm/arch/hwregs/reg_map.h>
7342 +#include <asm/arch/hwregs/ser_defs.h>
7343 +#include <asm/arch/hwregs/pinmux_defs.h>
7344 +
7345 +#include "lib.h"
7346 +
7347 +/* the "heap" is put directly after BSS ends, at _end */
7348 +  
7349 +extern int _end;
7350 +static long free_mem_ptr = (long)&_end;
7351
7352 +void *malloc(int size)
7353 +{
7354 +       void *p;
7355 +
7356 +       if (size <0) error("Malloc error");
7357 +
7358 +       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
7359 +
7360 +       p = (void *)free_mem_ptr;
7361 +       free_mem_ptr += size;
7362 +
7363 +       return p;
7364 +}
7365 +
7366 +void free(void *where)
7367 +{      /* Don't care */
7368 +}
7369 +
7370 +/* I/O */
7371 +
7372 +unsigned char readb(const volatile void *addr)
7373 +{
7374 +       return *(volatile unsigned char *) addr;
7375 +}
7376 +
7377 +unsigned short readw(const volatile void *addr)
7378 +{
7379 +       return *(volatile unsigned short *) addr;
7380 +}
7381 +
7382 +void writeb(unsigned char b, volatile void *addr)
7383 +{
7384 +       *(volatile unsigned char *) addr = b;
7385 +}
7386 +
7387 +void writew(unsigned short b, volatile void *addr)
7388 +{
7389 +       *(volatile unsigned short *) addr = b;
7390 +}
7391 +
7392 +/* info and error messages to serial console */
7393 +
7394 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
7395 +static inline void
7396 +serout(const char c, reg_scope_instances regi_ser)
7397 +{
7398 +       reg_ser_rs_stat_din rs;
7399 +       reg_ser_rw_dout dout = {.data = c};
7400 +
7401 +       do {
7402 +               rs = REG_RD(ser, regi_ser, rs_stat_din);
7403 +       }
7404 +       while (!rs.tr_rdy);/* Wait for tranceiver. */
7405 +       
7406 +       REG_WR(ser, regi_ser, rw_dout, dout);
7407 +}
7408 +
7409 +
7410 +void
7411 +putc(const char c)
7412 +{
7413 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7414 +       serout(c, regi_ser0);
7415 +#endif
7416 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7417 +       serout(c, regi_ser1);
7418 +#endif
7419 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7420 +       serout(c, regi_ser2);
7421 +#endif
7422 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7423 +       serout(c, regi_ser3);
7424 +#endif
7425 +}
7426 +
7427 +
7428 +void
7429 +puts(const char *s)
7430 +{
7431 +       while (*s)
7432 +               putc(*s++);
7433 +}
7434 +
7435 +void
7436 +putnybble(int n)
7437 +{
7438 +       putc("0123456789abcdef"[n & 15]);
7439 +}
7440 +
7441 +void
7442 +putx(int x)
7443 +{
7444 +       int i;
7445 +
7446 +       puts("0x");
7447 +       for (i = 7; i >= 0; i--)
7448 +               putnybble(x >> 4*i);
7449 +}
7450 +
7451 +void
7452 +putnl()
7453 +{
7454 +       puts("\r\n");
7455 +}
7456 +
7457 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
7458 +
7459 +void*
7460 +memset(void* s, int c, size_t n)
7461 +{
7462 +       int i;
7463 +       char *ss = (char*)s;
7464 +
7465 +       for (i=0;i<n;i++) ss[i] = c;
7466 +}
7467 +
7468 +void*
7469 +memcpy(void* __dest, __const void* __src,
7470 +                           size_t __n)
7471 +{
7472 +       int i;
7473 +       char *d = (char *)__dest, *s = (char *)__src;
7474 +
7475 +       for (i=0;i<__n;i++) d[i] = s[i];
7476 +}
7477 +
7478 +void
7479 +error(const char *x)
7480 +{
7481 +       puts("\r\n\n");
7482 +       puts(x);
7483 +       puts("\r\n\n -- System halted\n");
7484 +
7485 +       while(1);       /* Halt */
7486 +}
7487 +
7488 +void
7489 +error2(const char *x, int y, const char *z)
7490 +{
7491 +       puts("\r\n\n");
7492 +       puts(x);
7493 +       putc(':');
7494 +       putx(y);
7495 +       putc(':');
7496 +       puts(z);
7497 +       puts("\r\n\n -- System halted\n");
7498 +
7499 +       while(1);       /* Halt */
7500 +}
7501 +
7502 +static inline void
7503 +serial_setup(reg_scope_instances regi_ser)
7504 +{
7505 +       reg_ser_rw_xoff xoff;
7506 +       reg_ser_rw_tr_ctrl tr_ctrl;
7507 +       reg_ser_rw_rec_ctrl rec_ctrl;
7508 +       reg_ser_rw_tr_baud_div tr_baud;
7509 +       reg_ser_rw_rec_baud_div rec_baud;
7510 +       
7511 +       /* Turn off XOFF. */
7512 +       xoff = REG_RD(ser, regi_ser, rw_xoff);
7513 +       
7514 +       xoff.chr = 0;
7515 +       xoff.automatic = regk_ser_no;
7516 +       
7517 +       REG_WR(ser, regi_ser, rw_xoff, xoff);
7518 +
7519 +       /* Set baudrate and stopbits. */
7520 +       tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
7521 +       rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
7522 +       tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
7523 +       rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
7524 +       
7525 +       tr_ctrl.stop_bits = 1;  /* 2 stop bits. */
7526 +       tr_ctrl.en = 1; /* enable transmitter */
7527 +       rec_ctrl.en = 1; /* enabler receiver */
7528 +       
7529 +       /* 
7530 +        * The baudrate setup used to be a bit fishy, but now transmitter and
7531 +        * receiver are both set to the intended baud rate, 115200.
7532 +        * The magic value is 29.493 MHz.
7533 +        */
7534 +       tr_ctrl.base_freq = regk_ser_f29_493;
7535 +       rec_ctrl.base_freq = regk_ser_f29_493;
7536 +       tr_baud.div = (29493000 / 8) / 115200;
7537 +       rec_baud.div = (29493000 / 8) / 115200;
7538 +       
7539 +       REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
7540 +       REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
7541 +       REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
7542 +       REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
7543 +}
7544 +
7545 +void
7546 +serial_init()
7547 +{
7548 +       reg_pinmux_rw_hwprot hwprot;
7549 +       
7550 +       hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
7551 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7552 +       serial_setup(regi_ser0);
7553 +#endif
7554 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7555 +       hwprot.ser1 = regk_pinmux_yes;
7556 +       serial_setup(regi_ser1);
7557 +#endif
7558 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7559 +       hwprot.ser2 = regk_pinmux_yes;
7560 +       serial_setup(regi_ser2);
7561 +#endif
7562 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7563 +       hwprot.ser3 = regk_pinmux_yes;
7564 +       serial_setup(regi_ser3);
7565 +#endif
7566 +       REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
7567 +}
7568 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.h
7569 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.h     1970-01-01 01:00:00.000000000 +0100
7570 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.h     2006-11-03 11:35:52.000000000 +0100
7571 @@ -0,0 +1,56 @@
7572 +/*
7573 + * lib.c
7574 + * Small practical functions for boot loader
7575 + * malloc/free
7576 + * memset/memcpy
7577 + * putc/puts/putnybble/putd
7578 + * writeb/writew/readb/readw
7579 + * error/error2/BUG
7580 + * serial_init
7581 + *
7582 + * $Id: lib.h,v 1.3 2006/11/03 10:35:52 pkj Exp $
7583 + * 
7584 + */
7585 +
7586 +#ifndef _LIB_H
7587 +#define _LIB_H
7588 +
7589 +#include <linux/types.h>
7590 +
7591 +/* nice stuff we need without having any library around */
7592 +
7593 +void* memset(void* s, int c, size_t n);
7594 +void* memcpy(void* __dest, __const void* __src,
7595 +            size_t __n);
7596 +
7597 +#define memzero(s, n)     memset ((s), 0, (n))
7598 +
7599 +#undef BUG
7600 +#define BUG() error2("BUG in " __FILE__, __LINE__, __FUNCTION__)
7601 +
7602 +void *malloc(int size);
7603 +void free(void *where);
7604 +void error(const char *m);
7605 +void error2(const char *m, int l, const char *f);
7606 +void serial_init(void);
7607 +
7608 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL 
7609 +void putc(const char);
7610 +void puts(const char *);
7611 +void putnybble(int n);
7612 +void putx(int x);
7613 +void putnl();
7614 +#else
7615 +#define putc(ch) 
7616 +#define puts(str)
7617 +#define putnybble(nyb)
7618 +#define putx(x)
7619 +#define putnl()
7620 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
7621 +
7622 +unsigned char readb(const volatile void *addr);
7623 +unsigned short readw(const volatile void *addr);
7624 +void writeb(unsigned char b, volatile void *addr);
7625 +void writew(unsigned short b, volatile void *addr);
7626 +
7627 +#endif /* _LIB_H */
7628 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd-abi.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd-abi.h
7629 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd-abi.h 1970-01-01 01:00:00.000000000 +0100
7630 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd-abi.h 2006-09-06 11:21:07.000000000 +0200
7631 @@ -0,0 +1,121 @@
7632 +/*
7633 + * $Id: mtd-abi.h,v 1.1 2006/09/06 09:21:07 ricardw Exp $
7634 + *
7635 + * Portions of MTD ABI definition which are shared by kernel and user space
7636 + */
7637 +
7638 +#ifndef __MTD_ABI_H__
7639 +#define __MTD_ABI_H__
7640 +
7641 +#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into
7642 +                   separate files was to avoid #ifdef __KERNEL__ */
7643 +#define __user
7644 +#endif
7645 +
7646 +struct erase_info_user {
7647 +       uint32_t start;
7648 +       uint32_t length;
7649 +};
7650 +
7651 +struct mtd_oob_buf {
7652 +       uint32_t start;
7653 +       uint32_t length;
7654 +       unsigned char __user *ptr;
7655 +};
7656 +
7657 +#define MTD_ABSENT             0
7658 +#define MTD_RAM                        1
7659 +#define MTD_ROM                        2
7660 +#define MTD_NORFLASH           3
7661 +#define MTD_NANDFLASH          4
7662 +#define MTD_PEROM              5
7663 +#define MTD_DATAFLASH          6
7664 +#define MTD_OTHER              14
7665 +#define MTD_UNKNOWN            15
7666 +
7667 +#define MTD_CLEAR_BITS         1       // Bits can be cleared (flash)
7668 +#define MTD_SET_BITS           2       // Bits can be set
7669 +#define MTD_ERASEABLE          4       // Has an erase function
7670 +#define MTD_WRITEB_WRITEABLE   8       // Direct IO is possible
7671 +#define MTD_VOLATILE           16      // Set for RAMs
7672 +#define MTD_XIP                        32      // eXecute-In-Place possible
7673 +#define MTD_OOB                        64      // Out-of-band data (NAND flash)
7674 +#define MTD_ECC                        128     // Device capable of automatic ECC
7675 +#define MTD_NO_VIRTBLOCKS      256     // Virtual blocks not allowed
7676 +#define MTD_PROGRAM_REGIONS    512     // Configurable Programming Regions
7677 +
7678 +// Some common devices / combinations of capabilities
7679 +#define MTD_CAP_ROM            0
7680 +#define MTD_CAP_RAM            (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE)
7681 +#define MTD_CAP_NORFLASH        (MTD_CLEAR_BITS|MTD_ERASEABLE)
7682 +#define MTD_CAP_NANDFLASH       (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB)
7683 +#define MTD_WRITEABLE          (MTD_CLEAR_BITS|MTD_SET_BITS)
7684 +
7685 +
7686 +// Types of automatic ECC/Checksum available
7687 +#define MTD_ECC_NONE           0       // No automatic ECC available
7688 +#define MTD_ECC_RS_DiskOnChip  1       // Automatic ECC on DiskOnChip
7689 +#define MTD_ECC_SW             2       // SW ECC for Toshiba & Samsung devices
7690 +
7691 +/* ECC byte placement */
7692 +#define MTD_NANDECC_OFF                0       // Switch off ECC (Not recommended)
7693 +#define MTD_NANDECC_PLACE      1       // Use the given placement in the structure (YAFFS1 legacy mode)
7694 +#define MTD_NANDECC_AUTOPLACE  2       // Use the default placement scheme
7695 +#define MTD_NANDECC_PLACEONLY  3       // Use the given placement in the structure (Do not store ecc result on read)
7696 +#define MTD_NANDECC_AUTOPL_USR         4       // Use the given autoplacement scheme rather than using the default
7697 +
7698 +/* OTP mode selection */
7699 +#define MTD_OTP_OFF            0
7700 +#define MTD_OTP_FACTORY                1
7701 +#define MTD_OTP_USER           2
7702 +
7703 +struct mtd_info_user {
7704 +       uint8_t type;
7705 +       uint32_t flags;
7706 +       uint32_t size;   // Total size of the MTD
7707 +       uint32_t erasesize;
7708 +       uint32_t oobblock;  // Size of OOB blocks (e.g. 512)
7709 +       uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
7710 +       uint32_t ecctype;
7711 +       uint32_t eccsize;
7712 +};
7713 +
7714 +struct region_info_user {
7715 +       uint32_t offset;                /* At which this region starts,
7716 +                                        * from the beginning of the MTD */
7717 +       uint32_t erasesize;             /* For this region */
7718 +       uint32_t numblocks;             /* Number of blocks in this region */
7719 +       uint32_t regionindex;
7720 +};
7721 +
7722 +struct otp_info {
7723 +       uint32_t start;
7724 +       uint32_t length;
7725 +       uint32_t locked;
7726 +};
7727 +
7728 +#define MEMGETINFO              _IOR('M', 1, struct mtd_info_user)
7729 +#define MEMERASE                _IOW('M', 2, struct erase_info_user)
7730 +#define MEMWRITEOOB             _IOWR('M', 3, struct mtd_oob_buf)
7731 +#define MEMREADOOB              _IOWR('M', 4, struct mtd_oob_buf)
7732 +#define MEMLOCK                 _IOW('M', 5, struct erase_info_user)
7733 +#define MEMUNLOCK               _IOW('M', 6, struct erase_info_user)
7734 +#define MEMGETREGIONCOUNT      _IOR('M', 7, int)
7735 +#define MEMGETREGIONINFO       _IOWR('M', 8, struct region_info_user)
7736 +#define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
7737 +#define MEMGETOOBSEL           _IOR('M', 10, struct nand_oobinfo)
7738 +#define MEMGETBADBLOCK         _IOW('M', 11, loff_t)
7739 +#define MEMSETBADBLOCK         _IOW('M', 12, loff_t)
7740 +#define OTPSELECT              _IOR('M', 13, int)
7741 +#define OTPGETREGIONCOUNT      _IOW('M', 14, int)
7742 +#define OTPGETREGIONINFO       _IOW('M', 15, struct otp_info)
7743 +#define OTPLOCK                _IOR('M', 16, struct otp_info)
7744 +
7745 +struct nand_oobinfo {
7746 +       uint32_t useecc;
7747 +       uint32_t eccbytes;
7748 +       uint32_t oobfree[8][2];
7749 +       uint32_t eccpos[32];
7750 +};
7751 +
7752 +#endif /* __MTD_ABI_H__ */
7753 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd.h
7754 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd.h     1970-01-01 01:00:00.000000000 +0100
7755 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd.h     2006-12-14 07:59:24.000000000 +0100
7756 @@ -0,0 +1,270 @@
7757 +/*
7758 + * $Id: mtd.h,v 1.5 2006/12/14 06:59:24 ricardw Exp $
7759 + *
7760 + * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
7761 + *
7762 + * Released under GPL
7763 + */
7764 +
7765 +#ifndef __MTD_MTD_H__
7766 +#define __MTD_MTD_H__
7767 +
7768 +#ifndef __KERNEL__
7769 +#error This is a kernel header. Perhaps include mtd-user.h instead?
7770 +#endif
7771 +
7772 +/* only include absolutely necessary linux headers which will not change
7773 + * significantly 
7774 + */
7775 +#include <linux/types.h>
7776 +#include <linux/errno.h>
7777 +
7778 +#if 0
7779 +#include <linux/module.h>
7780 +#include <linux/uio.h>
7781 +#include <linux/notifier.h>
7782 +
7783 +#include <linux/mtd/compatmac.h>
7784 +#include <mtd/mtd-abi.h>
7785 +#endif
7786 +
7787 +#include "mtd-abi.h"
7788 +
7789 +/* local config, we don't want linux/config.h here */
7790 +/* any undef/define pairs here avoid warnings due to linux autoconf includes */
7791 +#undef CONFIG_MTD_PARTITIONS
7792 +#undef CONFIG_MTD_DEBUG
7793 +#undef CONFIG_MTD_NAND_VERIFY_WRITE
7794 +#define CONFIG_MTD_NAND_VERIFY_WRITE
7795 +
7796 +/* our MTD config */
7797 +
7798 +#define NAND_BBT_SUPPORT  0
7799 +#define NAND_WRITE_SUPPORT 0
7800 +#define NAND_ERASE_SUPPORT 0
7801 +#define NAND_MULTICHIP_SUPPORT 0
7802 +#define NAND_HWECC_SUPPORT 0
7803 +#define NAND_KVEC_SUPPORT 0
7804 +
7805 +
7806 +#define MTD_CHAR_MAJOR 90
7807 +#define MTD_BLOCK_MAJOR 31
7808 +#define MAX_MTD_DEVICES 16
7809 +
7810 +#define MTD_ERASE_PENDING              0x01
7811 +#define MTD_ERASING            0x02
7812 +#define MTD_ERASE_SUSPEND      0x04
7813 +#define MTD_ERASE_DONE          0x08
7814 +#define MTD_ERASE_FAILED        0x10
7815 +
7816 +/* If the erase fails, fail_addr might indicate exactly which block failed.  If
7817 +   fail_addr = 0xffffffff, the failure was not at the device level or was not
7818 +   specific to any particular block. */
7819 +struct erase_info {
7820 +       struct mtd_info *mtd;
7821 +       u_int32_t addr;
7822 +       u_int32_t len;
7823 +       u_int32_t fail_addr;
7824 +       u_long time;
7825 +       u_long retries;
7826 +       u_int dev;
7827 +       u_int cell;
7828 +       void (*callback) (struct erase_info *self);
7829 +       u_long priv;
7830 +       u_char state;
7831 +       struct erase_info *next;
7832 +};
7833 +
7834 +struct mtd_erase_region_info {
7835 +       u_int32_t offset;                       /* At which this region starts, from the beginning of the MTD */
7836 +       u_int32_t erasesize;            /* For this region */
7837 +       u_int32_t numblocks;            /* Number of blocks of erasesize in this region */
7838 +};
7839 +
7840 +struct mtd_info {
7841 +       u_char type;
7842 +       u_int32_t flags;
7843 +       u_int32_t size;  // Total size of the MTD
7844 +
7845 +       /* "Major" erase size for the device. Naïve users may take this
7846 +        * to be the only erase size available, or may use the more detailed
7847 +        * information below if they desire
7848 +        */
7849 +       u_int32_t erasesize;
7850 +
7851 +       u_int32_t oobblock;  // Size of OOB blocks (e.g. 512)
7852 +       u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
7853 +       u_int32_t ecctype;
7854 +       u_int32_t eccsize;
7855 +
7856 +       /*
7857 +        * Reuse some of the above unused fields in the case of NOR flash
7858 +        * with configurable programming regions to avoid modifying the
7859 +        * user visible structure layout/size.  Only valid when the
7860 +        * MTD_PROGRAM_REGIONS flag is set.
7861 +        * (Maybe we should have an union for those?)
7862 +        */
7863 +#define MTD_PROGREGION_SIZE(mtd)  (mtd)->oobblock
7864 +#define MTD_PROGREGION_CTRLMODE_VALID(mtd)  (mtd)->oobsize
7865 +#define MTD_PROGREGION_CTRLMODE_INVALID(mtd)  (mtd)->ecctype
7866 +
7867 +       // Kernel-only stuff starts here.
7868 +       char *name;
7869 +       int index;
7870 +
7871 +       // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
7872 +       struct nand_oobinfo oobinfo;
7873 +       u_int32_t oobavail;  // Number of bytes in OOB area available for fs
7874 +
7875 +       /* Data for variable erase regions. If numeraseregions is zero,
7876 +        * it means that the whole device has erasesize as given above.
7877 +        */
7878 +       int numeraseregions;
7879 +       struct mtd_erase_region_info *eraseregions;
7880 +
7881 +       /* This really shouldn't be here. It can go away in 2.5 */
7882 +       u_int32_t bank_size;
7883 +
7884 +       int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
7885 +
7886 +       /* This stuff for eXecute-In-Place */
7887 +       int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
7888 +
7889 +       /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
7890 +       void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
7891 +
7892 +
7893 +       int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7894 +       int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
7895 +
7896 +       int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
7897 +       int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
7898 +
7899 +       int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7900 +       int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
7901 +
7902 +       /*
7903 +        * Methods to access the protection register area, present in some
7904 +        * flash devices. The user data is one time programmable but the
7905 +        * factory data is read only.
7906 +        */
7907 +       int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
7908 +       int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7909 +       int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
7910 +       int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7911 +       int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7912 +       int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
7913 +
7914 +#if NAND_KVEC_SUPPORT
7915 +       /* kvec-based read/write methods. We need these especially for NAND flash,
7916 +          with its limited number of write cycles per erase.
7917 +          NB: The 'count' parameter is the number of _vectors_, each of
7918 +          which contains an (ofs, len) tuple.
7919 +       */
7920 +       int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
7921 +       int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
7922 +               size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
7923 +       int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
7924 +       int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
7925 +               size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
7926 +#endif
7927 +
7928 +       /* Sync */
7929 +       void (*sync) (struct mtd_info *mtd);
7930 +
7931 +       /* Chip-supported device locking */
7932 +       int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
7933 +       int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
7934 +
7935 +       /* Power Management functions */
7936 +       int (*suspend) (struct mtd_info *mtd);
7937 +       void (*resume) (struct mtd_info *mtd);
7938 +
7939 +       /* Bad block management functions */
7940 +       int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
7941 +       int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
7942 +
7943 +#if 0 /* don't know what this is for */
7944 +       struct notifier_block reboot_notifier;  /* default mode before reboot */
7945 +#endif
7946 +
7947 +       void *priv;
7948 +
7949 +       struct module *owner;
7950 +       int usecount;
7951 +};
7952 +
7953 +#if 0 /* don't need these */
7954 +       /* Kernel-side ioctl definitions */
7955 +
7956 +extern int add_mtd_device(struct mtd_info *mtd);
7957 +extern int del_mtd_device (struct mtd_info *mtd);
7958 +
7959 +extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
7960 +
7961 +extern void put_mtd_device(struct mtd_info *mtd);
7962 +
7963 +
7964 +struct mtd_notifier {
7965 +       void (*add)(struct mtd_info *mtd);
7966 +       void (*remove)(struct mtd_info *mtd);
7967 +       struct list_head list;
7968 +};
7969 +
7970 +
7971 +extern void register_mtd_user (struct mtd_notifier *new);
7972 +extern int unregister_mtd_user (struct mtd_notifier *old);
7973 +#endif
7974 +
7975 +#if NAND_KVEC_SUPPORT
7976 +int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
7977 +                      unsigned long count, loff_t to, size_t *retlen);
7978 +
7979 +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
7980 +                     unsigned long count, loff_t from, size_t *retlen);
7981 +#endif
7982 +
7983 +#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
7984 +#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
7985 +#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
7986 +#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args)
7987 +#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args)
7988 +#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args)
7989 +#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args)
7990 +#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args)
7991 +#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args)
7992 +#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
7993 +#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
7994 +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd);  } while (0)
7995 +
7996 +
7997 +#ifdef CONFIG_MTD_PARTITIONS
7998 +void mtd_erase_callback(struct erase_info *instr);
7999 +#else
8000 +static inline void mtd_erase_callback(struct erase_info *instr)
8001 +{
8002 +       if (instr->callback)
8003 +               instr->callback(instr);
8004 +}
8005 +#endif
8006 +
8007 +/*
8008 + * Debugging macro and defines
8009 + */
8010 +#define MTD_DEBUG_LEVEL0       (0)     /* Quiet   */
8011 +#define MTD_DEBUG_LEVEL1       (1)     /* Audible */
8012 +#define MTD_DEBUG_LEVEL2       (2)     /* Loud    */
8013 +#define MTD_DEBUG_LEVEL3       (3)     /* Noisy   */
8014 +
8015 +#ifdef CONFIG_MTD_DEBUG
8016 +#define DEBUG(n, args...)                              \
8017 +       do {                                            \
8018 +               if (n <= CONFIG_MTD_DEBUG_VERBOSE)      \
8019 +                       printk(KERN_INFO args);         \
8020 +       } while(0)
8021 +#else /* CONFIG_MTD_DEBUG */
8022 +#define DEBUG(n, args...) do { } while(0)
8023 +
8024 +#endif /* CONFIG_MTD_DEBUG */
8025 +
8026 +#endif /* __MTD_MTD_H__ */
8027 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand.h
8028 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand.h    1970-01-01 01:00:00.000000000 +0100
8029 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand.h    2006-11-03 11:35:52.000000000 +0100
8030 @@ -0,0 +1,521 @@
8031 +/*
8032 + *  linux/include/linux/mtd/nand.h
8033 + *
8034 + *  Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
8035 + *                     Steven J. Hill <sjhill@realitydiluted.com>
8036 + *                    Thomas Gleixner <tglx@linutronix.de>
8037 + *
8038 + * $Id: nand.h,v 1.4 2006/11/03 10:35:52 pkj Exp $
8039 + *
8040 + * This program is free software; you can redistribute it and/or modify
8041 + * it under the terms of the GNU General Public License version 2 as
8042 + * published by the Free Software Foundation.
8043 + *
8044 + *  Info:
8045 + *   Contains standard defines and IDs for NAND flash devices
8046 + *
8047 + *  Changelog:
8048 + *   01-31-2000 DMW     Created
8049 + *   09-18-2000 SJH     Moved structure out of the Disk-On-Chip drivers
8050 + *                     so it can be used by other NAND flash device
8051 + *                     drivers. I also changed the copyright since none
8052 + *                     of the original contents of this file are specific
8053 + *                     to DoC devices. David can whack me with a baseball
8054 + *                     bat later if I did something naughty.
8055 + *   10-11-2000 SJH     Added private NAND flash structure for driver
8056 + *   10-24-2000 SJH     Added prototype for 'nand_scan' function
8057 + *   10-29-2001 TG     changed nand_chip structure to support
8058 + *                     hardwarespecific function for accessing control lines
8059 + *   02-21-2002 TG     added support for different read/write adress and
8060 + *                     ready/busy line access function
8061 + *   02-26-2002 TG     added chip_delay to nand_chip structure to optimize
8062 + *                     command delay times for different chips
8063 + *   04-28-2002 TG     OOB config defines moved from nand.c to avoid duplicate
8064 + *                     defines in jffs2/wbuf.c
8065 + *   08-07-2002 TG     forced bad block location to byte 5 of OOB, even if
8066 + *                     CONFIG_MTD_NAND_ECC_JFFS2 is not set
8067 + *   08-10-2002 TG     extensions to nand_chip structure to support HW-ECC
8068 + *
8069 + *   08-29-2002 tglx   nand_chip structure: data_poi for selecting
8070 + *                     internal / fs-driver buffer
8071 + *                     support for 6byte/512byte hardware ECC
8072 + *                     read_ecc, write_ecc extended for different oob-layout
8073 + *                     oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
8074 + *                     NAND_YAFFS_OOB
8075 + *  11-25-2002 tglx    Added Manufacturer code FUJITSU, NATIONAL
8076 + *                     Split manufacturer and device ID structures
8077 + *
8078 + *  02-08-2004 tglx    added option field to nand structure for chip anomalities
8079 + *  05-25-2004 tglx    added bad block table support, ST-MICRO manufacturer id
8080 + *                     update of nand_chip structure description
8081 + *  01-17-2005 dmarlin added extended commands for AG-AND device and added option
8082 + *                     for BBT_AUTO_REFRESH.
8083 + *  01-20-2005 dmarlin added optional pointer to hardware specific callback for
8084 + *                     extra error status checks.
8085 + */
8086 +#ifndef __LINUX_MTD_NAND_H
8087 +#define __LINUX_MTD_NAND_H
8088 +
8089 +#if 0 /* avoid these as much as possible */
8090 +#include <linux/wait.h>
8091 +#include <linux/spinlock.h>
8092 +#include <linux/mtd/mtd.h>
8093 +#endif
8094 +
8095 +#include "mtd.h" /* local */
8096 +
8097 +#include <linux/kernel.h> /* we do need this though ... */
8098 +
8099 +struct mtd_info;
8100 +/* Scan and identify a NAND device */
8101 +extern int nand_scan (struct mtd_info *mtd, int max_chips);
8102 +/* Free resources held by the NAND device */
8103 +extern void nand_release (struct mtd_info *mtd);
8104 +
8105 +/* Read raw data from the device without ECC */
8106 +extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen);
8107 +
8108 +
8109 +/* The maximum number of NAND chips in an array */
8110 +#define NAND_MAX_CHIPS         8
8111 +
8112 +/* This constant declares the max. oobsize / page, which
8113 + * is supported now. If you add a chip with bigger oobsize/page
8114 + * adjust this accordingly.
8115 + */
8116 +#define NAND_MAX_OOBSIZE       64
8117 +
8118 +/*
8119 + * Constants for hardware specific CLE/ALE/NCE function
8120 +*/
8121 +/* Select the chip by setting nCE to low */
8122 +#define NAND_CTL_SETNCE        1
8123 +/* Deselect the chip by setting nCE to high */
8124 +#define NAND_CTL_CLRNCE                2
8125 +/* Select the command latch by setting CLE to high */
8126 +#define NAND_CTL_SETCLE                3
8127 +/* Deselect the command latch by setting CLE to low */
8128 +#define NAND_CTL_CLRCLE                4
8129 +/* Select the address latch by setting ALE to high */
8130 +#define NAND_CTL_SETALE                5
8131 +/* Deselect the address latch by setting ALE to low */
8132 +#define NAND_CTL_CLRALE                6
8133 +/* Set write protection by setting WP to high. Not used! */
8134 +#define NAND_CTL_SETWP         7
8135 +/* Clear write protection by setting WP to low. Not used! */
8136 +#define NAND_CTL_CLRWP         8
8137 +
8138 +/*
8139 + * Standard NAND flash commands
8140 + */
8141 +#define NAND_CMD_READ0         0
8142 +#define NAND_CMD_READ1         1
8143 +#define NAND_CMD_PAGEPROG      0x10
8144 +#define NAND_CMD_READOOB       0x50
8145 +#define NAND_CMD_ERASE1                0x60
8146 +#define NAND_CMD_STATUS                0x70
8147 +#define NAND_CMD_STATUS_MULTI  0x71
8148 +#define NAND_CMD_SEQIN         0x80
8149 +#define NAND_CMD_READID                0x90
8150 +#define NAND_CMD_ERASE2                0xd0
8151 +#define NAND_CMD_RESET         0xff
8152 +
8153 +/* Extended commands for large page devices */
8154 +#define NAND_CMD_READSTART     0x30
8155 +#define NAND_CMD_CACHEDPROG    0x15
8156 +
8157 +/* Extended commands for AG-AND device */
8158 +/*
8159 + * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
8160 + *       there is no way to distinguish that from NAND_CMD_READ0
8161 + *       until the remaining sequence of commands has been completed
8162 + *       so add a high order bit and mask it off in the command.
8163 + */
8164 +#define NAND_CMD_DEPLETE1      0x100
8165 +#define NAND_CMD_DEPLETE2      0x38
8166 +#define NAND_CMD_STATUS_MULTI  0x71
8167 +#define NAND_CMD_STATUS_ERROR  0x72
8168 +/* multi-bank error status (banks 0-3) */
8169 +#define NAND_CMD_STATUS_ERROR0 0x73
8170 +#define NAND_CMD_STATUS_ERROR1 0x74
8171 +#define NAND_CMD_STATUS_ERROR2 0x75
8172 +#define NAND_CMD_STATUS_ERROR3 0x76
8173 +#define NAND_CMD_STATUS_RESET  0x7f
8174 +#define NAND_CMD_STATUS_CLEAR  0xff
8175 +
8176 +/* Status bits */
8177 +#define NAND_STATUS_FAIL       0x01
8178 +#define NAND_STATUS_FAIL_N1    0x02
8179 +#define NAND_STATUS_TRUE_READY 0x20
8180 +#define NAND_STATUS_READY      0x40
8181 +#define NAND_STATUS_WP         0x80
8182 +
8183 +/*
8184 + * Constants for ECC_MODES
8185 + */
8186 +
8187 +/* No ECC. Usage is not recommended ! */
8188 +#define NAND_ECC_NONE          0
8189 +/* Software ECC 3 byte ECC per 256 Byte data */
8190 +#define NAND_ECC_SOFT          1
8191 +/* Hardware ECC 3 byte ECC per 256 Byte data */
8192 +#define NAND_ECC_HW3_256       2
8193 +/* Hardware ECC 3 byte ECC per 512 Byte data */
8194 +#define NAND_ECC_HW3_512       3
8195 +/* Hardware ECC 3 byte ECC per 512 Byte data */
8196 +#define NAND_ECC_HW6_512       4
8197 +/* Hardware ECC 8 byte ECC per 512 Byte data */
8198 +#define NAND_ECC_HW8_512       6
8199 +/* Hardware ECC 12 byte ECC per 2048 Byte data */
8200 +#define NAND_ECC_HW12_2048     7
8201 +
8202 +/*
8203 + * Constants for Hardware ECC
8204 + */
8205 +/* Reset Hardware ECC for read */
8206 +#define NAND_ECC_READ          0
8207 +/* Reset Hardware ECC for write */
8208 +#define NAND_ECC_WRITE         1
8209 +/* Enable Hardware ECC before syndrom is read back from flash */
8210 +#define NAND_ECC_READSYN       2
8211 +
8212 +/* Bit mask for flags passed to do_nand_read_ecc */
8213 +#define NAND_GET_DEVICE                0x80
8214 +
8215 +
8216 +/* Option constants for bizarre disfunctionality and real
8217 +*  features
8218 +*/
8219 +/* Chip can not auto increment pages */
8220 +#define NAND_NO_AUTOINCR       0x00000001
8221 +/* Buswitdh is 16 bit */
8222 +#define NAND_BUSWIDTH_16       0x00000002
8223 +/* Device supports partial programming without padding */
8224 +#define NAND_NO_PADDING                0x00000004
8225 +/* Chip has cache program function */
8226 +#define NAND_CACHEPRG          0x00000008
8227 +/* Chip has copy back function */
8228 +#define NAND_COPYBACK          0x00000010
8229 +/* AND Chip which has 4 banks and a confusing page / block
8230 + * assignment. See Renesas datasheet for further information */
8231 +#define NAND_IS_AND            0x00000020
8232 +/* Chip has a array of 4 pages which can be read without
8233 + * additional ready /busy waits */
8234 +#define NAND_4PAGE_ARRAY       0x00000040
8235 +/* Chip requires that BBT is periodically rewritten to prevent
8236 + * bits from adjacent blocks from 'leaking' in altering data.
8237 + * This happens with the Renesas AG-AND chips, possibly others.  */
8238 +#define BBT_AUTO_REFRESH       0x00000080
8239 +
8240 +/* Options valid for Samsung large page devices */
8241 +#define NAND_SAMSUNG_LP_OPTIONS \
8242 +       (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
8243 +
8244 +/* Macros to identify the above */
8245 +#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR))
8246 +#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
8247 +#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
8248 +#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
8249 +
8250 +/* Mask to zero out the chip options, which come from the id table */
8251 +#define NAND_CHIPOPTIONS_MSK   (0x0000ffff & ~NAND_NO_AUTOINCR)
8252 +
8253 +/* Non chip related options */
8254 +/* Use a flash based bad block table. This option is passed to the
8255 + * default bad block table function. */
8256 +#define NAND_USE_FLASH_BBT     0x00010000
8257 +/* The hw ecc generator provides a syndrome instead a ecc value on read
8258 + * This can only work if we have the ecc bytes directly behind the
8259 + * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
8260 +#define NAND_HWECC_SYNDROME    0x00020000
8261 +/* This option skips the bbt scan during initialization. */
8262 +#define NAND_SKIP_BBTSCAN      0x00040000
8263 +
8264 +/* Options set by nand scan */
8265 +/* Nand scan has allocated oob_buf */
8266 +#define NAND_OOBBUF_ALLOC      0x40000000
8267 +/* Nand scan has allocated data_buf */
8268 +#define NAND_DATABUF_ALLOC     0x80000000
8269 +
8270 +
8271 +/*
8272 + * nand_state_t - chip states
8273 + * Enumeration for NAND flash chip state
8274 + */
8275 +typedef enum {
8276 +       FL_READY,
8277 +       FL_READING,
8278 +       FL_WRITING,
8279 +       FL_ERASING,
8280 +       FL_SYNCING,
8281 +       FL_CACHEDPRG,
8282 +       FL_PM_SUSPENDED,
8283 +} nand_state_t;
8284 +
8285 +/* Keep gcc happy */
8286 +struct nand_chip;
8287 +
8288 +/**
8289 + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
8290 + * @lock:               protection lock
8291 + * @active:            the mtd device which holds the controller currently
8292 + * @wq:                        wait queue to sleep on if a NAND operation is in progress
8293 + *                      used instead of the per chip wait queue when a hw controller is available
8294 + */
8295 +#if NAND_HWECC_SUPPORT
8296 +struct nand_hw_control {
8297 +       spinlock_t       lock;
8298 +       struct nand_chip *active;
8299 +       wait_queue_head_t wq;
8300 +};
8301 +#endif
8302 +
8303 +/**
8304 + * struct nand_chip - NAND Private Flash Chip Data
8305 + * @IO_ADDR_R:         [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
8306 + * @IO_ADDR_W:         [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
8307 + * @read_byte:         [REPLACEABLE] read one byte from the chip
8308 + * @write_byte:                [REPLACEABLE] write one byte to the chip
8309 + * @read_word:         [REPLACEABLE] read one word from the chip
8310 + * @write_word:                [REPLACEABLE] write one word to the chip
8311 + * @write_buf:         [REPLACEABLE] write data from the buffer to the chip
8312 + * @read_buf:          [REPLACEABLE] read data from the chip into the buffer
8313 + * @verify_buf:                [REPLACEABLE] verify buffer contents against the chip data
8314 + * @select_chip:       [REPLACEABLE] select chip nr
8315 + * @block_bad:         [REPLACEABLE] check, if the block is bad
8316 + * @block_markbad:     [REPLACEABLE] mark the block bad
8317 + * @hwcontrol:         [BOARDSPECIFIC] hardwarespecific function for accesing control-lines
8318 + * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
8319 + *                     If set to NULL no access to ready/busy is available and the ready/busy information
8320 + *                     is read from the chip status register
8321 + * @cmdfunc:           [REPLACEABLE] hardwarespecific function for writing commands to the chip
8322 + * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on ready
8323 + * @calculate_ecc:     [REPLACEABLE] function for ecc calculation or readback from ecc hardware
8324 + * @correct_data:      [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw)
8325 + * @enable_hwecc:      [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only
8326 + *                     be provided if a hardware ECC is available
8327 + * @erase_cmd:         [INTERN] erase command write function, selectable due to AND support
8328 + * @scan_bbt:          [REPLACEABLE] function to scan bad block table
8329 + * @eccmode:           [BOARDSPECIFIC] mode of ecc, see defines
8330 + * @eccsize:           [INTERN] databytes used per ecc-calculation
8331 + * @eccbytes:          [INTERN] number of ecc bytes per ecc-calculation step
8332 + * @eccsteps:          [INTERN] number of ecc calculation steps per page
8333 + * @chip_delay:                [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
8334 + * @chip_lock:         [INTERN] spinlock used to protect access to this structure and the chip
8335 + * @wq:                        [INTERN] wait queue to sleep on if a NAND operation is in progress
8336 + * @state:             [INTERN] the current state of the NAND device
8337 + * @page_shift:                [INTERN] number of address bits in a page (column address bits)
8338 + * @phys_erase_shift:  [INTERN] number of address bits in a physical eraseblock
8339 + * @bbt_erase_shift:   [INTERN] number of address bits in a bbt entry
8340 + * @chip_shift:                [INTERN] number of address bits in one chip
8341 + * @data_buf:          [INTERN] internal buffer for one page + oob
8342 + * @oob_buf:           [INTERN] oob buffer for one eraseblock
8343 + * @oobdirty:          [INTERN] indicates that oob_buf must be reinitialized
8344 + * @data_poi:          [INTERN] pointer to a data buffer
8345 + * @options:           [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
8346 + *                     special functionality. See the defines for further explanation
8347 + * @badblockpos:       [INTERN] position of the bad block marker in the oob area
8348 + * @numchips:          [INTERN] number of physical chips
8349 + * @chipsize:          [INTERN] the size of one chip for multichip arrays
8350 + * @pagemask:          [INTERN] page number mask = number of (pages / chip) - 1
8351 + * @pagebuf:           [INTERN] holds the pagenumber which is currently in data_buf
8352 + * @autooob:           [REPLACEABLE] the default (auto)placement scheme
8353 + * @bbt:               [INTERN] bad block table pointer
8354 + * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash lookup
8355 + * @bbt_md:            [REPLACEABLE] bad block table mirror descriptor
8356 + * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial bad block scan
8357 + * @controller:                [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
8358 + * @priv:              [OPTIONAL] pointer to private chip date
8359 + * @errstat:           [OPTIONAL] hardware specific function to perform additional error status checks
8360 + *                     (determine if errors are correctable)
8361 + */
8362 +
8363 +struct nand_chip {
8364 +       void  __iomem   *IO_ADDR_R;
8365 +       void  __iomem   *IO_ADDR_W;
8366 +
8367 +       u_char          (*read_byte)(struct mtd_info *mtd);
8368 +       void            (*write_byte)(struct mtd_info *mtd, u_char byte);
8369 +       u16             (*read_word)(struct mtd_info *mtd);
8370 +       void            (*write_word)(struct mtd_info *mtd, u16 word);
8371 +
8372 +       void            (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
8373 +       void            (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
8374 +       int             (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
8375 +       void            (*select_chip)(struct mtd_info *mtd, int chip);
8376 +       int             (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
8377 +       int             (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
8378 +       void            (*hwcontrol)(struct mtd_info *mtd, int cmd);
8379 +       int             (*dev_ready)(struct mtd_info *mtd);
8380 +       void            (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
8381 +       int             (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
8382 +       int             (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
8383 +       int             (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
8384 +       void            (*enable_hwecc)(struct mtd_info *mtd, int mode);
8385 +       void            (*erase_cmd)(struct mtd_info *mtd, int page);
8386 +       int             (*scan_bbt)(struct mtd_info *mtd);
8387 +       int             eccmode;
8388 +       int             eccsize;
8389 +       int             eccbytes;
8390 +       int             eccsteps;
8391 +       int             chip_delay;
8392 +#if 0 /* no spinlocks or wait queues in boot loader */
8393 +       spinlock_t      chip_lock;
8394 +       wait_queue_head_t wq;
8395 +#endif
8396 +       nand_state_t    state;
8397 +       int             page_shift;
8398 +       int             phys_erase_shift;
8399 +       int             bbt_erase_shift;
8400 +       int             chip_shift;
8401 +       u_char          *data_buf;
8402 +       u_char          *oob_buf;
8403 +       int             oobdirty;
8404 +       u_char          *data_poi;
8405 +       unsigned int    options;
8406 +       int             badblockpos;
8407 +       int             numchips;
8408 +       unsigned long   chipsize;
8409 +       int             pagemask;
8410 +       int             pagebuf;
8411 +       struct nand_oobinfo     *autooob;
8412 +       uint8_t         *bbt;
8413 +       struct nand_bbt_descr   *bbt_td;
8414 +       struct nand_bbt_descr   *bbt_md;
8415 +       struct nand_bbt_descr   *badblock_pattern;
8416 +       struct nand_hw_control  *controller;
8417 +       void            *priv;
8418 +       int             (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
8419 +};
8420 +
8421 +/*
8422 + * NAND Flash Manufacturer ID Codes
8423 + */
8424 +#define NAND_MFR_TOSHIBA       0x98
8425 +#define NAND_MFR_SAMSUNG       0xec
8426 +#define NAND_MFR_FUJITSU       0x04
8427 +#define NAND_MFR_NATIONAL      0x8f
8428 +#define NAND_MFR_RENESAS       0x07
8429 +#define NAND_MFR_STMICRO       0x20
8430 +#define NAND_MFR_HYNIX          0xad
8431 +
8432 +/**
8433 + * struct nand_flash_dev - NAND Flash Device ID Structure
8434 + *
8435 + * @name:      Identify the device type
8436 + * @id:        device ID code
8437 + * @pagesize:          Pagesize in bytes. Either 256 or 512 or 0
8438 + *             If the pagesize is 0, then the real pagesize
8439 + *             and the eraseize are determined from the
8440 + *             extended id bytes in the chip
8441 + * @erasesize:         Size of an erase block in the flash device.
8442 + * @chipsize:          Total chipsize in Mega Bytes
8443 + * @options:   Bitfield to store chip relevant options
8444 + */
8445 +struct nand_flash_dev {
8446 +       char *name;
8447 +       int id;
8448 +       unsigned long pagesize;
8449 +       unsigned long chipsize;
8450 +       unsigned long erasesize;
8451 +       unsigned long options;
8452 +};
8453 +
8454 +/**
8455 + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
8456 + * @name:      Manufacturer name
8457 + * @id:        manufacturer ID code of device.
8458 +*/
8459 +struct nand_manufacturers {
8460 +       int id;
8461 +       char * name;
8462 +};
8463 +
8464 +extern struct nand_flash_dev nand_flash_ids[];
8465 +extern struct nand_manufacturers nand_manuf_ids[];
8466 +
8467 +/**
8468 + * struct nand_bbt_descr - bad block table descriptor
8469 + * @options:   options for this descriptor
8470 + * @pages:     the page(s) where we find the bbt, used with option BBT_ABSPAGE
8471 + *             when bbt is searched, then we store the found bbts pages here.
8472 + *             Its an array and supports up to 8 chips now
8473 + * @offs:      offset of the pattern in the oob area of the page
8474 + * @veroffs:   offset of the bbt version counter in the oob are of the page
8475 + * @version:   version read from the bbt page during scan
8476 + * @len:       length of the pattern, if 0 no pattern check is performed
8477 + * @maxblocks: maximum number of blocks to search for a bbt. This number of
8478 + *             blocks is reserved at the end of the device where the tables are
8479 + *             written.
8480 + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
8481 + *              bad) block in the stored bbt
8482 + * @pattern:   pattern to identify bad block table or factory marked good /
8483 + *             bad blocks, can be NULL, if len = 0
8484 + *
8485 + * Descriptor for the bad block table marker and the descriptor for the
8486 + * pattern which identifies good and bad blocks. The assumption is made
8487 + * that the pattern and the version count are always located in the oob area
8488 + * of the first block.
8489 + */
8490 +struct nand_bbt_descr {
8491 +       int     options;
8492 +       int     pages[NAND_MAX_CHIPS];
8493 +       int     offs;
8494 +       int     veroffs;
8495 +       uint8_t version[NAND_MAX_CHIPS];
8496 +       int     len;
8497 +       int     maxblocks;
8498 +       int     reserved_block_code;
8499 +       uint8_t *pattern;
8500 +};
8501 +
8502 +/* Options for the bad block table descriptors */
8503 +
8504 +/* The number of bits used per block in the bbt on the device */
8505 +#define NAND_BBT_NRBITS_MSK    0x0000000F
8506 +#define NAND_BBT_1BIT          0x00000001
8507 +#define NAND_BBT_2BIT          0x00000002
8508 +#define NAND_BBT_4BIT          0x00000004
8509 +#define NAND_BBT_8BIT          0x00000008
8510 +/* The bad block table is in the last good block of the device */
8511 +#define        NAND_BBT_LASTBLOCK      0x00000010
8512 +/* The bbt is at the given page, else we must scan for the bbt */
8513 +#define NAND_BBT_ABSPAGE       0x00000020
8514 +/* The bbt is at the given page, else we must scan for the bbt */
8515 +#define NAND_BBT_SEARCH                0x00000040
8516 +/* bbt is stored per chip on multichip devices */
8517 +#define NAND_BBT_PERCHIP       0x00000080
8518 +/* bbt has a version counter at offset veroffs */
8519 +#define NAND_BBT_VERSION       0x00000100
8520 +/* Create a bbt if none axists */
8521 +#define NAND_BBT_CREATE                0x00000200
8522 +/* Search good / bad pattern through all pages of a block */
8523 +#define NAND_BBT_SCANALLPAGES  0x00000400
8524 +/* Scan block empty during good / bad block scan */
8525 +#define NAND_BBT_SCANEMPTY     0x00000800
8526 +/* Write bbt if neccecary */
8527 +#define NAND_BBT_WRITE         0x00001000
8528 +/* Read and write back block contents when writing bbt */
8529 +#define NAND_BBT_SAVECONTENT   0x00002000
8530 +/* Search good / bad pattern on the first and the second page */
8531 +#define NAND_BBT_SCAN2NDPAGE   0x00004000
8532 +
8533 +/* The maximum number of blocks to scan for a bbt */
8534 +#define NAND_BBT_SCAN_MAXBLOCKS        4
8535 +
8536 +extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd);
8537 +extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs);
8538 +extern int nand_default_bbt (struct mtd_info *mtd);
8539 +extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt);
8540 +extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt);
8541 +extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
8542 +                             size_t * retlen, u_char * buf, u_char * oob_buf,
8543 +                             struct nand_oobinfo *oobsel, int flags);
8544 +
8545 +/*
8546 +* Constants for oob configuration
8547 +*/
8548 +#define NAND_SMALL_BADBLOCK_POS                5
8549 +#define NAND_LARGE_BADBLOCK_POS                0
8550 +
8551 +#endif /* __LINUX_MTD_NAND_H */
8552 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_base.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_base.c
8553 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_base.c       1970-01-01 01:00:00.000000000 +0100
8554 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_base.c       2006-11-10 09:55:58.000000000 +0100
8555 @@ -0,0 +1,2910 @@
8556 +/*
8557 + * Snitched from  drivers/mtd/nand_base.c
8558 + * Modified to run outside Linux.
8559 + * #if 0'd to remove non-essential functionality
8560 + *
8561 + *  Overview:
8562 + *   This is the generic MTD driver for NAND flash devices. It should be
8563 + *   capable of working with almost all NAND chips currently available.
8564 + *   Basic support for AG-AND chips is provided.
8565 + *
8566 + *     Additional technical information is available on
8567 + *     http://www.linux-mtd.infradead.org/tech/nand.html
8568 + *
8569 + *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8570 + *               2002 Thomas Gleixner (tglx@linutronix.de)
8571 + *
8572 + *  02-08-2004  tglx: support for strange chips, which cannot auto increment
8573 + *             pages on read / read_oob
8574 + *
8575 + *  03-17-2004  tglx: Check ready before auto increment check. Simon Bayes
8576 + *             pointed this out, as he marked an auto increment capable chip
8577 + *             as NOAUTOINCR in the board driver.
8578 + *             Make reads over block boundaries work too
8579 + *
8580 + *  04-14-2004 tglx: first working version for 2k page size chips
8581 + *
8582 + *  05-19-2004  tglx: Basic support for Renesas AG-AND chips
8583 + *
8584 + *  09-24-2004  tglx: add support for hardware controllers (e.g. ECC) shared
8585 + *             among multiple independend devices. Suggestions and initial patch
8586 + *             from Ben Dooks <ben-mtd@fluff.org>
8587 + *
8588 + *  12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
8589 + *             Basically, any block not rewritten may lose data when surrounding blocks
8590 + *             are rewritten many times.  JFFS2 ensures this doesn't happen for blocks
8591 + *             it uses, but the Bad Block Table(s) may not be rewritten.  To ensure they
8592 + *             do not lose data, force them to be rewritten when some of the surrounding
8593 + *             blocks are erased.  Rather than tracking a specific nearby block (which
8594 + *             could itself go bad), use a page address 'mask' to select several blocks
8595 + *             in the same area, and rewrite the BBT when any of them are erased.
8596 + *
8597 + *  01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
8598 + *             AG-AND chips.  If there was a sudden loss of power during an erase operation,
8599 + *             a "device recovery" operation must be performed when power is restored
8600 + *             to ensure correct operation.
8601 + *
8602 + *  01-20-2005 dmarlin: added support for optional hardware specific callback routine to
8603 + *             perform extra error status checks on erase and write failures.  This required
8604 + *             adding a wrapper function for nand_read_ecc.
8605 + *
8606 + * 08-20-2005  vwool: suspend/resume added
8607 + *
8608 + * Credits:
8609 + *     David Woodhouse for adding multichip support
8610 + *
8611 + *     Aleph One Ltd. and Toby Churchill Ltd. for supporting the
8612 + *     rework for 2K page size chips
8613 + *
8614 + * TODO:
8615 + *     Enable cached programming for 2k page size chips
8616 + *     Check, if mtd->ecctype should be set to MTD_ECC_HW
8617 + *     if we have HW ecc support.
8618 + *     The AG-AND chips have nice features for speed improvement,
8619 + *     which are not supported yet. Read / program 4 pages in one go.
8620 + *
8621 + * $Id: nand_base.c,v 1.11 2006/11/10 08:55:58 ricardw Exp $
8622 + *
8623 + * This program is free software; you can redistribute it and/or modify
8624 + * it under the terms of the GNU General Public License version 2 as
8625 + * published by the Free Software Foundation.
8626 + *
8627 + */
8628 +
8629 +#include <linux/types.h>
8630 +#include <linux/delay.h>
8631 +#include <linux/errno.h>
8632 +#if 0
8633 +#include <linux/sched.h>
8634 +#include <linux/slab.h>
8635 +#endif
8636 +
8637 +#include "mtd.h"
8638 +#include "nand.h"
8639 +#include "nand_ecc.h"
8640 +
8641 +#if 0
8642 +#include <linux/mtd/compatmac.h>
8643 +#include <linux/interrupt.h>
8644 +#include <linux/bitops.h>
8645 +#include <asm/io.h>
8646 +#endif
8647 +
8648 +#ifdef CONFIG_MTD_PARTITIONS
8649 +#include <linux/mtd/partitions.h>
8650 +
8651 +#endif
8652 +
8653 +#include "lib.h"
8654 +
8655 +#define GPIO_SYNC 0
8656 +
8657 +#undef DEBUG /* from mtd.h */
8658 +#define DEBUG(n, args...) do { } while(0)
8659 +
8660 +#define D(x) 
8661 +
8662 +/* Define default oob placement schemes for large and small page devices */
8663 +static struct nand_oobinfo nand_oob_8 = {
8664 +       .useecc = MTD_NANDECC_AUTOPLACE,
8665 +       .eccbytes = 3,
8666 +       .eccpos = {0, 1, 2},
8667 +       .oobfree = { {3, 2}, {6, 2} }
8668 +};
8669 +
8670 +static struct nand_oobinfo nand_oob_16 = {
8671 +       .useecc = MTD_NANDECC_AUTOPLACE,
8672 +       .eccbytes = 6,
8673 +       .eccpos = {0, 1, 2, 3, 6, 7},
8674 +       .oobfree = { {8, 8} }
8675 +};
8676 +
8677 +static struct nand_oobinfo nand_oob_64 = {
8678 +       .useecc = MTD_NANDECC_AUTOPLACE,
8679 +       .eccbytes = 24,
8680 +       .eccpos = {
8681 +               40, 41, 42, 43, 44, 45, 46, 47,
8682 +               48, 49, 50, 51, 52, 53, 54, 55,
8683 +               56, 57, 58, 59, 60, 61, 62, 63},
8684 +       .oobfree = { {2, 38} }
8685 +};
8686 +
8687 +/* This is used for padding purposes in nand_write_oob */
8688 +#if NAND_WRITE_SUPPORT
8689 +static u_char ffchars[] = {
8690 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8691 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8692 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8693 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8694 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8695 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8696 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8697 +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8698 +};
8699 +#endif
8700 +
8701 +/*
8702 + * NAND low-level MTD interface functions
8703 + */
8704 +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
8705 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
8706 +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
8707 +
8708 +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
8709 +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
8710 +                         size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
8711 +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
8712 +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
8713 +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
8714 +                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
8715 +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
8716 +#if NAND_KVEC_SUPPORT
8717 +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
8718 +                       unsigned long count, loff_t to, size_t * retlen);
8719 +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
8720 +                       unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
8721 +#endif
8722 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
8723 +static void nand_sync (struct mtd_info *mtd);
8724 +
8725 +/* Some internal functions */
8726 +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
8727 +               struct nand_oobinfo *oobsel, int mode);
8728 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
8729 +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
8730 +       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
8731 +#else
8732 +#define nand_verify_pages(...) (0)
8733 +#endif
8734 +
8735 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
8736 +
8737 +/**
8738 + * nand_release_device - [GENERIC] release chip
8739 + * @mtd:       MTD device structure
8740 + *
8741 + * Deselect, release chip lock and wake up anyone waiting on the device
8742 + */
8743 +static void nand_release_device (struct mtd_info *mtd)
8744 +{
8745 +       struct nand_chip *this = mtd->priv;
8746 +
8747 +       /* De-select the NAND device */
8748 +       this->select_chip(mtd, -1);
8749 +#if 0
8750 +
8751 +       if (this->controller) {
8752 +               /* Release the controller and the chip */
8753 +               spin_lock(&this->controller->lock);
8754 +               this->controller->active = NULL;
8755 +               this->state = FL_READY;
8756 +               wake_up(&this->controller->wq);
8757 +               spin_unlock(&this->controller->lock);
8758 +       } else {
8759 +               /* Release the chip */
8760 +               spin_lock(&this->chip_lock);
8761 +               this->state = FL_READY;
8762 +               wake_up(&this->wq);
8763 +               spin_unlock(&this->chip_lock);
8764 +       }
8765 +#endif
8766 +}
8767 +
8768 +/**
8769 + * nand_read_byte - [DEFAULT] read one byte from the chip
8770 + * @mtd:       MTD device structure
8771 + *
8772 + * Default read function for 8bit buswith
8773 + */
8774 +static u_char nand_read_byte(struct mtd_info *mtd)
8775 +{
8776 +       struct nand_chip *this = mtd->priv;
8777 +       return readb(this->IO_ADDR_R);
8778 +}
8779 +
8780 +/**
8781 + * nand_write_byte - [DEFAULT] write one byte to the chip
8782 + * @mtd:       MTD device structure
8783 + * @byte:      pointer to data byte to write
8784 + *
8785 + * Default write function for 8it buswith
8786 + */
8787 +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
8788 +{
8789 +       struct nand_chip *this = mtd->priv;
8790 +       writeb(byte, this->IO_ADDR_W);
8791 +
8792 +#if GPIO_SYNC
8793 +       /* Bus sync: Read from address we just wrote.
8794 +        * This generates no signal to the NAND flash, since only chip 
8795 +        * select lines are pulled out to the chip, and read is not 
8796 +        * gated with chip select for the write  area.
8797 +        * Turns out this is (probably) the wrong way to do it; the
8798 +        * right way is to set up suitable wait states in the kernel
8799 +        * config (CONFIG_ETRAX_MEM_GRP3_CONFIG).
8800 +        */
8801 +       (void) readb(this->IO_ADDR_W); /* that's right, IO_ADDR_W */
8802 +#endif
8803 +}
8804 +
8805 +/**
8806 + * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
8807 + * @mtd:       MTD device structure
8808 + *
8809 + * Default read function for 16bit buswith with
8810 + * endianess conversion
8811 + */
8812 +static u_char nand_read_byte16(struct mtd_info *mtd)
8813 +{
8814 +       struct nand_chip *this = mtd->priv;
8815 +       return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
8816 +}
8817 +
8818 +/**
8819 + * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
8820 + * @mtd:       MTD device structure
8821 + * @byte:      pointer to data byte to write
8822 + *
8823 + * Default write function for 16bit buswith with
8824 + * endianess conversion
8825 + */
8826 +static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
8827 +{
8828 +       struct nand_chip *this = mtd->priv;
8829 +       writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
8830 +}
8831 +
8832 +/**
8833 + * nand_read_word - [DEFAULT] read one word from the chip
8834 + * @mtd:       MTD device structure
8835 + *
8836 + * Default read function for 16bit buswith without
8837 + * endianess conversion
8838 + */
8839 +static u16 nand_read_word(struct mtd_info *mtd)
8840 +{
8841 +       struct nand_chip *this = mtd->priv;
8842 +       return readw(this->IO_ADDR_R);
8843 +}
8844 +
8845 +/**
8846 + * nand_write_word - [DEFAULT] write one word to the chip
8847 + * @mtd:       MTD device structure
8848 + * @word:      data word to write
8849 + *
8850 + * Default write function for 16bit buswith without
8851 + * endianess conversion
8852 + */
8853 +static void nand_write_word(struct mtd_info *mtd, u16 word)
8854 +{
8855 +       struct nand_chip *this = mtd->priv;
8856 +       writew(word, this->IO_ADDR_W);
8857 +}
8858 +
8859 +/**
8860 + * nand_select_chip - [DEFAULT] control CE line
8861 + * @mtd:       MTD device structure
8862 + * @chip:      chipnumber to select, -1 for deselect
8863 + *
8864 + * Default select function for 1 chip devices.
8865 + */
8866 +static void nand_select_chip(struct mtd_info *mtd, int chip)
8867 +{
8868 +       struct nand_chip *this = mtd->priv;
8869 +       switch(chip) {
8870 +       case -1:
8871 +               this->hwcontrol(mtd, NAND_CTL_CLRNCE);
8872 +               break;
8873 +       case 0:
8874 +               this->hwcontrol(mtd, NAND_CTL_SETNCE);
8875 +               break;
8876 +
8877 +       default:
8878 +               BUG();
8879 +       }
8880 +}
8881 +
8882 +/**
8883 + * nand_write_buf - [DEFAULT] write buffer to chip
8884 + * @mtd:       MTD device structure
8885 + * @buf:       data buffer
8886 + * @len:       number of bytes to write
8887 + *
8888 + * Default write function for 8bit buswith
8889 + */
8890 +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
8891 +{
8892 +       int i;
8893 +       struct nand_chip *this = mtd->priv;
8894 +
8895 +       for (i=0; i<len; i++)
8896 +               writeb(buf[i], this->IO_ADDR_W);
8897 +}
8898 +
8899 +/**
8900 + * nand_read_buf - [DEFAULT] read chip data into buffer
8901 + * @mtd:       MTD device structure
8902 + * @buf:       buffer to store date
8903 + * @len:       number of bytes to read
8904 + *
8905 + * Default read function for 8bit buswith
8906 + */
8907 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
8908 +{
8909 +       int i;
8910 +       struct nand_chip *this = mtd->priv;
8911 +
8912 +       for (i=0; i<len; i++)
8913 +               buf[i] = readb(this->IO_ADDR_R);
8914 +}
8915 +
8916 +/**
8917 + * nand_verify_buf - [DEFAULT] Verify chip data against buffer
8918 + * @mtd:       MTD device structure
8919 + * @buf:       buffer containing the data to compare
8920 + * @len:       number of bytes to compare
8921 + *
8922 + * Default verify function for 8bit buswith
8923 + */
8924 +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
8925 +{
8926 +       int i;
8927 +       struct nand_chip *this = mtd->priv;
8928 +
8929 +       for (i=0; i<len; i++)
8930 +               if (buf[i] != readb(this->IO_ADDR_R))
8931 +                       return -EFAULT;
8932 +
8933 +       return 0;
8934 +}
8935 +
8936 +/**
8937 + * nand_write_buf16 - [DEFAULT] write buffer to chip
8938 + * @mtd:       MTD device structure
8939 + * @buf:       data buffer
8940 + * @len:       number of bytes to write
8941 + *
8942 + * Default write function for 16bit buswith
8943 + */
8944 +static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8945 +{
8946 +       int i;
8947 +       struct nand_chip *this = mtd->priv;
8948 +       u16 *p = (u16 *) buf;
8949 +       len >>= 1;
8950 +
8951 +       for (i=0; i<len; i++)
8952 +               writew(p[i], this->IO_ADDR_W);
8953 +
8954 +}
8955 +
8956 +/**
8957 + * nand_read_buf16 - [DEFAULT] read chip data into buffer
8958 + * @mtd:       MTD device structure
8959 + * @buf:       buffer to store date
8960 + * @len:       number of bytes to read
8961 + *
8962 + * Default read function for 16bit buswith
8963 + */
8964 +static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
8965 +{
8966 +       int i;
8967 +       struct nand_chip *this = mtd->priv;
8968 +       u16 *p = (u16 *) buf;
8969 +       len >>= 1;
8970 +
8971 +       for (i=0; i<len; i++)
8972 +               p[i] = readw(this->IO_ADDR_R);
8973 +}
8974 +
8975 +/**
8976 + * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
8977 + * @mtd:       MTD device structure
8978 + * @buf:       buffer containing the data to compare
8979 + * @len:       number of bytes to compare
8980 + *
8981 + * Default verify function for 16bit buswith
8982 + */
8983 +static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8984 +{
8985 +       int i;
8986 +       struct nand_chip *this = mtd->priv;
8987 +       u16 *p = (u16 *) buf;
8988 +       len >>= 1;
8989 +
8990 +       for (i=0; i<len; i++)
8991 +               if (p[i] != readw(this->IO_ADDR_R))
8992 +                       return -EFAULT;
8993 +
8994 +       return 0;
8995 +}
8996 +
8997 +/**
8998 + * nand_block_bad - [DEFAULT] Read bad block marker from the chip
8999 + * @mtd:       MTD device structure
9000 + * @ofs:       offset from device start
9001 + * @getchip:   0, if the chip is already selected
9002 + *
9003 + * Check, if the block is bad.
9004 + */
9005 +static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
9006 +{
9007 +       int page, chipnr, res = 0;
9008 +       struct nand_chip *this = mtd->priv;
9009 +       u16 bad;
9010 +
9011 +       if (getchip) {
9012 +               page = (int)(ofs >> this->page_shift);
9013 +               chipnr = (int)(ofs >> this->chip_shift);
9014 +
9015 +               /* Grab the lock and see if the device is available */
9016 +               nand_get_device (this, mtd, FL_READING);
9017 +
9018 +               /* Select the NAND device */
9019 +               this->select_chip(mtd, chipnr);
9020 +       } else
9021 +               page = (int) ofs;
9022 +
9023 +       if (this->options & NAND_BUSWIDTH_16) {
9024 +               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
9025 +               bad = cpu_to_le16(this->read_word(mtd));
9026 +               if (this->badblockpos & 0x1)
9027 +                       bad >>= 8;
9028 +               if ((bad & 0xFF) != 0xff)
9029 +                       res = 1;
9030 +       } else {
9031 +               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
9032 +               if (this->read_byte(mtd) != 0xff)
9033 +                       res = 1;
9034 +       }
9035 +
9036 +       if (getchip) {
9037 +               /* Deselect and wake up anyone waiting on the device */
9038 +               nand_release_device(mtd);
9039 +       }
9040 +
9041 +       return res;
9042 +}
9043 +
9044 +/**
9045 + * nand_default_block_markbad - [DEFAULT] mark a block bad
9046 + * @mtd:       MTD device structure
9047 + * @ofs:       offset from device start
9048 + *
9049 + * This is the default implementation, which can be overridden by
9050 + * a hardware specific driver.
9051 +*/
9052 +#if NAND_WRITE_SUPPORT
9053 +static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
9054 +{
9055 +       struct nand_chip *this = mtd->priv;
9056 +       u_char buf[2] = {0, 0};
9057 +       size_t  retlen;
9058 +       int block;
9059 +
9060 +       /* Get block number */
9061 +       block = ((int) ofs) >> this->bbt_erase_shift;
9062 +       if (this->bbt)
9063 +               this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
9064 +
9065 +#if NAND_BBT_SUPPORT
9066 +       /* Do we have a flash based bad block table ? */
9067 +       if (this->options & NAND_USE_FLASH_BBT)
9068 +               return nand_update_bbt (mtd, ofs);
9069 +#endif
9070 +
9071 +       /* We write two bytes, so we dont have to mess with 16 bit access */
9072 +       ofs += mtd->oobsize + (this->badblockpos & ~0x01);
9073 +       return nand_write_oob (mtd, ofs , 2, &retlen, buf);
9074 +}
9075 +#endif
9076 +
9077 +/**
9078 + * nand_check_wp - [GENERIC] check if the chip is write protected
9079 + * @mtd:       MTD device structure
9080 + * Check, if the device is write protected
9081 + *
9082 + * The function expects, that the device is already selected
9083 + */
9084 +#if NAND_WRITE_SUPPORT
9085 +static int nand_check_wp (struct mtd_info *mtd)
9086 +{
9087 +       struct nand_chip *this = mtd->priv;
9088 +       /* Check the WP bit */
9089 +       this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
9090 +       return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
9091 +}
9092 +#endif
9093 +
9094 +/**
9095 + * nand_block_checkbad - [GENERIC] Check if a block is marked bad
9096 + * @mtd:       MTD device structure
9097 + * @ofs:       offset from device start
9098 + * @getchip:   0, if the chip is already selected
9099 + * @allowbbt:  1, if its allowed to access the bbt area
9100 + *
9101 + * Check, if the block is bad. Either by reading the bad block table or
9102 + * calling of the scan function.
9103 + */
9104 +static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
9105 +{
9106 +       struct nand_chip *this = mtd->priv;
9107 +
9108 +       if (!this->bbt)
9109 +               return this->block_bad(mtd, ofs, getchip);
9110 +
9111 +#if NAND_BBT_SUPPORT
9112 +       /* Return info from the table */
9113 +       return nand_isbad_bbt (mtd, ofs, allowbbt);
9114 +#endif
9115 +       BUG(); /* should not happen */
9116 +}
9117 +
9118 +/*
9119 + * Wait for the ready pin, after a command
9120 + * The timeout is catched later.
9121 + */
9122 +static void nand_wait_ready(struct mtd_info *mtd)
9123 +{
9124 +       struct nand_chip *this = mtd->priv;
9125 +#if 0
9126 +       unsigned long   timeo = jiffies + 2;
9127 +#endif
9128 +
9129 +       /* wait until command is processed or timeout occures */
9130 +       do {
9131 +               if (this->dev_ready(mtd))
9132 +                       return;
9133 +#if 0
9134 +               touch_softlockup_watchdog();
9135 +       } while (time_before(jiffies, timeo));
9136 +#endif
9137 +       } while (1);
9138 +}
9139 +
9140 +/**
9141 + * nand_command - [DEFAULT] Send command to NAND device
9142 + * @mtd:       MTD device structure
9143 + * @command:   the command to be sent
9144 + * @column:    the column address for this command, -1 if none
9145 + * @page_addr: the page address for this command, -1 if none
9146 + *
9147 + * Send command to NAND device. This function is used for small page
9148 + * devices (256/512 Bytes per page)
9149 + */
9150 +static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9151 +{
9152 +       register struct nand_chip *this = mtd->priv;
9153 +
9154 +       /* Begin command latch cycle */
9155 +       this->hwcontrol(mtd, NAND_CTL_SETCLE);
9156 +       /*
9157 +        * Write out the command to the device.
9158 +        */
9159 +       if (command == NAND_CMD_SEQIN) {
9160 +               int readcmd;
9161 +
9162 +               if (column >= mtd->oobblock) {
9163 +                       /* OOB area */
9164 +                       column -= mtd->oobblock;
9165 +                       readcmd = NAND_CMD_READOOB;
9166 +               } else if (column < 256) {
9167 +                       /* First 256 bytes --> READ0 */
9168 +                       readcmd = NAND_CMD_READ0;
9169 +               } else {
9170 +                       column -= 256;
9171 +                       readcmd = NAND_CMD_READ1;
9172 +               }
9173 +               this->write_byte(mtd, readcmd);
9174 +       }
9175 +       this->write_byte(mtd, command);
9176 +
9177 +       /* Set ALE and clear CLE to start address cycle */
9178 +       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9179 +
9180 +       if (column != -1 || page_addr != -1) {
9181 +               this->hwcontrol(mtd, NAND_CTL_SETALE);
9182 +
9183 +               /* Serially input address */
9184 +               if (column != -1) {
9185 +                       /* Adjust columns for 16 bit buswidth */
9186 +                       if (this->options & NAND_BUSWIDTH_16)
9187 +                               column >>= 1;
9188 +                       this->write_byte(mtd, column);
9189 +               }
9190 +               if (page_addr != -1) {
9191 +                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
9192 +                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
9193 +                       /* One more address cycle for devices > 32MiB */
9194 +                       if (this->chipsize > (32 << 20))
9195 +                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
9196 +               }
9197 +               /* Latch in address */
9198 +               this->hwcontrol(mtd, NAND_CTL_CLRALE);
9199 +       }
9200 +
9201 +       /*
9202 +        * program and erase have their own busy handlers
9203 +        * status and sequential in needs no delay
9204 +       */
9205 +       switch (command) {
9206 +
9207 +       case NAND_CMD_PAGEPROG:
9208 +       case NAND_CMD_ERASE1:
9209 +       case NAND_CMD_ERASE2:
9210 +       case NAND_CMD_SEQIN:
9211 +       case NAND_CMD_STATUS:
9212 +               return;
9213 +
9214 +       case NAND_CMD_RESET:
9215 +               if (this->dev_ready)
9216 +                       break;
9217 +               udelay(this->chip_delay);
9218 +               this->hwcontrol(mtd, NAND_CTL_SETCLE);
9219 +               this->write_byte(mtd, NAND_CMD_STATUS);
9220 +               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9221 +               while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
9222 +               return;
9223 +
9224 +       /* This applies to read commands */
9225 +       default:
9226 +               /*
9227 +                * If we don't have access to the busy pin, we apply the given
9228 +                * command delay
9229 +               */
9230 +               if (!this->dev_ready) {
9231 +                       udelay (this->chip_delay);
9232 +                       return;
9233 +               }
9234 +       }
9235 +       /* Apply this short delay always to ensure that we do wait tWB in
9236 +        * any case on any machine. */
9237 +       ndelay (100);
9238 +
9239 +       nand_wait_ready(mtd);
9240 +}
9241 +
9242 +/**
9243 + * nand_command_lp - [DEFAULT] Send command to NAND large page device
9244 + * @mtd:       MTD device structure
9245 + * @command:   the command to be sent
9246 + * @column:    the column address for this command, -1 if none
9247 + * @page_addr: the page address for this command, -1 if none
9248 + *
9249 + * Send command to NAND device. This is the version for the new large page devices
9250 + * We dont have the seperate regions as we have in the small page devices.
9251 + * We must emulate NAND_CMD_READOOB to keep the code compatible.
9252 + *
9253 + */
9254 +static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9255 +{
9256 +       register struct nand_chip *this = mtd->priv;
9257 +
9258 +       /* Emulate NAND_CMD_READOOB */
9259 +       if (command == NAND_CMD_READOOB) {
9260 +               column += mtd->oobblock;
9261 +               command = NAND_CMD_READ0;
9262 +       }
9263 +
9264 +
9265 +       /* Begin command latch cycle */
9266 +       this->hwcontrol(mtd, NAND_CTL_SETCLE);
9267 +       /* Write out the command to the device. */
9268 +       this->write_byte(mtd, (command & 0xff));
9269 +       /* End command latch cycle */
9270 +       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9271 +
9272 +       if (column != -1 || page_addr != -1) {
9273 +               this->hwcontrol(mtd, NAND_CTL_SETALE);
9274 +
9275 +               /* Serially input address */
9276 +               if (column != -1) {
9277 +                       /* Adjust columns for 16 bit buswidth */
9278 +                       if (this->options & NAND_BUSWIDTH_16)
9279 +                               column >>= 1;
9280 +                       this->write_byte(mtd, column & 0xff);
9281 +                       this->write_byte(mtd, column >> 8);
9282 +               }
9283 +               if (page_addr != -1) {
9284 +                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
9285 +                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
9286 +                       /* One more address cycle for devices > 128MiB */
9287 +                       if (this->chipsize > (128 << 20))
9288 +                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
9289 +               }
9290 +               /* Latch in address */
9291 +               this->hwcontrol(mtd, NAND_CTL_CLRALE);
9292 +       }
9293 +
9294 +       /*
9295 +        * program and erase have their own busy handlers
9296 +        * status, sequential in, and deplete1 need no delay
9297 +        */
9298 +       switch (command) {
9299 +
9300 +       case NAND_CMD_CACHEDPROG:
9301 +       case NAND_CMD_PAGEPROG:
9302 +       case NAND_CMD_ERASE1:
9303 +       case NAND_CMD_ERASE2:
9304 +       case NAND_CMD_SEQIN:
9305 +       case NAND_CMD_STATUS:
9306 +       case NAND_CMD_DEPLETE1:
9307 +               return;
9308 +
9309 +       /*
9310 +        * read error status commands require only a short delay
9311 +        */
9312 +       case NAND_CMD_STATUS_ERROR:
9313 +       case NAND_CMD_STATUS_ERROR0:
9314 +       case NAND_CMD_STATUS_ERROR1:
9315 +       case NAND_CMD_STATUS_ERROR2:
9316 +       case NAND_CMD_STATUS_ERROR3:
9317 +               udelay(this->chip_delay);
9318 +               return;
9319 +
9320 +       case NAND_CMD_RESET:
9321 +               if (this->dev_ready)
9322 +                       break;
9323 +               udelay(this->chip_delay);
9324 +               this->hwcontrol(mtd, NAND_CTL_SETCLE);
9325 +               this->write_byte(mtd, NAND_CMD_STATUS);
9326 +               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9327 +               while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
9328 +               return;
9329 +
9330 +       case NAND_CMD_READ0:
9331 +               /* Begin command latch cycle */
9332 +               this->hwcontrol(mtd, NAND_CTL_SETCLE);
9333 +               /* Write out the start read command */
9334 +               this->write_byte(mtd, NAND_CMD_READSTART);
9335 +               /* End command latch cycle */
9336 +               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9337 +               /* Fall through into ready check */
9338 +
9339 +       /* This applies to read commands */
9340 +       default:
9341 +               /*
9342 +                * If we don't have access to the busy pin, we apply the given
9343 +                * command delay
9344 +               */
9345 +               if (!this->dev_ready) {
9346 +                       udelay (this->chip_delay);
9347 +                       return;
9348 +               }
9349 +       }
9350 +
9351 +       /* Apply this short delay always to ensure that we do wait tWB in
9352 +        * any case on any machine. */
9353 +       ndelay (100);
9354 +
9355 +       nand_wait_ready(mtd);
9356 +}
9357 +
9358 +/**
9359 + * nand_get_device - [GENERIC] Get chip for selected access
9360 + * @this:      the nand chip descriptor
9361 + * @mtd:       MTD device structure
9362 + * @new_state: the state which is requested
9363 + *
9364 + * Get the device and lock it for exclusive access
9365 + */
9366 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
9367 +{
9368 +       this->state = new_state;
9369 +       return 0;
9370 +#if 0
9371 +       struct nand_chip *active;
9372 +       spinlock_t *lock;
9373 +       wait_queue_head_t *wq;
9374 +       DECLARE_WAITQUEUE (wait, current);
9375 +
9376 +       lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
9377 +       wq = (this->controller) ? &this->controller->wq : &this->wq;
9378 +retry:
9379 +       active = this;
9380 +       spin_lock(lock);
9381 +
9382 +       /* Hardware controller shared among independend devices */
9383 +       if (this->controller) {
9384 +               if (this->controller->active)
9385 +                       active = this->controller->active;
9386 +               else
9387 +                       this->controller->active = this;
9388 +       }
9389 +       if (active == this && this->state == FL_READY) {
9390 +               this->state = new_state;
9391 +               spin_unlock(lock);
9392 +               return 0;
9393 +       }
9394 +       if (new_state == FL_PM_SUSPENDED) {
9395 +               spin_unlock(lock);
9396 +               return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
9397 +       }
9398 +       set_current_state(TASK_UNINTERRUPTIBLE);
9399 +       add_wait_queue(wq, &wait);
9400 +       spin_unlock(lock);
9401 +       schedule();
9402 +       remove_wait_queue(wq, &wait);
9403 +       goto retry;
9404 +#endif
9405 +}
9406 +
9407 +/**
9408 + * nand_wait - [DEFAULT]  wait until the command is done
9409 + * @mtd:       MTD device structure
9410 + * @this:      NAND chip structure
9411 + * @state:     state to select the max. timeout value
9412 + *
9413 + * Wait for command done. This applies to erase and program only
9414 + * Erase can take up to 400ms and program up to 20ms according to
9415 + * general NAND and SmartMedia specs
9416 + *
9417 +*/
9418 +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
9419 +{
9420 +
9421 +#if 0
9422 +       unsigned long   timeo = jiffies;
9423 +#endif
9424 +       int     status;
9425 +
9426 +#if 0
9427 +       if (state == FL_ERASING)
9428 +                timeo += (HZ * 400) / 1000;
9429 +       else
9430 +                timeo += (HZ * 20) / 1000;
9431 +#endif
9432 +
9433 +       /* Apply this short delay always to ensure that we do wait tWB in
9434 +        * any case on any machine. */
9435 +       ndelay (100);
9436 +
9437 +       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
9438 +               this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
9439 +       else
9440 +               this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
9441 +
9442 +#if 0
9443 +       while (time_before(jiffies, timeo)) {
9444 +               /* Check, if we were interrupted */
9445 +               if (this->state != state)
9446 +                       return 0;
9447 +#endif
9448 +       while (1) { /* wait indefinitely */
9449 +
9450 +               if (this->dev_ready) {
9451 +                       if (this->dev_ready(mtd))
9452 +                               break;
9453 +               } else {
9454 +                       if (this->read_byte(mtd) & NAND_STATUS_READY)
9455 +                               break;
9456 +               }
9457 +
9458 +#if 0
9459 +               cond_resched();
9460 +#endif
9461 +       }
9462 +       status = (int) this->read_byte(mtd);
9463 +       return status;
9464 +}
9465 +
9466 +/**
9467 + * nand_write_page - [GENERIC] write one page
9468 + * @mtd:       MTD device structure
9469 + * @this:      NAND chip structure
9470 + * @page:      startpage inside the chip, must be called with (page & this->pagemask)
9471 + * @oob_buf:   out of band data buffer
9472 + * @oobsel:    out of band selecttion structre
9473 + * @cached:    1 = enable cached programming if supported by chip
9474 + *
9475 + * Nand_page_program function is used for write and writev !
9476 + * This function will always program a full page of data
9477 + * If you call it with a non page aligned buffer, you're lost :)
9478 + *
9479 + * Cached programming is not supported yet.
9480 + */
9481 +#if NAND_WRITE_SUPPORT
9482 +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
9483 +       u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
9484 +{
9485 +       int     i, status;
9486 +       u_char  ecc_code[32];
9487 +       int     eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
9488 +       int     *oob_config = oobsel->eccpos;
9489 +       int     datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
9490 +       int     eccbytes = 0;
9491 +
9492 +       /* FIXME: Enable cached programming */
9493 +       cached = 0;
9494 +
9495 +       /* Send command to begin auto page programming */
9496 +       this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
9497 +
9498 +       /* Write out complete page of data, take care of eccmode */
9499 +       switch (eccmode) {
9500 +       /* No ecc, write all */
9501 +       case NAND_ECC_NONE:
9502 +               puts ("Writing data without ECC to NAND-FLASH is not recommended\r\n");
9503 +               this->write_buf(mtd, this->data_poi, mtd->oobblock);
9504 +               break;
9505 +
9506 +       /* Software ecc 3/256, write all */
9507 +       case NAND_ECC_SOFT:
9508 +               for (; eccsteps; eccsteps--) {
9509 +                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
9510 +                       for (i = 0; i < 3; i++, eccidx++)
9511 +                               oob_buf[oob_config[eccidx]] = ecc_code[i];
9512 +                       datidx += this->eccsize;
9513 +               }
9514 +               this->write_buf(mtd, this->data_poi, mtd->oobblock);
9515 +               break;
9516 +       default:
9517 +               eccbytes = this->eccbytes;
9518 +               for (; eccsteps; eccsteps--) {
9519 +                       /* enable hardware ecc logic for write */
9520 +                       this->enable_hwecc(mtd, NAND_ECC_WRITE);
9521 +                       this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
9522 +                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
9523 +                       for (i = 0; i < eccbytes; i++, eccidx++)
9524 +                               oob_buf[oob_config[eccidx]] = ecc_code[i];
9525 +                       /* If the hardware ecc provides syndromes then
9526 +                        * the ecc code must be written immidiately after
9527 +                        * the data bytes (words) */
9528 +                       if (this->options & NAND_HWECC_SYNDROME)
9529 +                               this->write_buf(mtd, ecc_code, eccbytes);
9530 +                       datidx += this->eccsize;
9531 +               }
9532 +               break;
9533 +       }
9534 +
9535 +       /* Write out OOB data */
9536 +       if (this->options & NAND_HWECC_SYNDROME)
9537 +               this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
9538 +       else
9539 +               this->write_buf(mtd, oob_buf, mtd->oobsize);
9540 +
9541 +       /* Send command to actually program the data */
9542 +       this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
9543 +
9544 +       if (!cached) {
9545 +               /* call wait ready function */
9546 +               status = this->waitfunc (mtd, this, FL_WRITING);
9547 +
9548 +               /* See if operation failed and additional status checks are available */
9549 +               if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
9550 +                       status = this->errstat(mtd, this, FL_WRITING, status, page);
9551 +               }
9552 +
9553 +               /* See if device thinks it succeeded */
9554 +               if (status & NAND_STATUS_FAIL) {
9555 +                       DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
9556 +                       return -EIO;
9557 +               }
9558 +       } else {
9559 +               /* FIXME: Implement cached programming ! */
9560 +               /* wait until cache is ready*/
9561 +               // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
9562 +       }
9563 +       return 0;
9564 +}
9565 +#endif
9566 +
9567 +#if NAND_WRITE_SUPPORT
9568 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
9569 +/**
9570 + * nand_verify_pages - [GENERIC] verify the chip contents after a write
9571 + * @mtd:       MTD device structure
9572 + * @this:      NAND chip structure
9573 + * @page:      startpage inside the chip, must be called with (page & this->pagemask)
9574 + * @numpages:  number of pages to verify
9575 + * @oob_buf:   out of band data buffer
9576 + * @oobsel:    out of band selecttion structre
9577 + * @chipnr:    number of the current chip
9578 + * @oobmode:   1 = full buffer verify, 0 = ecc only
9579 + *
9580 + * The NAND device assumes that it is always writing to a cleanly erased page.
9581 + * Hence, it performs its internal write verification only on bits that
9582 + * transitioned from 1 to 0. The device does NOT verify the whole page on a
9583 + * byte by byte basis. It is possible that the page was not completely erased
9584 + * or the page is becoming unusable due to wear. The read with ECC would catch
9585 + * the error later when the ECC page check fails, but we would rather catch
9586 + * it early in the page write stage. Better to write no data than invalid data.
9587 + */
9588 +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
9589 +       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
9590 +{
9591 +       int     i, j, datidx = 0, oobofs = 0, res = -EIO;
9592 +       int     eccsteps = this->eccsteps;
9593 +       int     hweccbytes;
9594 +       u_char  oobdata[64];
9595 +
9596 +       hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
9597 +
9598 +       /* Send command to read back the first page */
9599 +       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
9600 +
9601 +       for(;;) {
9602 +               for (j = 0; j < eccsteps; j++) {
9603 +                       /* Loop through and verify the data */
9604 +                       if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
9605 +                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9606 +                               goto out;
9607 +                       }
9608 +                       datidx += mtd->eccsize;
9609 +                       /* Have we a hw generator layout ? */
9610 +                       if (!hweccbytes)
9611 +                               continue;
9612 +                       if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
9613 +                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9614 +                               goto out;
9615 +                       }
9616 +                       oobofs += hweccbytes;
9617 +               }
9618 +
9619 +               /* check, if we must compare all data or if we just have to
9620 +                * compare the ecc bytes
9621 +                */
9622 +               if (oobmode) {
9623 +                       if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
9624 +                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9625 +                               goto out;
9626 +                       }
9627 +               } else {
9628 +                       /* Read always, else autoincrement fails */
9629 +                       this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
9630 +
9631 +                       if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
9632 +                               int ecccnt = oobsel->eccbytes;
9633 +
9634 +                               for (i = 0; i < ecccnt; i++) {
9635 +                                       int idx = oobsel->eccpos[i];
9636 +                                       if (oobdata[idx] != oob_buf[oobofs + idx] ) {
9637 +                                               DEBUG (MTD_DEBUG_LEVEL0,
9638 +                                               "%s: Failed ECC write "
9639 +                                               "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
9640 +                                               goto out;
9641 +                                       }
9642 +                               }
9643 +                       }
9644 +               }
9645 +               oobofs += mtd->oobsize - hweccbytes * eccsteps;
9646 +               page++;
9647 +               numpages--;
9648 +
9649 +               /* Apply delay or wait for ready/busy pin
9650 +                * Do this before the AUTOINCR check, so no problems
9651 +                * arise if a chip which does auto increment
9652 +                * is marked as NOAUTOINCR by the board driver.
9653 +                * Do this also before returning, so the chip is
9654 +                * ready for the next command.
9655 +               */
9656 +               if (!this->dev_ready)
9657 +                       udelay (this->chip_delay);
9658 +               else
9659 +                       nand_wait_ready(mtd);
9660 +
9661 +               /* All done, return happy */
9662 +               if (!numpages)
9663 +                       return 0;
9664 +
9665 +
9666 +               /* Check, if the chip supports auto page increment */
9667 +               if (!NAND_CANAUTOINCR(this))
9668 +                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
9669 +       }
9670 +       /*
9671 +        * Terminate the read command. We come here in case of an error
9672 +        * So we must issue a reset command.
9673 +        */
9674 +out:
9675 +       this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
9676 +       return res;
9677 +}
9678 +#endif
9679 +#endif
9680 +
9681 +/**
9682 + * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
9683 + * @mtd:       MTD device structure
9684 + * @from:      offset to read from
9685 + * @len:       number of bytes to read
9686 + * @retlen:    pointer to variable to store the number of read bytes
9687 + * @buf:       the databuffer to put data
9688 + *
9689 + * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
9690 + * and flags = 0xff
9691 + */
9692 +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
9693 +{
9694 +       return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
9695 +}
9696 +
9697 +
9698 +/**
9699 + * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
9700 + * @mtd:       MTD device structure
9701 + * @from:      offset to read from
9702 + * @len:       number of bytes to read
9703 + * @retlen:    pointer to variable to store the number of read bytes
9704 + * @buf:       the databuffer to put data
9705 + * @oob_buf:   filesystem supplied oob data buffer
9706 + * @oobsel:    oob selection structure
9707 + *
9708 + * This function simply calls nand_do_read_ecc with flags = 0xff
9709 + */
9710 +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
9711 +                         size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
9712 +{
9713 +       /* use userspace supplied oobinfo, if zero */
9714 +       if (oobsel == NULL)
9715 +               oobsel = &mtd->oobinfo;
9716 +       return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
9717 +}
9718 +
9719 +
9720 +/**
9721 + * nand_do_read_ecc - [MTD Interface] Read data with ECC
9722 + * @mtd:       MTD device structure
9723 + * @from:      offset to read from
9724 + * @len:       number of bytes to read
9725 + * @retlen:    pointer to variable to store the number of read bytes
9726 + * @buf:       the databuffer to put data
9727 + * @oob_buf:   filesystem supplied oob data buffer (can be NULL)
9728 + * @oobsel:    oob selection structure
9729 + * @flags:     flag to indicate if nand_get_device/nand_release_device should be preformed
9730 + *             and how many corrected error bits are acceptable:
9731 + *               bits 0..7 - number of tolerable errors
9732 + *               bit  8    - 0 == do not get/release chip, 1 == get/release chip
9733 + *
9734 + * NAND read with ECC
9735 + */
9736 +int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
9737 +                            size_t * retlen, u_char * buf, u_char * oob_buf,
9738 +                            struct nand_oobinfo *oobsel, int flags)
9739 +{
9740 +
9741 +       int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
9742 +       int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
9743 +       struct nand_chip *this = mtd->priv;
9744 +       u_char *data_poi, *oob_data = oob_buf;
9745 +       u_char ecc_calc[32];
9746 +       u_char ecc_code[32];
9747 +        int eccmode, eccsteps;
9748 +       int     *oob_config, datidx;
9749 +       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
9750 +       int     eccbytes;
9751 +       int     compareecc = 1;
9752 +       int     oobreadlen;
9753 +
9754 +
9755 +       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
9756 +       D(
9757 +         puts ("nand_read_ecc: from = ");
9758 +         putx (from);
9759 +         puts (", len = ");
9760 +         putx(len);
9761 +         putnl();
9762 +        )
9763 +
9764 +       /* Do not allow reads past end of device */
9765 +       if ((from + len) > mtd->size) {
9766 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
9767 +               D(puts("nand_read_ecc: Attempt read beyond end of device\r\n"));
9768 +               *retlen = 0;
9769 +               return -EINVAL;
9770 +       }
9771 +
9772 +       /* Grab the lock and see if the device is available */
9773 +       if (flags & NAND_GET_DEVICE)
9774 +               nand_get_device (this, mtd, FL_READING);
9775 +
9776 +       /* Autoplace of oob data ? Use the default placement scheme */
9777 +       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
9778 +               oobsel = this->autooob;
9779 +
9780 +       eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
9781 +       oob_config = oobsel->eccpos;
9782 +
9783 +       /* Select the NAND device */
9784 +       chipnr = (int)(from >> this->chip_shift);
9785 +       this->select_chip(mtd, chipnr);
9786 +
9787 +       /* First we calculate the starting page */
9788 +       realpage = (int) (from >> this->page_shift);
9789 +       page = realpage & this->pagemask;
9790 +
9791 +       /* Get raw starting column */
9792 +       col = from & (mtd->oobblock - 1);
9793 +
9794 +       end = mtd->oobblock;
9795 +       ecc = this->eccsize;
9796 +       eccbytes = this->eccbytes;
9797 +
9798 +       if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
9799 +               compareecc = 0;
9800 +
9801 +       oobreadlen = mtd->oobsize;
9802 +       if (this->options & NAND_HWECC_SYNDROME)
9803 +               oobreadlen -= oobsel->eccbytes;
9804 +
9805 +       /* Loop until all data read */
9806 +       while (read < len) {
9807 +
9808 +               int aligned = (!col && (len - read) >= end);
9809 +               /*
9810 +                * If the read is not page aligned, we have to read into data buffer
9811 +                * due to ecc, else we read into return buffer direct
9812 +                */
9813 +               if (aligned)
9814 +                       data_poi = &buf[read];
9815 +               else
9816 +                       data_poi = this->data_buf;
9817 +
9818 +               /* Check, if we have this page in the buffer
9819 +                *
9820 +                * FIXME: Make it work when we must provide oob data too,
9821 +                * check the usage of data_buf oob field
9822 +                */
9823 +               if (realpage == this->pagebuf && !oob_buf) {
9824 +                       /* aligned read ? */
9825 +                       if (aligned)
9826 +                               memcpy (data_poi, this->data_buf, end);
9827 +                       goto readdata;
9828 +               }
9829 +
9830 +               /* Check, if we must send the read command */
9831 +               if (sndcmd) {
9832 +                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
9833 +                       sndcmd = 0;
9834 +               }
9835 +
9836 +               /* get oob area, if we have no oob buffer from fs-driver */
9837 +               if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
9838 +                       oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
9839 +                       oob_data = &this->data_buf[end];
9840 +
9841 +               eccsteps = this->eccsteps;
9842 +
9843 +               switch (eccmode) {
9844 +               case NAND_ECC_NONE: {   /* No ECC, Read in a page */
9845 +#if 0
9846 +                       static unsigned long lastwhinge = 0;
9847 +                       if ((lastwhinge / HZ) != (jiffies / HZ)) {
9848 +                               puts ("Reading data from NAND FLASH without ECC is not recommended\r\n");
9849 +                               lastwhinge = jiffies;
9850 +                       }
9851 +#endif
9852 +                       this->read_buf(mtd, data_poi, end);
9853 +                       break;
9854 +               }
9855 +
9856 +               case NAND_ECC_SOFT:     /* Software ECC 3/256: Read in a page + oob data */
9857 +                       this->read_buf(mtd, data_poi, end);
9858 +                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
9859 +                               this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
9860 +                       break;
9861 +
9862 +               default:
9863 +#if NAND_HWECC_SUPPORT
9864 +                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
9865 +                               this->enable_hwecc(mtd, NAND_ECC_READ);
9866 +                               this->read_buf(mtd, &data_poi[datidx], ecc);
9867 +
9868 +                               /* HW ecc with syndrome calculation must read the
9869 +                                * syndrome from flash immidiately after the data */
9870 +                               if (!compareecc) {
9871 +                                       /* Some hw ecc generators need to know when the
9872 +                                        * syndrome is read from flash */
9873 +                                       this->enable_hwecc(mtd, NAND_ECC_READSYN);
9874 +                                       this->read_buf(mtd, &oob_data[i], eccbytes);
9875 +                                       /* We calc error correction directly, it checks the hw
9876 +                                        * generator for an error, reads back the syndrome and
9877 +                                        * does the error correction on the fly */
9878 +                                       ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
9879 +                                       if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
9880 +                                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
9881 +                                                       "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
9882 +                                               ecc_failed++;
9883 +                                       }
9884 +                               } else {
9885 +                                       this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
9886 +                               }
9887 +                       }
9888 +#endif
9889 +                       break;
9890 +               }
9891 +
9892 +               /* read oobdata */
9893 +               this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
9894 +
9895 +               /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
9896 +               if (!compareecc)
9897 +                       goto readoob;
9898 +
9899 +               /* Pick the ECC bytes out of the oob data */
9900 +               for (j = 0; j < oobsel->eccbytes; j++)
9901 +                       ecc_code[j] = oob_data[oob_config[j]];
9902 +
9903 +               /* correct data, if neccecary */
9904 +               for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
9905 +                       ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
9906 +
9907 +                       /* Get next chunk of ecc bytes */
9908 +                       j += eccbytes;
9909 +
9910 +                       /* Check, if we have a fs supplied oob-buffer,
9911 +                        * This is the legacy mode. Used by YAFFS1
9912 +                        * Should go away some day
9913 +                        */
9914 +                       if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
9915 +                               int *p = (int *)(&oob_data[mtd->oobsize]);
9916 +                               p[i] = ecc_status;
9917 +                       }
9918 +
9919 +                       if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
9920 +                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
9921 +                               D(
9922 +                                 puts ("nand_read_ecc: " "Failed ECC read, page ");
9923 +                                 putx (page);
9924 +                                 putnl();
9925 +                                )
9926 +                               ecc_failed++;
9927 +                       }
9928 +               }
9929 +
9930 +       readoob:
9931 +               /* check, if we have a fs supplied oob-buffer */
9932 +               if (oob_buf) {
9933 +                       /* without autoplace. Legacy mode used by YAFFS1 */
9934 +                       switch(oobsel->useecc) {
9935 +                       case MTD_NANDECC_AUTOPLACE:
9936 +                       case MTD_NANDECC_AUTOPL_USR:
9937 +                               /* Walk through the autoplace chunks */
9938 +                               for (i = 0; oobsel->oobfree[i][1]; i++) {
9939 +                                       int from = oobsel->oobfree[i][0];
9940 +                                       int num = oobsel->oobfree[i][1];
9941 +                                       memcpy(&oob_buf[oob], &oob_data[from], num);
9942 +                                       oob += num;
9943 +                               }
9944 +                               break;
9945 +                       case MTD_NANDECC_PLACE:
9946 +                               /* YAFFS1 legacy mode */
9947 +                               oob_data += this->eccsteps * sizeof (int);
9948 +                       default:
9949 +                               oob_data += mtd->oobsize;
9950 +                       }
9951 +               }
9952 +       readdata:
9953 +               /* Partial page read, transfer data into fs buffer */
9954 +               if (!aligned) {
9955 +                       for (j = col; j < end && read < len; j++)
9956 +                               buf[read++] = data_poi[j];
9957 +                       this->pagebuf = realpage;
9958 +               } else
9959 +                       read += mtd->oobblock;
9960 +
9961 +               /* Apply delay or wait for ready/busy pin
9962 +                * Do this before the AUTOINCR check, so no problems
9963 +                * arise if a chip which does auto increment
9964 +                * is marked as NOAUTOINCR by the board driver.
9965 +               */
9966 +               if (!this->dev_ready)
9967 +                       udelay (this->chip_delay);
9968 +               else
9969 +                       nand_wait_ready(mtd);
9970 +
9971 +               if (read == len)
9972 +                       break;
9973 +
9974 +               /* For subsequent reads align to page boundary. */
9975 +               col = 0;
9976 +               /* Increment page address */
9977 +               realpage++;
9978 +
9979 +               page = realpage & this->pagemask;
9980 +               /* Check, if we cross a chip boundary */
9981 +               if (!page) {
9982 +                       chipnr++;
9983 +                       this->select_chip(mtd, -1);
9984 +                       this->select_chip(mtd, chipnr);
9985 +               }
9986 +               /* Check, if the chip supports auto page increment
9987 +                * or if we have hit a block boundary.
9988 +               */
9989 +               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
9990 +                       sndcmd = 1;
9991 +       }
9992 +
9993 +       /* Deselect and wake up anyone waiting on the device */
9994 +       if (flags & NAND_GET_DEVICE)
9995 +               nand_release_device(mtd);
9996 +
9997 +       /*
9998 +        * Return success, if no ECC failures, else -EBADMSG
9999 +        * fs driver will take care of that, because
10000 +        * retlen == desired len and result == -EBADMSG
10001 +        */
10002 +       *retlen = read;
10003 +       return ecc_failed ? -EBADMSG : 0;
10004 +}
10005 +
10006 +/**
10007 + * nand_read_oob - [MTD Interface] NAND read out-of-band
10008 + * @mtd:       MTD device structure
10009 + * @from:      offset to read from
10010 + * @len:       number of bytes to read
10011 + * @retlen:    pointer to variable to store the number of read bytes
10012 + * @buf:       the databuffer to put data
10013 + *
10014 + * NAND read out-of-band data from the spare area
10015 + */
10016 +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
10017 +{
10018 +       int i, col, page, chipnr;
10019 +       struct nand_chip *this = mtd->priv;
10020 +       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
10021 +
10022 +       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
10023 +
10024 +       /* Shift to get page */
10025 +       page = (int)(from >> this->page_shift);
10026 +       chipnr = (int)(from >> this->chip_shift);
10027 +
10028 +       /* Mask to get column */
10029 +       col = from & (mtd->oobsize - 1);
10030 +
10031 +       /* Initialize return length value */
10032 +       *retlen = 0;
10033 +
10034 +       /* Do not allow reads past end of device */
10035 +       if ((from + len) > mtd->size) {
10036 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
10037 +               *retlen = 0;
10038 +               return -EINVAL;
10039 +       }
10040 +
10041 +       /* Grab the lock and see if the device is available */
10042 +       nand_get_device (this, mtd , FL_READING);
10043 +
10044 +       /* Select the NAND device */
10045 +       this->select_chip(mtd, chipnr);
10046 +
10047 +       /* Send the read command */
10048 +       this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
10049 +       /*
10050 +        * Read the data, if we read more than one page
10051 +        * oob data, let the device transfer the data !
10052 +        */
10053 +       i = 0;
10054 +       while (i < len) {
10055 +               int thislen = mtd->oobsize - col;
10056 +               thislen = min_t(int, thislen, len);
10057 +               this->read_buf(mtd, &buf[i], thislen);
10058 +               i += thislen;
10059 +
10060 +               /* Read more ? */
10061 +               if (i < len) {
10062 +                       page++;
10063 +                       col = 0;
10064 +
10065 +                       /* Check, if we cross a chip boundary */
10066 +                       if (!(page & this->pagemask)) {
10067 +                               chipnr++;
10068 +                               this->select_chip(mtd, -1);
10069 +                               this->select_chip(mtd, chipnr);
10070 +                       }
10071 +
10072 +                       /* Apply delay or wait for ready/busy pin
10073 +                        * Do this before the AUTOINCR check, so no problems
10074 +                        * arise if a chip which does auto increment
10075 +                        * is marked as NOAUTOINCR by the board driver.
10076 +                        */
10077 +                       if (!this->dev_ready)
10078 +                               udelay (this->chip_delay);
10079 +                       else
10080 +                               nand_wait_ready(mtd);
10081 +
10082 +                       /* Check, if the chip supports auto page increment
10083 +                        * or if we have hit a block boundary.
10084 +                       */
10085 +                       if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
10086 +                               /* For subsequent page reads set offset to 0 */
10087 +                               this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
10088 +                       }
10089 +               }
10090 +       }
10091 +
10092 +       /* Deselect and wake up anyone waiting on the device */
10093 +       nand_release_device(mtd);
10094 +
10095 +       /* Return happy */
10096 +       *retlen = len;
10097 +       return 0;
10098 +}
10099 +
10100 +/**
10101 + * nand_read_raw - [GENERIC] Read raw data including oob into buffer
10102 + * @mtd:       MTD device structure
10103 + * @buf:       temporary buffer
10104 + * @from:      offset to read from
10105 + * @len:       number of bytes to read
10106 + * @ooblen:    number of oob data bytes to read
10107 + *
10108 + * Read raw data including oob into buffer
10109 + */
10110 +int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
10111 +{
10112 +       struct nand_chip *this = mtd->priv;
10113 +       int page = (int) (from >> this->page_shift);
10114 +       int chip = (int) (from >> this->chip_shift);
10115 +       int sndcmd = 1;
10116 +       int cnt = 0;
10117 +       int pagesize = mtd->oobblock + mtd->oobsize;
10118 +       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
10119 +
10120 +       /* Do not allow reads past end of device */
10121 +       if ((from + len) > mtd->size) {
10122 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
10123 +               return -EINVAL;
10124 +       }
10125 +
10126 +       /* Grab the lock and see if the device is available */
10127 +       nand_get_device (this, mtd , FL_READING);
10128 +
10129 +       this->select_chip (mtd, chip);
10130 +
10131 +       /* Add requested oob length */
10132 +       len += ooblen;
10133 +
10134 +       while (len) {
10135 +               if (sndcmd)
10136 +                       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
10137 +               sndcmd = 0;
10138 +
10139 +               this->read_buf (mtd, &buf[cnt], pagesize);
10140 +
10141 +               len -= pagesize;
10142 +               cnt += pagesize;
10143 +               page++;
10144 +
10145 +               if (!this->dev_ready)
10146 +                       udelay (this->chip_delay);
10147 +               else
10148 +                       nand_wait_ready(mtd);
10149 +
10150 +               /* Check, if the chip supports auto page increment */
10151 +               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
10152 +                       sndcmd = 1;
10153 +       }
10154 +
10155 +       /* Deselect and wake up anyone waiting on the device */
10156 +       nand_release_device(mtd);
10157 +       return 0;
10158 +}
10159 +
10160 +
10161 +/**
10162 + * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
10163 + * @mtd:       MTD device structure
10164 + * @fsbuf:     buffer given by fs driver
10165 + * @oobsel:    out of band selection structre
10166 + * @autoplace: 1 = place given buffer into the oob bytes
10167 + * @numpages:  number of pages to prepare
10168 + *
10169 + * Return:
10170 + * 1. Filesystem buffer available and autoplacement is off,
10171 + *    return filesystem buffer
10172 + * 2. No filesystem buffer or autoplace is off, return internal
10173 + *    buffer
10174 + * 3. Filesystem buffer is given and autoplace selected
10175 + *    put data from fs buffer into internal buffer and
10176 + *    retrun internal buffer
10177 + *
10178 + * Note: The internal buffer is filled with 0xff. This must
10179 + * be done only once, when no autoplacement happens
10180 + * Autoplacement sets the buffer dirty flag, which
10181 + * forces the 0xff fill before using the buffer again.
10182 + *
10183 +*/
10184 +#if NAND_WRITE_SUPPORT
10185 +static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
10186 +               int autoplace, int numpages)
10187 +{
10188 +       struct nand_chip *this = mtd->priv;
10189 +       int i, len, ofs;
10190 +
10191 +       /* Zero copy fs supplied buffer */
10192 +       if (fsbuf && !autoplace)
10193 +               return fsbuf;
10194 +
10195 +       /* Check, if the buffer must be filled with ff again */
10196 +       if (this->oobdirty) {
10197 +               memset (this->oob_buf, 0xff,
10198 +                       mtd->oobsize << (this->phys_erase_shift - this->page_shift));
10199 +               this->oobdirty = 0;
10200 +       }
10201 +
10202 +       /* If we have no autoplacement or no fs buffer use the internal one */
10203 +       if (!autoplace || !fsbuf)
10204 +               return this->oob_buf;
10205 +
10206 +       /* Walk through the pages and place the data */
10207 +       this->oobdirty = 1;
10208 +       ofs = 0;
10209 +       while (numpages--) {
10210 +               for (i = 0, len = 0; len < mtd->oobavail; i++) {
10211 +                       int to = ofs + oobsel->oobfree[i][0];
10212 +                       int num = oobsel->oobfree[i][1];
10213 +                       memcpy (&this->oob_buf[to], fsbuf, num);
10214 +                       len += num;
10215 +                       fsbuf += num;
10216 +               }
10217 +               ofs += mtd->oobavail;
10218 +       }
10219 +       return this->oob_buf;
10220 +}
10221 +#endif
10222 +
10223 +#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
10224 +
10225 +/**
10226 + * nand_write - [MTD Interface] compability function for nand_write_ecc
10227 + * @mtd:       MTD device structure
10228 + * @to:                offset to write to
10229 + * @len:       number of bytes to write
10230 + * @retlen:    pointer to variable to store the number of written bytes
10231 + * @buf:       the data to write
10232 + *
10233 + * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
10234 + *
10235 +*/
10236 +#if NAND_WRITE_SUPPORT
10237 +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
10238 +{
10239 +       return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
10240 +}
10241 +#endif
10242 +
10243 +/**
10244 + * nand_write_ecc - [MTD Interface] NAND write with ECC
10245 + * @mtd:       MTD device structure
10246 + * @to:                offset to write to
10247 + * @len:       number of bytes to write
10248 + * @retlen:    pointer to variable to store the number of written bytes
10249 + * @buf:       the data to write
10250 + * @eccbuf:    filesystem supplied oob data buffer
10251 + * @oobsel:    oob selection structure
10252 + *
10253 + * NAND write with ECC
10254 + */
10255 +#if NAND_WRITE_SUPPORT
10256 +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
10257 +                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
10258 +{
10259 +       int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
10260 +       int autoplace = 0, numpages, totalpages;
10261 +       struct nand_chip *this = mtd->priv;
10262 +       u_char *oobbuf, *bufstart;
10263 +       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
10264 +
10265 +       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10266 +
10267 +       /* Initialize retlen, in case of early exit */
10268 +       *retlen = 0;
10269 +
10270 +       /* Do not allow write past end of device */
10271 +       if ((to + len) > mtd->size) {
10272 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
10273 +               return -EINVAL;
10274 +       }
10275 +
10276 +       /* reject writes, which are not page aligned */
10277 +       if (NOTALIGNED (to) || NOTALIGNED(len)) {
10278 +               puts ("nand_write_ecc: Attempt to write not page aligned data\r\n");
10279 +               return -EINVAL;
10280 +       }
10281 +
10282 +       /* Grab the lock and see if the device is available */
10283 +       nand_get_device (this, mtd, FL_WRITING);
10284 +
10285 +       /* Calculate chipnr */
10286 +       chipnr = (int)(to >> this->chip_shift);
10287 +       /* Select the NAND device */
10288 +       this->select_chip(mtd, chipnr);
10289 +
10290 +       /* Check, if it is write protected */
10291 +       if (nand_check_wp(mtd))
10292 +               goto out;
10293 +
10294 +       /* if oobsel is NULL, use chip defaults */
10295 +       if (oobsel == NULL)
10296 +               oobsel = &mtd->oobinfo;
10297 +
10298 +       /* Autoplace of oob data ? Use the default placement scheme */
10299 +       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10300 +               oobsel = this->autooob;
10301 +               autoplace = 1;
10302 +       }
10303 +       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
10304 +               autoplace = 1;
10305 +
10306 +       /* Setup variables and oob buffer */
10307 +       totalpages = len >> this->page_shift;
10308 +       page = (int) (to >> this->page_shift);
10309 +       /* Invalidate the page cache, if we write to the cached page */
10310 +       if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
10311 +               this->pagebuf = -1;
10312 +
10313 +       /* Set it relative to chip */
10314 +       page &= this->pagemask;
10315 +       startpage = page;
10316 +       /* Calc number of pages we can write in one go */
10317 +       numpages = min (ppblock - (startpage  & (ppblock - 1)), totalpages);
10318 +       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
10319 +       bufstart = (u_char *)buf;
10320 +
10321 +       /* Loop until all data is written */
10322 +       while (written < len) {
10323 +
10324 +               this->data_poi = (u_char*) &buf[written];
10325 +               /* Write one page. If this is the last page to write
10326 +                * or the last page in this block, then use the
10327 +                * real pageprogram command, else select cached programming
10328 +                * if supported by the chip.
10329 +                */
10330 +               ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
10331 +               if (ret) {
10332 +                       DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
10333 +                       goto out;
10334 +               }
10335 +               /* Next oob page */
10336 +               oob += mtd->oobsize;
10337 +               /* Update written bytes count */
10338 +               written += mtd->oobblock;
10339 +               if (written == len)
10340 +                       goto cmp;
10341 +
10342 +               /* Increment page address */
10343 +               page++;
10344 +
10345 +               /* Have we hit a block boundary ? Then we have to verify and
10346 +                * if verify is ok, we have to setup the oob buffer for
10347 +                * the next pages.
10348 +               */
10349 +               if (!(page & (ppblock - 1))){
10350 +                       int ofs;
10351 +                       this->data_poi = bufstart;
10352 +                       ret = nand_verify_pages (mtd, this, startpage,
10353 +                               page - startpage,
10354 +                               oobbuf, oobsel, chipnr, (eccbuf != NULL));
10355 +                       if (ret) {
10356 +                               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10357 +                               goto out;
10358 +                       }
10359 +                       *retlen = written;
10360 +
10361 +                       ofs = autoplace ? mtd->oobavail : mtd->oobsize;
10362 +                       if (eccbuf)
10363 +                               eccbuf += (page - startpage) * ofs;
10364 +                       totalpages -= page - startpage;
10365 +                       numpages = min (totalpages, ppblock);
10366 +                       page &= this->pagemask;
10367 +                       startpage = page;
10368 +                       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
10369 +                                       autoplace, numpages);
10370 +                       oob = 0;
10371 +                       /* Check, if we cross a chip boundary */
10372 +                       if (!page) {
10373 +                               chipnr++;
10374 +                               this->select_chip(mtd, -1);
10375 +                               this->select_chip(mtd, chipnr);
10376 +                       }
10377 +               }
10378 +       }
10379 +       /* Verify the remaining pages */
10380 +cmp:
10381 +       this->data_poi = bufstart;
10382 +       ret = nand_verify_pages (mtd, this, startpage, totalpages,
10383 +               oobbuf, oobsel, chipnr, (eccbuf != NULL));
10384 +       if (!ret)
10385 +               *retlen = written;
10386 +       else
10387 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10388 +
10389 +out:
10390 +       /* Deselect and wake up anyone waiting on the device */
10391 +       nand_release_device(mtd);
10392 +
10393 +       return ret;
10394 +}
10395 +#endif
10396 +
10397 +
10398 +/**
10399 + * nand_write_oob - [MTD Interface] NAND write out-of-band
10400 + * @mtd:       MTD device structure
10401 + * @to:                offset to write to
10402 + * @len:       number of bytes to write
10403 + * @retlen:    pointer to variable to store the number of written bytes
10404 + * @buf:       the data to write
10405 + *
10406 + * NAND write out-of-band
10407 + */
10408 +#if NAND_WRITE_SUPPORT
10409 +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
10410 +{
10411 +       int column, page, status, ret = -EIO, chipnr;
10412 +       struct nand_chip *this = mtd->priv;
10413 +
10414 +       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10415 +
10416 +       /* Shift to get page */
10417 +       page = (int) (to >> this->page_shift);
10418 +       chipnr = (int) (to >> this->chip_shift);
10419 +
10420 +       /* Mask to get column */
10421 +       column = to & (mtd->oobsize - 1);
10422 +
10423 +       /* Initialize return length value */
10424 +       *retlen = 0;
10425 +
10426 +       /* Do not allow write past end of page */
10427 +       if ((column + len) > mtd->oobsize) {
10428 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
10429 +               return -EINVAL;
10430 +       }
10431 +
10432 +       /* Grab the lock and see if the device is available */
10433 +       nand_get_device (this, mtd, FL_WRITING);
10434 +
10435 +       /* Select the NAND device */
10436 +       this->select_chip(mtd, chipnr);
10437 +
10438 +       /* Reset the chip. Some chips (like the Toshiba TC5832DC found
10439 +          in one of my DiskOnChip 2000 test units) will clear the whole
10440 +          data page too if we don't do this. I have no clue why, but
10441 +          I seem to have 'fixed' it in the doc2000 driver in
10442 +          August 1999.  dwmw2. */
10443 +       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
10444 +
10445 +       /* Check, if it is write protected */
10446 +       if (nand_check_wp(mtd))
10447 +               goto out;
10448 +
10449 +       /* Invalidate the page cache, if we write to the cached page */
10450 +       if (page == this->pagebuf)
10451 +               this->pagebuf = -1;
10452 +
10453 +       if (NAND_MUST_PAD(this)) {
10454 +               /* Write out desired data */
10455 +               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
10456 +               /* prepad 0xff for partial programming */
10457 +               this->write_buf(mtd, ffchars, column);
10458 +               /* write data */
10459 +               this->write_buf(mtd, buf, len);
10460 +               /* postpad 0xff for partial programming */
10461 +               this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
10462 +       } else {
10463 +               /* Write out desired data */
10464 +               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
10465 +               /* write data */
10466 +               this->write_buf(mtd, buf, len);
10467 +       }
10468 +       /* Send command to program the OOB data */
10469 +       this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
10470 +
10471 +       status = this->waitfunc (mtd, this, FL_WRITING);
10472 +
10473 +       /* See if device thinks it succeeded */
10474 +       if (status & NAND_STATUS_FAIL) {
10475 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
10476 +               ret = -EIO;
10477 +               goto out;
10478 +       }
10479 +       /* Return happy */
10480 +       *retlen = len;
10481 +
10482 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
10483 +       /* Send command to read back the data */
10484 +       this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
10485 +
10486 +       if (this->verify_buf(mtd, buf, len)) {
10487 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
10488 +               ret = -EIO;
10489 +               goto out;
10490 +       }
10491 +#endif
10492 +       ret = 0;
10493 +out:
10494 +       /* Deselect and wake up anyone waiting on the device */
10495 +       nand_release_device(mtd);
10496 +
10497 +       return ret;
10498 +}
10499 +#endif
10500 +
10501 +
10502 +/**
10503 + * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
10504 + * @mtd:       MTD device structure
10505 + * @vecs:      the iovectors to write
10506 + * @count:     number of vectors
10507 + * @to:                offset to write to
10508 + * @retlen:    pointer to variable to store the number of written bytes
10509 + *
10510 + * NAND write with kvec. This just calls the ecc function
10511 + */
10512 +#if NAND_KVEC_SUPPORT
10513 +#if NAND_WRITE_SUPPORT
10514 +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
10515 +               loff_t to, size_t * retlen)
10516 +{
10517 +       return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
10518 +}
10519 +#endif
10520 +#endif
10521 +
10522 +/**
10523 + * nand_writev_ecc - [MTD Interface] write with iovec with ecc
10524 + * @mtd:       MTD device structure
10525 + * @vecs:      the iovectors to write
10526 + * @count:     number of vectors
10527 + * @to:                offset to write to
10528 + * @retlen:    pointer to variable to store the number of written bytes
10529 + * @eccbuf:    filesystem supplied oob data buffer
10530 + * @oobsel:    oob selection structure
10531 + *
10532 + * NAND write with iovec with ecc
10533 + */
10534 +#if NAND_KVEC_SUPPORT
10535 +#if NAND_WRITE_SUPPORT
10536 +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
10537 +               loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
10538 +{
10539 +       int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
10540 +       int oob, numpages, autoplace = 0, startpage;
10541 +       struct nand_chip *this = mtd->priv;
10542 +       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
10543 +       u_char *oobbuf, *bufstart;
10544 +
10545 +       /* Preset written len for early exit */
10546 +       *retlen = 0;
10547 +
10548 +       /* Calculate total length of data */
10549 +       total_len = 0;
10550 +       for (i = 0; i < count; i++)
10551 +               total_len += (int) vecs[i].iov_len;
10552 +
10553 +       DEBUG (MTD_DEBUG_LEVEL3,
10554 +              "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
10555 +
10556 +       /* Do not allow write past end of page */
10557 +       if ((to + total_len) > mtd->size) {
10558 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
10559 +               return -EINVAL;
10560 +       }
10561 +
10562 +       /* reject writes, which are not page aligned */
10563 +       if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
10564 +               puts ("nand_write_ecc: Attempt to write not page aligned data\r\n");
10565 +               return -EINVAL;
10566 +       }
10567 +
10568 +       /* Grab the lock and see if the device is available */
10569 +       nand_get_device (this, mtd, FL_WRITING);
10570 +
10571 +       /* Get the current chip-nr */
10572 +       chipnr = (int) (to >> this->chip_shift);
10573 +       /* Select the NAND device */
10574 +       this->select_chip(mtd, chipnr);
10575 +
10576 +       /* Check, if it is write protected */
10577 +       if (nand_check_wp(mtd))
10578 +               goto out;
10579 +
10580 +       /* if oobsel is NULL, use chip defaults */
10581 +       if (oobsel == NULL)
10582 +               oobsel = &mtd->oobinfo;
10583 +
10584 +       /* Autoplace of oob data ? Use the default placement scheme */
10585 +       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10586 +               oobsel = this->autooob;
10587 +               autoplace = 1;
10588 +       }
10589 +       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
10590 +               autoplace = 1;
10591 +
10592 +       /* Setup start page */
10593 +       page = (int) (to >> this->page_shift);
10594 +       /* Invalidate the page cache, if we write to the cached page */
10595 +       if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
10596 +               this->pagebuf = -1;
10597 +
10598 +       startpage = page & this->pagemask;
10599 +
10600 +       /* Loop until all kvec' data has been written */
10601 +       len = 0;
10602 +       while (count) {
10603 +               /* If the given tuple is >= pagesize then
10604 +                * write it out from the iov
10605 +                */
10606 +               if ((vecs->iov_len - len) >= mtd->oobblock) {
10607 +                       /* Calc number of pages we can write
10608 +                        * out of this iov in one go */
10609 +                       numpages = (vecs->iov_len - len) >> this->page_shift;
10610 +                       /* Do not cross block boundaries */
10611 +                       numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
10612 +                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
10613 +                       bufstart = (u_char *)vecs->iov_base;
10614 +                       bufstart += len;
10615 +                       this->data_poi = bufstart;
10616 +                       oob = 0;
10617 +                       for (i = 1; i <= numpages; i++) {
10618 +                               /* Write one page. If this is the last page to write
10619 +                                * then use the real pageprogram command, else select
10620 +                                * cached programming if supported by the chip.
10621 +                                */
10622 +                               ret = nand_write_page (mtd, this, page & this->pagemask,
10623 +                                       &oobbuf[oob], oobsel, i != numpages);
10624 +                               if (ret)
10625 +                                       goto out;
10626 +                               this->data_poi += mtd->oobblock;
10627 +                               len += mtd->oobblock;
10628 +                               oob += mtd->oobsize;
10629 +                               page++;
10630 +                       }
10631 +                       /* Check, if we have to switch to the next tuple */
10632 +                       if (len >= (int) vecs->iov_len) {
10633 +                               vecs++;
10634 +                               len = 0;
10635 +                               count--;
10636 +                       }
10637 +               } else {
10638 +                       /* We must use the internal buffer, read data out of each
10639 +                        * tuple until we have a full page to write
10640 +                        */
10641 +                       int cnt = 0;
10642 +                       while (cnt < mtd->oobblock) {
10643 +                               if (vecs->iov_base != NULL && vecs->iov_len)
10644 +                                       this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
10645 +                               /* Check, if we have to switch to the next tuple */
10646 +                               if (len >= (int) vecs->iov_len) {
10647 +                                       vecs++;
10648 +                                       len = 0;
10649 +                                       count--;
10650 +                               }
10651 +                       }
10652 +                       this->pagebuf = page;
10653 +                       this->data_poi = this->data_buf;
10654 +                       bufstart = this->data_poi;
10655 +                       numpages = 1;
10656 +                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
10657 +                       ret = nand_write_page (mtd, this, page & this->pagemask,
10658 +                               oobbuf, oobsel, 0);
10659 +                       if (ret)
10660 +                               goto out;
10661 +                       page++;
10662 +               }
10663 +
10664 +               this->data_poi = bufstart;
10665 +               ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
10666 +               if (ret)
10667 +                       goto out;
10668 +
10669 +               written += mtd->oobblock * numpages;
10670 +               /* All done ? */
10671 +               if (!count)
10672 +                       break;
10673 +
10674 +               startpage = page & this->pagemask;
10675 +               /* Check, if we cross a chip boundary */
10676 +               if (!startpage) {
10677 +                       chipnr++;
10678 +                       this->select_chip(mtd, -1);
10679 +                       this->select_chip(mtd, chipnr);
10680 +               }
10681 +       }
10682 +       ret = 0;
10683 +out:
10684 +       /* Deselect and wake up anyone waiting on the device */
10685 +       nand_release_device(mtd);
10686 +
10687 +       *retlen = written;
10688 +       return ret;
10689 +}
10690 +#endif
10691 +#endif
10692 +
10693 +/**
10694 + * single_erease_cmd - [GENERIC] NAND standard block erase command function
10695 + * @mtd:       MTD device structure
10696 + * @page:      the page address of the block which will be erased
10697 + *
10698 + * Standard erase command for NAND chips
10699 + */
10700 +#if NAND_ERASE_SUPPORT
10701 +static void single_erase_cmd (struct mtd_info *mtd, int page)
10702 +{
10703 +       struct nand_chip *this = mtd->priv;
10704 +       /* Send commands to erase a block */
10705 +       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
10706 +       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
10707 +}
10708 +#endif
10709 +
10710 +/**
10711 + * multi_erease_cmd - [GENERIC] AND specific block erase command function
10712 + * @mtd:       MTD device structure
10713 + * @page:      the page address of the block which will be erased
10714 + *
10715 + * AND multi block erase command function
10716 + * Erase 4 consecutive blocks
10717 + */
10718 +#if NAND_ERASE_SUPPORT
10719 +static void multi_erase_cmd (struct mtd_info *mtd, int page)
10720 +{
10721 +       struct nand_chip *this = mtd->priv;
10722 +       /* Send commands to erase a block */
10723 +       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10724 +       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10725 +       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10726 +       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
10727 +       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
10728 +}
10729 +#endif
10730 +
10731 +/**
10732 + * nand_erase - [MTD Interface] erase block(s)
10733 + * @mtd:       MTD device structure
10734 + * @instr:     erase instruction
10735 + *
10736 + * Erase one ore more blocks
10737 + */
10738 +#if NAND_ERASE_SUPPORT
10739 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
10740 +{
10741 +       return nand_erase_nand (mtd, instr, 0);
10742 +}
10743 +#endif
10744 +
10745 +#define BBT_PAGE_MASK  0xffffff3f
10746 +/**
10747 + * nand_erase_intern - [NAND Interface] erase block(s)
10748 + * @mtd:       MTD device structure
10749 + * @instr:     erase instruction
10750 + * @allowbbt:  allow erasing the bbt area
10751 + *
10752 + * Erase one ore more blocks
10753 + */
10754 +#if NAND_ERASE_SUPPORT
10755 +int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
10756 +{
10757 +       int page, len, status, pages_per_block, ret, chipnr;
10758 +       struct nand_chip *this = mtd->priv;
10759 +       int rewrite_bbt[NAND_MAX_CHIPS]={0};    /* flags to indicate the page, if bbt needs to be rewritten. */
10760 +       unsigned int bbt_masked_page;           /* bbt mask to compare to page being erased. */
10761 +                                               /* It is used to see if the current page is in the same */
10762 +                                               /*   256 block group and the same bank as the bbt. */
10763 +
10764 +       DEBUG (MTD_DEBUG_LEVEL3,
10765 +              "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
10766 +
10767 +       /* Start address must align on block boundary */
10768 +       if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
10769 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
10770 +               return -EINVAL;
10771 +       }
10772 +
10773 +       /* Length must align on block boundary */
10774 +       if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
10775 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
10776 +               return -EINVAL;
10777 +       }
10778 +
10779 +       /* Do not allow erase past end of device */
10780 +       if ((instr->len + instr->addr) > mtd->size) {
10781 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
10782 +               return -EINVAL;
10783 +       }
10784 +
10785 +       instr->fail_addr = 0xffffffff;
10786 +
10787 +       /* Grab the lock and see if the device is available */
10788 +       nand_get_device (this, mtd, FL_ERASING);
10789 +
10790 +       /* Shift to get first page */
10791 +       page = (int) (instr->addr >> this->page_shift);
10792 +       chipnr = (int) (instr->addr >> this->chip_shift);
10793 +
10794 +       /* Calculate pages in each block */
10795 +       pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
10796 +
10797 +       /* Select the NAND device */
10798 +       this->select_chip(mtd, chipnr);
10799 +
10800 +       /* Check the WP bit */
10801 +       /* Check, if it is write protected */
10802 +       if (nand_check_wp(mtd)) {
10803 +               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
10804 +               instr->state = MTD_ERASE_FAILED;
10805 +               goto erase_exit;
10806 +       }
10807 +
10808 +       /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
10809 +       if (this->options & BBT_AUTO_REFRESH) {
10810 +               bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
10811 +       } else {
10812 +               bbt_masked_page = 0xffffffff;   /* should not match anything */
10813 +       }
10814 +
10815 +       /* Loop through the pages */
10816 +       len = instr->len;
10817 +
10818 +       instr->state = MTD_ERASING;
10819 +
10820 +       while (len) {
10821 +               /* Check if we have a bad block, we do not erase bad blocks ! */
10822 +               if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
10823 +                       puts ("nand_erase: attempt to erase a bad block at page ");
10824 +                       putx (page);
10825 +                       putnl ();
10826 +                       instr->state = MTD_ERASE_FAILED;
10827 +                       goto erase_exit;
10828 +               }
10829 +
10830 +               /* Invalidate the page cache, if we erase the block which contains
10831 +                  the current cached page */
10832 +               if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
10833 +                       this->pagebuf = -1;
10834 +
10835 +               this->erase_cmd (mtd, page & this->pagemask);
10836 +
10837 +               status = this->waitfunc (mtd, this, FL_ERASING);
10838 +
10839 +               /* See if operation failed and additional status checks are available */
10840 +               if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
10841 +                       status = this->errstat(mtd, this, FL_ERASING, status, page);
10842 +               }
10843 +
10844 +               /* See if block erase succeeded */
10845 +               if (status & NAND_STATUS_FAIL) {
10846 +                       DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
10847 +                       instr->state = MTD_ERASE_FAILED;
10848 +                       instr->fail_addr = (page << this->page_shift);
10849 +                       goto erase_exit;
10850 +               }
10851 +
10852 +               /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
10853 +               if (this->options & BBT_AUTO_REFRESH) {
10854 +                       if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
10855 +                            (page != this->bbt_td->pages[chipnr])) {
10856 +                               rewrite_bbt[chipnr] = (page << this->page_shift);
10857 +                       }
10858 +               }
10859 +
10860 +               /* Increment page address and decrement length */
10861 +               len -= (1 << this->phys_erase_shift);
10862 +               page += pages_per_block;
10863 +
10864 +               /* Check, if we cross a chip boundary */
10865 +               if (len && !(page & this->pagemask)) {
10866 +                       chipnr++;
10867 +                       this->select_chip(mtd, -1);
10868 +                       this->select_chip(mtd, chipnr);
10869 +
10870 +                       /* if BBT requires refresh and BBT-PERCHIP,
10871 +                        *   set the BBT page mask to see if this BBT should be rewritten */
10872 +                       if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
10873 +                               bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
10874 +                       }
10875 +
10876 +               }
10877 +       }
10878 +       instr->state = MTD_ERASE_DONE;
10879 +
10880 +erase_exit:
10881 +
10882 +       ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
10883 +#if 0
10884 +       /* Do call back function */
10885 +       if (!ret)
10886 +               mtd_erase_callback(instr);
10887 +#endif
10888 +
10889 +       /* Deselect and wake up anyone waiting on the device */
10890 +       nand_release_device(mtd);
10891 +
10892 +#if NAND_BBT_SUPPORT
10893 +       /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
10894 +       if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
10895 +               for (chipnr = 0; chipnr < this->numchips; chipnr++) {
10896 +                       if (rewrite_bbt[chipnr]) {
10897 +                               /* update the BBT for chip */
10898 +                               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
10899 +                                       chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
10900 +                               nand_update_bbt (mtd, rewrite_bbt[chipnr]);
10901 +                       }
10902 +               }
10903 +       }
10904 +#endif
10905 +
10906 +       /* Return more or less happy */
10907 +       return ret;
10908 +}
10909 +#endif
10910 +
10911 +/**
10912 + * nand_sync - [MTD Interface] sync
10913 + * @mtd:       MTD device structure
10914 + *
10915 + * Sync is actually a wait for chip ready function
10916 + */
10917 +#if 0 /* not needed */
10918 +static void nand_sync (struct mtd_info *mtd)
10919 +{
10920 +       struct nand_chip *this = mtd->priv;
10921 +
10922 +       DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
10923 +
10924 +       /* Grab the lock and see if the device is available */
10925 +       nand_get_device (this, mtd, FL_SYNCING);
10926 +       /* Release it and go back */
10927 +       nand_release_device (mtd);
10928 +}
10929 +#endif
10930 +
10931 +
10932 +/**
10933 + * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
10934 + * @mtd:       MTD device structure
10935 + * @ofs:       offset relative to mtd start
10936 + */
10937 +static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
10938 +{
10939 +       /* Check for invalid offset */
10940 +       if (ofs > mtd->size)
10941 +               return -EINVAL;
10942 +
10943 +       return nand_block_checkbad (mtd, ofs, 1, 0);
10944 +}
10945 +
10946 +/**
10947 + * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
10948 + * @mtd:       MTD device structure
10949 + * @ofs:       offset relative to mtd start
10950 + */
10951 +#if NAND_WRITE_SUPPORT
10952 +static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
10953 +{
10954 +       struct nand_chip *this = mtd->priv;
10955 +       int ret;
10956 +
10957 +        if ((ret = nand_block_isbad(mtd, ofs))) {
10958 +               /* If it was bad already, return success and do nothing. */
10959 +               if (ret > 0)
10960 +                       return 0;
10961 +               return ret;
10962 +        }
10963 +
10964 +       return this->block_markbad(mtd, ofs);
10965 +}
10966 +#endif
10967 +
10968 +/**
10969 + * nand_suspend - [MTD Interface] Suspend the NAND flash
10970 + * @mtd:       MTD device structure
10971 + */
10972 +#if 0 /* don't need it */
10973 +static int nand_suspend(struct mtd_info *mtd)
10974 +{
10975 +       struct nand_chip *this = mtd->priv;
10976 +
10977 +       return nand_get_device (this, mtd, FL_PM_SUSPENDED);
10978 +}
10979 +#endif
10980 +
10981 +/**
10982 + * nand_resume - [MTD Interface] Resume the NAND flash
10983 + * @mtd:       MTD device structure
10984 + */
10985 +#if 0 /* don't need it */
10986 +static void nand_resume(struct mtd_info *mtd)
10987 +{
10988 +       struct nand_chip *this = mtd->priv;
10989 +
10990 +       if (this->state == FL_PM_SUSPENDED)
10991 +               nand_release_device(mtd);
10992 +       else
10993 +               puts("resume() called for the chip which is not in suspended state\n");
10994 +
10995 +}
10996 +#endif
10997 +
10998 +
10999 +/**
11000 + * nand_scan - [NAND Interface] Scan for the NAND device
11001 + * @mtd:       MTD device structure
11002 + * @maxchips:  Number of chips to scan for
11003 + *
11004 + * This fills out all the not initialized function pointers
11005 + * with the defaults.
11006 + * The flash ID is read and the mtd/chip structures are
11007 + * filled with the appropriate values. Buffers are allocated if
11008 + * they are not provided by the board driver
11009 + *
11010 + */
11011 +int nand_scan (struct mtd_info *mtd, int maxchips)
11012 +{
11013 +       int i, nand_maf_id, nand_dev_id, busw, maf_id;
11014 +       struct nand_chip *this = mtd->priv;
11015 +
11016 +       /* Get buswidth to select the correct functions*/
11017 +       busw = this->options & NAND_BUSWIDTH_16;
11018 +
11019 +       /* check for proper chip_delay setup, set 20us if not */
11020 +       if (!this->chip_delay)
11021 +               this->chip_delay = 20;
11022 +
11023 +       /* check, if a user supplied command function given */
11024 +       if (this->cmdfunc == NULL)
11025 +               this->cmdfunc = nand_command;
11026 +
11027 +       /* check, if a user supplied wait function given */
11028 +       if (this->waitfunc == NULL)
11029 +               this->waitfunc = nand_wait;
11030 +
11031 +       if (!this->select_chip)
11032 +               this->select_chip = nand_select_chip;
11033 +       if (!this->write_byte)
11034 +               this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
11035 +       if (!this->read_byte)
11036 +               this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
11037 +       if (!this->write_word)
11038 +               this->write_word = nand_write_word;
11039 +       if (!this->read_word)
11040 +               this->read_word = nand_read_word;
11041 +       if (!this->block_bad)
11042 +               this->block_bad = nand_block_bad;
11043 +#if NAND_WRITE_SUPPORT
11044 +       if (!this->block_markbad)
11045 +               this->block_markbad = nand_default_block_markbad;
11046 +#endif
11047 +       if (!this->write_buf)
11048 +               this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
11049 +       if (!this->read_buf)
11050 +               this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
11051 +       if (!this->verify_buf)
11052 +               this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
11053 +#if NAND_BBT_SUPPORT
11054 +       if (!this->scan_bbt)
11055 +               this->scan_bbt = nand_default_bbt;
11056 +#endif
11057 +
11058 +       /* Select the device */
11059 +       this->select_chip(mtd, 0);
11060 +
11061 +       /* Send the command for reading device ID */
11062 +       this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11063 +
11064 +       /* Read manufacturer and device IDs */
11065 +       nand_maf_id = this->read_byte(mtd);
11066 +       nand_dev_id = this->read_byte(mtd);
11067 +
11068 +       /* Print and store flash device information */
11069 +       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
11070 +
11071 +               if (nand_dev_id != nand_flash_ids[i].id)
11072 +                       continue;
11073 +
11074 +               if (!mtd->name) mtd->name = nand_flash_ids[i].name;
11075 +               this->chipsize = nand_flash_ids[i].chipsize << 20;
11076 +
11077 +               /* New devices have all the information in additional id bytes */
11078 +               if (!nand_flash_ids[i].pagesize) {
11079 +                       int extid;
11080 +                       /* The 3rd id byte contains non relevant data ATM */
11081 +                       extid = this->read_byte(mtd);
11082 +                       /* The 4th id byte is the important one */
11083 +                       extid = this->read_byte(mtd);
11084 +                       /* Calc pagesize */
11085 +                       mtd->oobblock = 1024 << (extid & 0x3);
11086 +                       extid >>= 2;
11087 +                       /* Calc oobsize */
11088 +                       mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
11089 +                       extid >>= 2;
11090 +                       /* Calc blocksize. Blocksize is multiples of 64KiB */
11091 +                       mtd->erasesize = (64 * 1024)  << (extid & 0x03);
11092 +                       extid >>= 2;
11093 +                       /* Get buswidth information */
11094 +                       busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
11095 +
11096 +               } else {
11097 +                       /* Old devices have this data hardcoded in the
11098 +                        * device id table */
11099 +                       mtd->erasesize = nand_flash_ids[i].erasesize;
11100 +                       mtd->oobblock = nand_flash_ids[i].pagesize;
11101 +                       mtd->oobsize = mtd->oobblock / 32;
11102 +                       busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
11103 +               }
11104 +
11105 +               /* Try to identify manufacturer */
11106 +               for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
11107 +                       if (nand_manuf_ids[maf_id].id == nand_maf_id)
11108 +                               break;
11109 +               }
11110 +
11111 +               /* Check, if buswidth is correct. Hardware drivers should set
11112 +                * this correct ! */
11113 +               if (busw != (this->options & NAND_BUSWIDTH_16)) {
11114 +#if 0
11115 +                       puts ("Manufacturer ID: ");
11116 +                       putx (nand_maf_id);
11117 +                       puts (", Chip ID: ");
11118 +                       putx (nand_dev_id);
11119 +                       puts (" (");
11120 +                       puts (nand_manuf_ids[maf_id].name);
11121 +                       putc (' ');
11122 +                       puts (mtd->name);
11123 +                       puts (")\r\n");
11124 +#endif
11125 +                       puts ("Expected NAND bus width ");
11126 +                       putx ((this->options & NAND_BUSWIDTH_16) ? 16 : 8);
11127 +                       puts (",found ");
11128 +                       putx (busw ? 16 : 8);
11129 +                       putnl();
11130 +                       this->select_chip(mtd, -1);
11131 +                       return 1;
11132 +               }
11133 +
11134 +               /* Calculate the address shift from the page size */
11135 +               this->page_shift = ffs(mtd->oobblock) - 1;
11136 +               this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
11137 +               this->chip_shift = ffs(this->chipsize) - 1;
11138 +
11139 +               /* Set the bad block position */
11140 +               this->badblockpos = mtd->oobblock > 512 ?
11141 +                       NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
11142 +
11143 +               /* Get chip options, preserve non chip based options */
11144 +               this->options &= ~NAND_CHIPOPTIONS_MSK;
11145 +               this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
11146 +               /* Set this as a default. Board drivers can override it, if neccecary */
11147 +               this->options |= NAND_NO_AUTOINCR;
11148 +               /* Check if this is a not a samsung device. Do not clear the options
11149 +                * for chips which are not having an extended id.
11150 +                */
11151 +               if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
11152 +                       this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
11153 +
11154 +#if NAND_ERASE_SUPPORT
11155 +               /* Check for AND chips with 4 page planes */
11156 +               if (this->options & NAND_4PAGE_ARRAY)
11157 +                       this->erase_cmd = multi_erase_cmd;
11158 +               else
11159 +                       this->erase_cmd = single_erase_cmd;
11160 +#endif
11161 +
11162 +               /* Do not replace user supplied command function ! */
11163 +               if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
11164 +                       this->cmdfunc = nand_command_lp;
11165 +
11166 +               puts ("Manufacturer ID / Chip ID: ");
11167 +               putx (nand_maf_id << 8 | nand_dev_id);
11168 +               puts (" (");
11169 +               puts (nand_manuf_ids[maf_id].name);
11170 +               putc (' ');
11171 +               puts (nand_flash_ids[i].name);
11172 +               puts (")\r\n");
11173 +               break;
11174 +       }
11175 +
11176 +       if (!nand_flash_ids[i].name) {
11177 +               puts ("No NAND device found!!!\r\n");
11178 +               this->select_chip(mtd, -1);
11179 +               return 1;
11180 +       }
11181 +
11182 +#if NAND_MULTICHIP_SUPPORT
11183 +       for (i=1; i < maxchips; i++) {
11184 +               this->select_chip(mtd, i);
11185 +
11186 +               /* Send the command for reading device ID */
11187 +               this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11188 +
11189 +               /* Read manufacturer and device IDs */
11190 +               if (nand_maf_id != this->read_byte(mtd) ||
11191 +                   nand_dev_id != this->read_byte(mtd))
11192 +                       break;
11193 +       }
11194 +       if (i > 1) {
11195 +               putx (i);
11196 +               puts (" NAND chips detected\r\n");
11197 +       }
11198 +#endif
11199 +
11200 +       /* Allocate buffers, if neccecary */
11201 +       if (!this->oob_buf) {
11202 +               size_t len;
11203 +               len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
11204 +               this->oob_buf = malloc (len);
11205 +               if (!this->oob_buf) {
11206 +                       puts ("nand_scan(): Cannot allocate oob_buf\r\n");
11207 +                       return -ENOMEM;
11208 +               }
11209 +               this->options |= NAND_OOBBUF_ALLOC;
11210 +       }
11211 +
11212 +       if (!this->data_buf) {
11213 +               size_t len;
11214 +               len = mtd->oobblock + mtd->oobsize;
11215 +               this->data_buf = malloc (len);
11216 +               if (!this->data_buf) {
11217 +                       if (this->options & NAND_OOBBUF_ALLOC)
11218 +                               free (this->oob_buf);
11219 +                       puts ("nand_scan(): Cannot allocate data_buf\r\n");
11220 +                       return -ENOMEM;
11221 +               }
11222 +               this->options |= NAND_DATABUF_ALLOC;
11223 +       }
11224 +
11225 +#if NAND_MULTICHIP_SUPP0RT
11226 +       /* Store the number of chips and calc total size for mtd */
11227 +       this->numchips = i;
11228 +       mtd->size = i * this->chipsize;
11229 +#else
11230 +       /* Store the number of chips and calc total size for mtd */
11231 +       this->numchips = 1;
11232 +       mtd->size = this->chipsize;
11233 +#endif
11234 +
11235 +       /* Convert chipsize to number of pages per chip -1. */
11236 +       this->pagemask = (this->chipsize >> this->page_shift) - 1;
11237 +       /* Preset the internal oob buffer */
11238 +       memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
11239 +
11240 +       /* If no default placement scheme is given, select an
11241 +        * appropriate one */
11242 +       if (!this->autooob) {
11243 +               /* Select the appropriate default oob placement scheme for
11244 +                * placement agnostic filesystems */
11245 +               switch (mtd->oobsize) {
11246 +               case 8:
11247 +                       this->autooob = &nand_oob_8;
11248 +                       break;
11249 +               case 16:
11250 +                       this->autooob = &nand_oob_16;
11251 +                       break;
11252 +               case 64:
11253 +                       this->autooob = &nand_oob_64;
11254 +                       break;
11255 +               default:
11256 +                       puts ("No oob scheme defined for oobsize ");
11257 +                       putx (mtd->oobsize);
11258 +                       putnl ();
11259 +                       BUG();
11260 +               }
11261 +       }
11262 +
11263 +       /* The number of bytes available for the filesystem to place fs dependend
11264 +        * oob data */
11265 +       mtd->oobavail = 0;
11266 +       for (i = 0; this->autooob->oobfree[i][1]; i++)
11267 +               mtd->oobavail += this->autooob->oobfree[i][1];
11268 +
11269 +       /*
11270 +        * check ECC mode, default to software
11271 +        * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
11272 +        * fallback to software ECC
11273 +       */
11274 +       this->eccsize = 256;    /* set default eccsize */
11275 +       this->eccbytes = 3;
11276 +
11277 +       switch (this->eccmode) {
11278 +#if NAND_HWECC_SUPPORT
11279 +       case NAND_ECC_HW12_2048:
11280 +               if (mtd->oobblock < 2048) {
11281 +                       puts ("2048 byte HW ECC not possible on ");
11282 +                       putx (mtd->oobblock);
11283 +                       puts (" byte page size, fallback to SW ECC\r\n");
11284 +                       this->eccmode = NAND_ECC_SOFT;
11285 +                       this->calculate_ecc = nand_calculate_ecc;
11286 +                       this->correct_data = nand_correct_data;
11287 +               } else
11288 +                       this->eccsize = 2048;
11289 +               break;
11290 +
11291 +       case NAND_ECC_HW3_512:
11292 +       case NAND_ECC_HW6_512:
11293 +       case NAND_ECC_HW8_512:
11294 +               if (mtd->oobblock == 256) {
11295 +                       puts ("512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC\r\n");
11296 +                       this->eccmode = NAND_ECC_SOFT;
11297 +                       this->calculate_ecc = nand_calculate_ecc;
11298 +                       this->correct_data = nand_correct_data;
11299 +               } else
11300 +                       this->eccsize = 512; /* set eccsize to 512 */
11301 +               break;
11302 +
11303 +       case NAND_ECC_HW3_256:
11304 +               break;
11305 +#endif
11306 +
11307 +       case NAND_ECC_NONE:
11308 +               puts ("NAND_ECC_NONE selected by board driver. This is not recommended !!\r\n");
11309 +               this->eccmode = NAND_ECC_NONE;
11310 +               break;
11311 +
11312 +       case NAND_ECC_SOFT:
11313 +               this->calculate_ecc = nand_calculate_ecc;
11314 +               this->correct_data = nand_correct_data;
11315 +               break;
11316 +
11317 +       default:
11318 +               puts ("Invalid NAND_ECC_MODE ");
11319 +               putx (this->eccmode);
11320 +               putnl ();
11321 +               BUG();
11322 +       }
11323 +
11324 +       /* Check hardware ecc function availability and adjust number of ecc bytes per
11325 +        * calculation step
11326 +       */
11327 +       switch (this->eccmode) {
11328 +       case NAND_ECC_HW12_2048:
11329 +               this->eccbytes += 4;
11330 +       case NAND_ECC_HW8_512:
11331 +               this->eccbytes += 2;
11332 +       case NAND_ECC_HW6_512:
11333 +               this->eccbytes += 3;
11334 +       case NAND_ECC_HW3_512:
11335 +       case NAND_ECC_HW3_256:
11336 +               if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
11337 +                       break;
11338 +               puts ("No ECC functions supplied, Hardware ECC not possible\r\n");
11339 +               BUG();
11340 +       }
11341 +
11342 +       mtd->eccsize = this->eccsize;
11343 +
11344 +       /* Set the number of read / write steps for one page to ensure ECC generation */
11345 +       switch (this->eccmode) {
11346 +       case NAND_ECC_HW12_2048:
11347 +               this->eccsteps = mtd->oobblock / 2048;
11348 +               break;
11349 +       case NAND_ECC_HW3_512:
11350 +       case NAND_ECC_HW6_512:
11351 +       case NAND_ECC_HW8_512:
11352 +               this->eccsteps = mtd->oobblock / 512;
11353 +               break;
11354 +       case NAND_ECC_HW3_256:
11355 +       case NAND_ECC_SOFT:
11356 +               this->eccsteps = mtd->oobblock / 256;
11357 +               break;
11358 +
11359 +       case NAND_ECC_NONE:
11360 +               this->eccsteps = 1;
11361 +               break;
11362 +       }
11363 +
11364 +       /* Initialize state, waitqueue and spinlock */
11365 +       this->state = FL_READY;
11366 +#if 0
11367 +       init_waitqueue_head (&this->wq);
11368 +       spin_lock_init (&this->chip_lock);
11369 +#endif
11370 +
11371 +       /* De-select the device */
11372 +       this->select_chip(mtd, -1);
11373 +
11374 +       /* Invalidate the pagebuffer reference */
11375 +       this->pagebuf = -1;
11376 +
11377 +       /* Fill in remaining MTD driver data */
11378 +       mtd->type = MTD_NANDFLASH;
11379 +       mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
11380 +       mtd->ecctype = MTD_ECC_SW;
11381 +#if NAND_ERASE_SUPPORT
11382 +       mtd->erase = nand_erase;
11383 +#endif
11384 +#if 0 /* not needed */
11385 +       mtd->point = NULL;
11386 +       mtd->unpoint = NULL;
11387 +#endif
11388 +       mtd->read = nand_read;
11389 +#if NAND_WRITE_SUPPORT
11390 +       mtd->write = nand_write;
11391 +#endif
11392 +       mtd->read_ecc = nand_read_ecc;
11393 +#if NAND_WRITE_SUPPORT
11394 +       mtd->write_ecc = nand_write_ecc;
11395 +#endif
11396 +       mtd->read_oob = nand_read_oob;
11397 +#if NAND_WRITE_SUPPORT
11398 +       mtd->write_oob = nand_write_oob;
11399 +#endif
11400 +#if NAND_KVEC_SUPPORT
11401 +       mtd->readv = NULL;
11402 +#endif
11403 +#if NAND_WRITE_SUPPORT && NAND_KVEC_SUPPORT
11404 +       mtd->writev = nand_writev;
11405 +       mtd->writev_ecc = nand_writev_ecc;
11406 +#endif
11407 +#if 0 /* not needed */
11408 +       mtd->sync = nand_sync;
11409 +       mtd->lock = NULL;
11410 +       mtd->unlock = NULL;
11411 +       mtd->suspend = nand_suspend;
11412 +       mtd->resume = nand_resume;
11413 +#endif
11414 +       mtd->block_isbad = nand_block_isbad;
11415 +#if NAND_WRITE_SUPPORT
11416 +       mtd->block_markbad = nand_block_markbad;
11417 +#endif
11418 +
11419 +       /* and make the autooob the default one */
11420 +       memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
11421 +
11422 +#ifdef THIS_MODULE /* normally isn't for us */
11423 +       mtd->owner = THIS_MODULE;
11424 +#endif
11425 +
11426 +       /* Check, if we should skip the bad block table scan */
11427 +       if (this->options & NAND_SKIP_BBTSCAN)
11428 +               return 0;
11429 +
11430 +#if NAND_BBT_SUPPORT
11431 +       /* Build bad block table */
11432 +       return this->scan_bbt (mtd);
11433 +#else
11434 +       return -1;
11435 +#endif
11436 +}
11437 +
11438 +/**
11439 + * nand_release - [NAND Interface] Free resources held by the NAND device
11440 + * @mtd:       MTD device structure
11441 +*/
11442 +#if 0 /* don't need it */
11443 +void nand_release (struct mtd_info *mtd)
11444 +{
11445 +       struct nand_chip *this = mtd->priv;
11446 +
11447 +#if 0
11448 +#ifdef CONFIG_MTD_PARTITIONS
11449 +       /* Deregister partitions */
11450 +       del_mtd_partitions (mtd);
11451 +#endif
11452 +       /* Deregister the device */
11453 +       del_mtd_device (mtd);
11454 +#endif
11455 +
11456 +       /* Free bad block table memory */
11457 +       free (this->bbt);
11458 +       /* Buffer allocated by nand_scan ? */
11459 +       if (this->options & NAND_OOBBUF_ALLOC)
11460 +               free (this->oob_buf);
11461 +       /* Buffer allocated by nand_scan ? */
11462 +       if (this->options & NAND_DATABUF_ALLOC)
11463 +               free (this->data_buf);
11464 +}
11465 +#endif
11466 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_bbt.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_bbt.c
11467 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_bbt.c        1970-01-01 01:00:00.000000000 +0100
11468 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_bbt.c        2006-11-10 09:55:58.000000000 +0100
11469 @@ -0,0 +1,1151 @@
11470 +/*
11471 + *  drivers/mtd/nand_bbt.c
11472 + *
11473 + *  Overview:
11474 + *   Bad block table support for the NAND driver
11475 + *
11476 + *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
11477 + *
11478 + * $Id: nand_bbt.c,v 1.5 2006/11/10 08:55:58 ricardw Exp $
11479 + *
11480 + * This program is free software; you can redistribute it and/or modify
11481 + * it under the terms of the GNU General Public License version 2 as
11482 + * published by the Free Software Foundation.
11483 + *
11484 + * Description:
11485 + *
11486 + * When nand_scan_bbt is called, then it tries to find the bad block table
11487 + * depending on the options in the bbt descriptor(s). If a bbt is found
11488 + * then the contents are read and the memory based bbt is created. If a
11489 + * mirrored bbt is selected then the mirror is searched too and the
11490 + * versions are compared. If the mirror has a greater version number
11491 + * than the mirror bbt is used to build the memory based bbt.
11492 + * If the tables are not versioned, then we "or" the bad block information.
11493 + * If one of the bbt's is out of date or does not exist it is (re)created.
11494 + * If no bbt exists at all then the device is scanned for factory marked
11495 + * good / bad blocks and the bad block tables are created.
11496 + *
11497 + * For manufacturer created bbts like the one found on M-SYS DOC devices
11498 + * the bbt is searched and read but never created
11499 + *
11500 + * The autogenerated bad block table is located in the last good blocks
11501 + * of the device. The table is mirrored, so it can be updated eventually.
11502 + * The table is marked in the oob area with an ident pattern and a version
11503 + * number which indicates which of both tables is more up to date.
11504 + *
11505 + * The table uses 2 bits per block
11506 + * 11b:        block is good
11507 + * 00b:        block is factory marked bad
11508 + * 01b, 10b:   block is marked bad due to wear
11509 + *
11510 + * The memory bad block table uses the following scheme:
11511 + * 00b:                block is good
11512 + * 01b:                block is marked bad due to wear
11513 + * 10b:                block is reserved (to protect the bbt area)
11514 + * 11b:                block is factory marked bad
11515 + *
11516 + * Multichip devices like DOC store the bad block info per floor.
11517 + *
11518 + * Following assumptions are made:
11519 + * - bbts start at a page boundary, if autolocated on a block boundary
11520 + * - the space neccecary for a bbt in FLASH does not exceed a block boundary
11521 + *
11522 + */
11523 +
11524 +#if 0
11525 +#include <linux/slab.h>
11526 +#endif
11527 +
11528 +#include <linux/types.h>
11529 +#include "mtd.h"
11530 +#include "nand.h"
11531 +#include "nand_ecc.h"
11532 +
11533 +#if 0
11534 +#include <linux/mtd/compatmac.h>
11535 +#include <linux/bitops.h>
11536 +#endif
11537 +
11538 +#include <linux/delay.h>
11539 +
11540 +#include "lib.h"
11541 +
11542 +
11543 +/**
11544 + * check_pattern - [GENERIC] check if a pattern is in the buffer
11545 + * @buf:       the buffer to search
11546 + * @len:       the length of buffer to search
11547 + * @paglen:    the pagelength
11548 + * @td:                search pattern descriptor
11549 + *
11550 + * Check for a pattern at the given place. Used to search bad block
11551 + * tables and good / bad block identifiers.
11552 + * If the SCAN_EMPTY option is set then check, if all bytes except the
11553 + * pattern area contain 0xff
11554 + *
11555 +*/
11556 +static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
11557 +{
11558 +       int i, end = 0;
11559 +       uint8_t *p = buf;
11560 +
11561 +       end = paglen + td->offs;
11562 +       if (td->options & NAND_BBT_SCANEMPTY) {
11563 +               for (i = 0; i < end; i++) {
11564 +                       if (p[i] != 0xff)
11565 +                               return -1;
11566 +               }
11567 +       }
11568 +       p += end;
11569 +
11570 +       /* Compare the pattern */
11571 +       for (i = 0; i < td->len; i++) {
11572 +               if (p[i] != td->pattern[i])
11573 +                       return -1;
11574 +       }
11575 +
11576 +       if (td->options & NAND_BBT_SCANEMPTY) {
11577 +               p += td->len;
11578 +               end += td->len;
11579 +               for (i = end; i < len; i++) {
11580 +                       if (*p++ != 0xff)
11581 +                               return -1;
11582 +               }
11583 +       }
11584 +       return 0;
11585 +}
11586 +
11587 +/**
11588 + * check_short_pattern - [GENERIC] check if a pattern is in the buffer
11589 + * @buf:       the buffer to search
11590 + * @td:                search pattern descriptor
11591 + *
11592 + * Check for a pattern at the given place. Used to search bad block
11593 + * tables and good / bad block identifiers. Same as check_pattern, but
11594 + * no optional empty check
11595 + *
11596 +*/
11597 +static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
11598 +{
11599 +       int i;
11600 +       uint8_t *p = buf;
11601 +
11602 +       /* Compare the pattern */
11603 +       for (i = 0; i < td->len; i++) {
11604 +               if (p[td->offs + i] != td->pattern[i])
11605 +                       return -1;
11606 +       }
11607 +       return 0;
11608 +}
11609 +
11610 +/**
11611 + * read_bbt - [GENERIC] Read the bad block table starting from page
11612 + * @mtd:       MTD device structure
11613 + * @buf:       temporary buffer
11614 + * @page:      the starting page
11615 + * @num:       the number of bbt descriptors to read
11616 + * @bits:      number of bits per block
11617 + * @offs:      offset in the memory table
11618 + * @reserved_block_code:       Pattern to identify reserved blocks
11619 + *
11620 + * Read the bad block table starting from page.
11621 + *
11622 + */
11623 +static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
11624 +       int bits, int offs, int reserved_block_code)
11625 +{
11626 +       int res, i, j, act = 0;
11627 +       struct nand_chip *this = mtd->priv;
11628 +       size_t retlen, len, totlen;
11629 +       loff_t from;
11630 +       uint8_t msk = (uint8_t) ((1 << bits) - 1);
11631 +
11632 +       totlen = (num * bits) >> 3;
11633 +       from = ((loff_t)page) << this->page_shift;
11634 +
11635 +       while (totlen) {
11636 +               len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
11637 +               res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
11638 +               if (res < 0) {
11639 +                       if (retlen != len) {
11640 +                               puts ("nand_bbt: Error reading bad block table\n");
11641 +                               return res;
11642 +                       }
11643 +                       puts ("nand_bbt: ECC error while reading bad block table\n");
11644 +               }
11645 +
11646 +               /* Analyse data */
11647 +               for (i = 0; i < len; i++) {
11648 +                       uint8_t dat = buf[i];
11649 +                       for (j = 0; j < 8; j += bits, act += 2) {
11650 +                               uint8_t tmp = (dat >> j) & msk;
11651 +                               if (tmp == msk)
11652 +                                       continue;
11653 +                               if (reserved_block_code &&
11654 +                                   (tmp == reserved_block_code)) {
11655 +                                       puts ("nand_read_bbt: Reserved block at");
11656 +                                       putx (((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
11657 +                                       putnl ();
11658 +                                       this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
11659 +                                       continue;
11660 +                               }
11661 +                               /* Leave it for now, if its matured we can move this
11662 +                                * message to MTD_DEBUG_LEVEL0 */
11663 +                               puts ("nand_read_bbt: Bad block at ");
11664 +                               putx (((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
11665 +                               putnl ();
11666 +                               /* Factory marked bad or worn out ? */
11667 +                               if (tmp == 0)
11668 +                                       this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
11669 +                               else
11670 +                                       this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
11671 +                       }
11672 +               }
11673 +               totlen -= len;
11674 +               from += len;
11675 +       }
11676 +       return 0;
11677 +}
11678 +
11679 +/**
11680 + * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
11681 + * @mtd:       MTD device structure
11682 + * @buf:       temporary buffer
11683 + * @td:                descriptor for the bad block table
11684 + * @chip:      read the table for a specific chip, -1 read all chips.
11685 + *             Applies only if NAND_BBT_PERCHIP option is set
11686 + *
11687 + * Read the bad block table for all chips starting at a given page
11688 + * We assume that the bbt bits are in consecutive order.
11689 +*/
11690 +static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
11691 +{
11692 +       struct nand_chip *this = mtd->priv;
11693 +       int res = 0, i;
11694 +       int bits;
11695 +
11696 +       bits = td->options & NAND_BBT_NRBITS_MSK;
11697 +       if (td->options & NAND_BBT_PERCHIP) {
11698 +               int offs = 0;
11699 +               for (i = 0; i < this->numchips; i++) {
11700 +                       if (chip == -1 || chip == i)
11701 +                               res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
11702 +                       if (res)
11703 +                               return res;
11704 +                       offs += this->chipsize >> (this->bbt_erase_shift + 2);
11705 +               }
11706 +       } else {
11707 +               res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
11708 +               if (res)
11709 +                       return res;
11710 +       }
11711 +       return 0;
11712 +}
11713 +
11714 +/**
11715 + * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
11716 + * @mtd:       MTD device structure
11717 + * @buf:       temporary buffer
11718 + * @td:                descriptor for the bad block table
11719 + * @md:                descriptor for the bad block table mirror
11720 + *
11721 + * Read the bad block table(s) for all chips starting at a given page
11722 + * We assume that the bbt bits are in consecutive order.
11723 + *
11724 +*/
11725 +static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
11726 +       struct nand_bbt_descr *md)
11727 +{
11728 +       struct nand_chip *this = mtd->priv;
11729 +
11730 +       /* Read the primary version, if available */
11731 +       if (td->options & NAND_BBT_VERSION) {
11732 +               nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
11733 +               td->version[0] = buf[mtd->oobblock + td->veroffs];
11734 +               puts ("Bad block table at page ");
11735 +               putx (td->pages[0]);
11736 +               puts (", version ");
11737 +               putx (td->version[0]);
11738 +               putnl ();
11739 +       }
11740 +
11741 +       /* Read the mirror version, if available */
11742 +       if (md && (md->options & NAND_BBT_VERSION)) {
11743 +               nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
11744 +               md->version[0] = buf[mtd->oobblock + md->veroffs];
11745 +               puts ("Bad block table at page ");
11746 +               putx (md->pages[0]);
11747 +               puts (", version ");
11748 +               putx (md->version[0]);
11749 +               putnl ();
11750 +       }
11751 +
11752 +       return 1;
11753 +}
11754 +
11755 +/**
11756 + * create_bbt - [GENERIC] Create a bad block table by scanning the device
11757 + * @mtd:       MTD device structure
11758 + * @buf:       temporary buffer
11759 + * @bd:                descriptor for the good/bad block search pattern
11760 + * @chip:      create the table for a specific chip, -1 read all chips.
11761 + *             Applies only if NAND_BBT_PERCHIP option is set
11762 + *
11763 + * Create a bad block table by scanning the device
11764 + * for the given good/bad block identify pattern
11765 + */
11766 +static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
11767 +{
11768 +       struct nand_chip *this = mtd->priv;
11769 +       int i, j, numblocks, len, scanlen;
11770 +       int startblock;
11771 +       loff_t from;
11772 +       size_t readlen, ooblen;
11773 +
11774 +       puts ("Scanning device for bad blocks\n");
11775 +
11776 +       if (bd->options & NAND_BBT_SCANALLPAGES)
11777 +               len = 1 << (this->bbt_erase_shift - this->page_shift);
11778 +       else {
11779 +               if (bd->options & NAND_BBT_SCAN2NDPAGE)
11780 +                       len = 2;
11781 +               else
11782 +                       len = 1;
11783 +       }
11784 +
11785 +       if (!(bd->options & NAND_BBT_SCANEMPTY)) {
11786 +               /* We need only read few bytes from the OOB area */
11787 +               scanlen = ooblen = 0;
11788 +               readlen = bd->len;
11789 +       } else {
11790 +               /* Full page content should be read */
11791 +               scanlen = mtd->oobblock + mtd->oobsize;
11792 +               readlen = len * mtd->oobblock;
11793 +               ooblen = len * mtd->oobsize;
11794 +       }
11795 +
11796 +       if (chip == -1) {
11797 +               /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
11798 +                * makes shifting and masking less painful */
11799 +               numblocks = mtd->size >> (this->bbt_erase_shift - 1);
11800 +               startblock = 0;
11801 +               from = 0;
11802 +       } else {
11803 +               if (chip >= this->numchips) {
11804 +                       puts ("create_bbt(): chipnr (");
11805 +                       putx (chip + 1);
11806 +                       puts (" > available chips ");
11807 +                       putx (this->numchips);
11808 +                       putnl ();
11809 +                       return -EINVAL;
11810 +               }
11811 +               numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
11812 +               startblock = chip * numblocks;
11813 +               numblocks += startblock;
11814 +               from = startblock << (this->bbt_erase_shift - 1);
11815 +       }
11816 +
11817 +       for (i = startblock; i < numblocks;) {
11818 +               int ret;
11819 +
11820 +               if (bd->options & NAND_BBT_SCANEMPTY)
11821 +                       if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
11822 +                               return ret;
11823 +
11824 +               for (j = 0; j < len; j++) {
11825 +                       if (!(bd->options & NAND_BBT_SCANEMPTY)) {
11826 +                               size_t retlen;
11827 +
11828 +                               /* Read the full oob until read_oob is fixed to
11829 +                                * handle single byte reads for 16 bit buswidth */
11830 +                               ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
11831 +                                                       mtd->oobsize, &retlen, buf);
11832 +                               if (ret)
11833 +                                       return ret;
11834 +
11835 +                               if (check_short_pattern (buf, bd)) {
11836 +                                       this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11837 +                                       puts ("Bad eraseblock ");
11838 +                                       putx (i >> 1);
11839 +                                       puts (" at ");
11840 +                                       putx ((unsigned int) from);
11841 +                                       putnl ();
11842 +                                       break;
11843 +                               }
11844 +                       } else {
11845 +                               if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
11846 +                                       this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11847 +                                       puts ("Bad eraseblock ");
11848 +                                       putx (i >> 1);
11849 +                                       puts (" at ");
11850 +                                       putx ((unsigned int) from);
11851 +                                       putnl ();
11852 +                                       break;
11853 +                               }
11854 +                       }
11855 +               }
11856 +               i += 2;
11857 +               from += (1 << this->bbt_erase_shift);
11858 +       }
11859 +       return 0;
11860 +}
11861 +
11862 +/**
11863 + * search_bbt - [GENERIC] scan the device for a specific bad block table
11864 + * @mtd:       MTD device structure
11865 + * @buf:       temporary buffer
11866 + * @td:                descriptor for the bad block table
11867 + *
11868 + * Read the bad block table by searching for a given ident pattern.
11869 + * Search is preformed either from the beginning up or from the end of
11870 + * the device downwards. The search starts always at the start of a
11871 + * block.
11872 + * If the option NAND_BBT_PERCHIP is given, each chip is searched
11873 + * for a bbt, which contains the bad block information of this chip.
11874 + * This is neccecary to provide support for certain DOC devices.
11875 + *
11876 + * The bbt ident pattern resides in the oob area of the first page
11877 + * in a block.
11878 + */
11879 +static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
11880 +{
11881 +       struct nand_chip *this = mtd->priv;
11882 +       int i, chips;
11883 +       int bits, startblock, block, dir;
11884 +       int scanlen = mtd->oobblock + mtd->oobsize;
11885 +       int bbtblocks;
11886 +
11887 +       /* Search direction top -> down ? */
11888 +       if (td->options & NAND_BBT_LASTBLOCK) {
11889 +               startblock = (mtd->size >> this->bbt_erase_shift) -1;
11890 +               dir = -1;
11891 +       } else {
11892 +               startblock = 0;
11893 +               dir = 1;
11894 +       }
11895 +
11896 +       /* Do we have a bbt per chip ? */
11897 +       if (td->options & NAND_BBT_PERCHIP) {
11898 +               chips = this->numchips;
11899 +               bbtblocks = this->chipsize >> this->bbt_erase_shift;
11900 +               startblock &= bbtblocks - 1;
11901 +       } else {
11902 +               chips = 1;
11903 +               bbtblocks = mtd->size >> this->bbt_erase_shift;
11904 +       }
11905 +
11906 +       /* Number of bits for each erase block in the bbt */
11907 +       bits = td->options & NAND_BBT_NRBITS_MSK;
11908 +
11909 +       for (i = 0; i < chips; i++) {
11910 +               /* Reset version information */
11911 +               td->version[i] = 0;
11912 +               td->pages[i] = -1;
11913 +               /* Scan the maximum number of blocks */
11914 +               for (block = 0; block < td->maxblocks; block++) {
11915 +                       int actblock = startblock + dir * block;
11916 +                       /* Read first page */
11917 +                       nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
11918 +                       if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
11919 +                               td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
11920 +                               if (td->options & NAND_BBT_VERSION) {
11921 +                                       td->version[i] = buf[mtd->oobblock + td->veroffs];
11922 +                               }
11923 +                               break;
11924 +                       }
11925 +               }
11926 +               startblock += this->chipsize >> this->bbt_erase_shift;
11927 +       }
11928 +       /* Check, if we found a bbt for each requested chip */
11929 +       for (i = 0; i < chips; i++) {
11930 +               if (td->pages[i] == -1) {
11931 +                       puts ("Bad block table not found for chip ");
11932 +                       putx (i);
11933 +                       putnl ();
11934 +               } else {
11935 +                       puts ("Bad block table found at page ");
11936 +                       putx (td->pages[i]);
11937 +                       puts (" version ");
11938 +                       putx (td->version[i]);
11939 +                       putnl ();
11940 +               }
11941 +       }
11942 +       return 0;
11943 +}
11944 +
11945 +/**
11946 + * search_read_bbts - [GENERIC] scan the device for bad block table(s)
11947 + * @mtd:       MTD device structure
11948 + * @buf:       temporary buffer
11949 + * @td:                descriptor for the bad block table
11950 + * @md:                descriptor for the bad block table mirror
11951 + *
11952 + * Search and read the bad block table(s)
11953 +*/
11954 +static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
11955 +       struct nand_bbt_descr *td, struct nand_bbt_descr *md)
11956 +{
11957 +       /* Search the primary table */
11958 +       search_bbt (mtd, buf, td);
11959 +
11960 +       /* Search the mirror table */
11961 +       if (md)
11962 +               search_bbt (mtd, buf, md);
11963 +
11964 +       /* Force result check */
11965 +       return 1;
11966 +}
11967 +
11968 +
11969 +/**
11970 + * write_bbt - [GENERIC] (Re)write the bad block table
11971 + *
11972 + * @mtd:       MTD device structure
11973 + * @buf:       temporary buffer
11974 + * @td:                descriptor for the bad block table
11975 + * @md:                descriptor for the bad block table mirror
11976 + * @chipsel:   selector for a specific chip, -1 for all
11977 + *
11978 + * (Re)write the bad block table
11979 + *
11980 +*/
11981 +static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
11982 +       struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
11983 +{
11984 +       struct nand_chip *this = mtd->priv;
11985 +       struct nand_oobinfo oobinfo;
11986 +       struct erase_info einfo;
11987 +       int i, j, res, chip = 0;
11988 +       int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
11989 +       int nrchips, bbtoffs, pageoffs;
11990 +       uint8_t msk[4];
11991 +       uint8_t rcode = td->reserved_block_code;
11992 +       size_t retlen, len = 0;
11993 +       loff_t to;
11994 +
11995 +       if (!rcode)
11996 +               rcode = 0xff;
11997 +       /* Write bad block table per chip rather than per device ? */
11998 +       if (td->options & NAND_BBT_PERCHIP) {
11999 +               numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
12000 +               /* Full device write or specific chip ? */
12001 +               if (chipsel == -1) {
12002 +                       nrchips = this->numchips;
12003 +               } else {
12004 +                       nrchips = chipsel + 1;
12005 +                       chip = chipsel;
12006 +               }
12007 +       } else {
12008 +               numblocks = (int) (mtd->size >> this->bbt_erase_shift);
12009 +               nrchips = 1;
12010 +       }
12011 +
12012 +       /* Loop through the chips */
12013 +       for (; chip < nrchips; chip++) {
12014 +
12015 +               /* There was already a version of the table, reuse the page
12016 +                * This applies for absolute placement too, as we have the
12017 +                * page nr. in td->pages.
12018 +                */
12019 +               if (td->pages[chip] != -1) {
12020 +                       page = td->pages[chip];
12021 +                       goto write;
12022 +               }
12023 +
12024 +               /* Automatic placement of the bad block table */
12025 +               /* Search direction top -> down ? */
12026 +               if (td->options & NAND_BBT_LASTBLOCK) {
12027 +                       startblock = numblocks * (chip + 1) - 1;
12028 +                       dir = -1;
12029 +               } else {
12030 +                       startblock = chip * numblocks;
12031 +                       dir = 1;
12032 +               }
12033 +
12034 +               for (i = 0; i < td->maxblocks; i++) {
12035 +                       int block = startblock + dir * i;
12036 +                       /* Check, if the block is bad */
12037 +                       switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) {
12038 +                       case 0x01:
12039 +                       case 0x03:
12040 +                               continue;
12041 +                       }
12042 +                       page = block << (this->bbt_erase_shift - this->page_shift);
12043 +                       /* Check, if the block is used by the mirror table */
12044 +                       if (!md || md->pages[chip] != page)
12045 +                               goto write;
12046 +               }
12047 +               puts ("No space left to write bad block table\r\n");
12048 +               return -ENOSPC;
12049 +write:
12050 +
12051 +               /* Set up shift count and masks for the flash table */
12052 +               bits = td->options & NAND_BBT_NRBITS_MSK;
12053 +               switch (bits) {
12054 +               case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break;
12055 +               case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break;
12056 +               case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break;
12057 +               case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
12058 +               default: return -EINVAL;
12059 +               }
12060 +
12061 +               bbtoffs = chip * (numblocks >> 2);
12062 +
12063 +               to = ((loff_t) page) << this->page_shift;
12064 +
12065 +               memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
12066 +               oobinfo.useecc = MTD_NANDECC_PLACEONLY;
12067 +
12068 +               /* Must we save the block contents ? */
12069 +               if (td->options & NAND_BBT_SAVECONTENT) {
12070 +                       /* Make it block aligned */
12071 +                       to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
12072 +                       len = 1 << this->bbt_erase_shift;
12073 +                       res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
12074 +                       if (res < 0) {
12075 +                               if (retlen != len) {
12076 +                                       puts ("nand_bbt: Error reading block for writing the bad block table\r\n");
12077 +                                       return res;
12078 +                               }
12079 +                               puts ("nand_bbt: ECC error while reading block for writing bad block table\r\n");
12080 +                       }
12081 +                       /* Calc the byte offset in the buffer */
12082 +                       pageoffs = page - (int)(to >> this->page_shift);
12083 +                       offs = pageoffs << this->page_shift;
12084 +                       /* Preset the bbt area with 0xff */
12085 +                       memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
12086 +                       /* Preset the bbt's oob area with 0xff */
12087 +                       memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
12088 +                               ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
12089 +                       if (td->options & NAND_BBT_VERSION) {
12090 +                               buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
12091 +                       }
12092 +               } else {
12093 +                       /* Calc length */
12094 +                       len = (size_t) (numblocks >> sft);
12095 +                       /* Make it page aligned ! */
12096 +                       len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
12097 +                       /* Preset the buffer with 0xff */
12098 +                       memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
12099 +                       offs = 0;
12100 +                       /* Pattern is located in oob area of first page */
12101 +                       memcpy (&buf[len + td->offs], td->pattern, td->len);
12102 +                       if (td->options & NAND_BBT_VERSION) {
12103 +                               buf[len + td->veroffs] = td->version[chip];
12104 +                       }
12105 +               }
12106 +
12107 +               /* walk through the memory table */
12108 +               for (i = 0; i < numblocks; ) {
12109 +                       uint8_t dat;
12110 +                       dat = this->bbt[bbtoffs + (i >> 2)];
12111 +                       for (j = 0; j < 4; j++ , i++) {
12112 +                               int sftcnt = (i << (3 - sft)) & sftmsk;
12113 +                               /* Do not store the reserved bbt blocks ! */
12114 +                               buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt);
12115 +                               dat >>= 2;
12116 +                       }
12117 +               }
12118 +
12119 +               memset (&einfo, 0, sizeof (einfo));
12120 +               einfo.mtd = mtd;
12121 +               einfo.addr = (unsigned long) to;
12122 +               einfo.len = 1 << this->bbt_erase_shift;
12123 +               res = nand_erase_nand (mtd, &einfo, 1);
12124 +               if (res < 0) {
12125 +                       puts ("nand_bbt: Error during block erase: ");
12126 +                       putx (res);
12127 +                       putnl();
12128 +                       return res;
12129 +               }
12130 +
12131 +               res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
12132 +               if (res < 0) {
12133 +                       puts ("nand_bbt: Error while writing bad block table ");
12134 +                       putx (res);
12135 +                       putnl ();
12136 +                       return res;
12137 +               }
12138 +               puts ("Bad block table written to ");
12139 +               putx ((unsigned int) to);
12140 +               puts (", version ");
12141 +               putx (td->version[chip]);
12142 +               putnl ();
12143 +
12144 +               /* Mark it as used */
12145 +               td->pages[chip] = page;
12146 +       }
12147 +       return 0;
12148 +}
12149 +
12150 +/**
12151 + * nand_memory_bbt - [GENERIC] create a memory based bad block table
12152 + * @mtd:       MTD device structure
12153 + * @bd:                descriptor for the good/bad block search pattern
12154 + *
12155 + * The function creates a memory based bbt by scanning the device
12156 + * for manufacturer / software marked good / bad blocks
12157 +*/
12158 +static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12159 +{
12160 +       struct nand_chip *this = mtd->priv;
12161 +
12162 +       bd->options &= ~NAND_BBT_SCANEMPTY;
12163 +       return create_bbt (mtd, this->data_buf, bd, -1);
12164 +}
12165 +
12166 +/**
12167 + * check_create - [GENERIC] create and write bbt(s) if neccecary
12168 + * @mtd:       MTD device structure
12169 + * @buf:       temporary buffer
12170 + * @bd:                descriptor for the good/bad block search pattern
12171 + *
12172 + * The function checks the results of the previous call to read_bbt
12173 + * and creates / updates the bbt(s) if neccecary
12174 + * Creation is neccecary if no bbt was found for the chip/device
12175 + * Update is neccecary if one of the tables is missing or the
12176 + * version nr. of one table is less than the other
12177 +*/
12178 +static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
12179 +{
12180 +       int i, chips, writeops, chipsel, res;
12181 +       struct nand_chip *this = mtd->priv;
12182 +       struct nand_bbt_descr *td = this->bbt_td;
12183 +       struct nand_bbt_descr *md = this->bbt_md;
12184 +       struct nand_bbt_descr *rd, *rd2;
12185 +
12186 +       /* Do we have a bbt per chip ? */
12187 +       if (td->options & NAND_BBT_PERCHIP)
12188 +               chips = this->numchips;
12189 +       else
12190 +               chips = 1;
12191 +
12192 +       for (i = 0; i < chips; i++) {
12193 +               writeops = 0;
12194 +               rd = NULL;
12195 +               rd2 = NULL;
12196 +               /* Per chip or per device ? */
12197 +               chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
12198 +               /* Mirrored table avilable ? */
12199 +               if (md) {
12200 +                       if (td->pages[i] == -1 && md->pages[i] == -1) {
12201 +                               writeops = 0x03;
12202 +                               goto create;
12203 +                       }
12204 +
12205 +                       if (td->pages[i] == -1) {
12206 +                               rd = md;
12207 +                               td->version[i] = md->version[i];
12208 +                               writeops = 1;
12209 +                               goto writecheck;
12210 +                       }
12211 +
12212 +                       if (md->pages[i] == -1) {
12213 +                               rd = td;
12214 +                               md->version[i] = td->version[i];
12215 +                               writeops = 2;
12216 +                               goto writecheck;
12217 +                       }
12218 +
12219 +                       if (td->version[i] == md->version[i]) {
12220 +                               rd = td;
12221 +                               if (!(td->options & NAND_BBT_VERSION))
12222 +                                       rd2 = md;
12223 +                               goto writecheck;
12224 +                       }
12225 +
12226 +                       if (((int8_t) (td->version[i] - md->version[i])) > 0) {
12227 +                               rd = td;
12228 +                               md->version[i] = td->version[i];
12229 +                               writeops = 2;
12230 +                       } else {
12231 +                               rd = md;
12232 +                               td->version[i] = md->version[i];
12233 +                               writeops = 1;
12234 +                       }
12235 +
12236 +                       goto writecheck;
12237 +
12238 +               } else {
12239 +                       if (td->pages[i] == -1) {
12240 +                               writeops = 0x01;
12241 +                               goto create;
12242 +                       }
12243 +                       rd = td;
12244 +                       goto writecheck;
12245 +               }
12246 +create:
12247 +               /* Create the bad block table by scanning the device ? */
12248 +               if (!(td->options & NAND_BBT_CREATE))
12249 +                       continue;
12250 +
12251 +               /* Create the table in memory by scanning the chip(s) */
12252 +               create_bbt (mtd, buf, bd, chipsel);
12253 +
12254 +               td->version[i] = 1;
12255 +               if (md)
12256 +                       md->version[i] = 1;
12257 +writecheck:
12258 +               /* read back first ? */
12259 +               if (rd)
12260 +                       read_abs_bbt (mtd, buf, rd, chipsel);
12261 +               /* If they weren't versioned, read both. */
12262 +               if (rd2)
12263 +                       read_abs_bbt (mtd, buf, rd2, chipsel);
12264 +
12265 +               /* Write the bad block table to the device ? */
12266 +               if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
12267 +                       res = write_bbt (mtd, buf, td, md, chipsel);
12268 +                       if (res < 0)
12269 +                               return res;
12270 +               }
12271 +
12272 +               /* Write the mirror bad block table to the device ? */
12273 +               if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
12274 +                       res = write_bbt (mtd, buf, md, td, chipsel);
12275 +                       if (res < 0)
12276 +                               return res;
12277 +               }
12278 +       }
12279 +       return 0;
12280 +}
12281 +
12282 +/**
12283 + * mark_bbt_regions - [GENERIC] mark the bad block table regions
12284 + * @mtd:       MTD device structure
12285 + * @td:                bad block table descriptor
12286 + *
12287 + * The bad block table regions are marked as "bad" to prevent
12288 + * accidental erasures / writes. The regions are identified by
12289 + * the mark 0x02.
12290 +*/
12291 +static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
12292 +{
12293 +       struct nand_chip *this = mtd->priv;
12294 +       int i, j, chips, block, nrblocks, update;
12295 +       uint8_t oldval, newval;
12296 +
12297 +       /* Do we have a bbt per chip ? */
12298 +       if (td->options & NAND_BBT_PERCHIP) {
12299 +               chips = this->numchips;
12300 +               nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
12301 +       } else {
12302 +               chips = 1;
12303 +               nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
12304 +       }
12305 +
12306 +       for (i = 0; i < chips; i++) {
12307 +               if ((td->options & NAND_BBT_ABSPAGE) ||
12308 +                   !(td->options & NAND_BBT_WRITE)) {
12309 +                       if (td->pages[i] == -1) continue;
12310 +                       block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
12311 +                       block <<= 1;
12312 +                       oldval = this->bbt[(block >> 3)];
12313 +                       newval = oldval | (0x2 << (block & 0x06));
12314 +                       this->bbt[(block >> 3)] = newval;
12315 +                       if ((oldval != newval) && td->reserved_block_code)
12316 +                               nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
12317 +                       continue;
12318 +               }
12319 +               update = 0;
12320 +               if (td->options & NAND_BBT_LASTBLOCK)
12321 +                       block = ((i + 1) * nrblocks) - td->maxblocks;
12322 +               else
12323 +                       block = i * nrblocks;
12324 +               block <<= 1;
12325 +               for (j = 0; j < td->maxblocks; j++) {
12326 +                       oldval = this->bbt[(block >> 3)];
12327 +                       newval = oldval | (0x2 << (block & 0x06));
12328 +                       this->bbt[(block >> 3)] = newval;
12329 +                       if (oldval != newval) update = 1;
12330 +                       block += 2;
12331 +               }
12332 +               /* If we want reserved blocks to be recorded to flash, and some
12333 +                  new ones have been marked, then we need to update the stored
12334 +                  bbts.  This should only happen once. */
12335 +               if (update && td->reserved_block_code)
12336 +                       nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
12337 +       }
12338 +}
12339 +
12340 +/**
12341 + * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
12342 + * @mtd:       MTD device structure
12343 + * @bd:                descriptor for the good/bad block search pattern
12344 + *
12345 + * The function checks, if a bad block table(s) is/are already
12346 + * available. If not it scans the device for manufacturer
12347 + * marked good / bad blocks and writes the bad block table(s) to
12348 + * the selected place.
12349 + *
12350 + * The bad block table memory is allocated here. It must be freed
12351 + * by calling the nand_free_bbt function.
12352 + *
12353 +*/
12354 +int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12355 +{
12356 +       struct nand_chip *this = mtd->priv;
12357 +       int len, res = 0;
12358 +       uint8_t *buf;
12359 +       struct nand_bbt_descr *td = this->bbt_td;
12360 +       struct nand_bbt_descr *md = this->bbt_md;
12361 +
12362 +       len = mtd->size >> (this->bbt_erase_shift + 2);
12363 +       /* Allocate memory (2bit per block) */
12364 +       this->bbt = malloc (len);
12365 +       if (!this->bbt) {
12366 +               puts ("nand_scan_bbt: Out of memory\r\n");
12367 +               return -ENOMEM;
12368 +       }
12369 +       /* Clear the memory bad block table */
12370 +       memset (this->bbt, 0x00, len);
12371 +
12372 +       /* If no primary table decriptor is given, scan the device
12373 +        * to build a memory based bad block table
12374 +        */
12375 +       if (!td) {
12376 +               if ((res = nand_memory_bbt(mtd, bd))) {
12377 +                       puts ("nand_bbt: Can't scan flash and build the RAM-based BBT\r\n");
12378 +                       free (this->bbt);
12379 +                       this->bbt = NULL;
12380 +               }
12381 +               return res;
12382 +       }
12383 +
12384 +       /* Allocate a temporary buffer for one eraseblock incl. oob */
12385 +       len = (1 << this->bbt_erase_shift);
12386 +       len += (len >> this->page_shift) * mtd->oobsize;
12387 +       buf = malloc (len);
12388 +       if (!buf) {
12389 +               puts ("nand_bbt: Out of memory\r\n");
12390 +               free (this->bbt);
12391 +               this->bbt = NULL;
12392 +               return -ENOMEM;
12393 +       }
12394 +
12395 +       /* Is the bbt at a given page ? */
12396 +       if (td->options & NAND_BBT_ABSPAGE) {
12397 +               res = read_abs_bbts (mtd, buf, td, md);
12398 +       } else {
12399 +               /* Search the bad block table using a pattern in oob */
12400 +               res = search_read_bbts (mtd, buf, td, md);
12401 +       }
12402 +
12403 +       if (res)
12404 +               res = check_create (mtd, buf, bd);
12405 +
12406 +       /* Prevent the bbt regions from erasing / writing */
12407 +       mark_bbt_region (mtd, td);
12408 +       if (md)
12409 +               mark_bbt_region (mtd, md);
12410 +
12411 +       free (buf);
12412 +       return res;
12413 +}
12414 +
12415 +
12416 +/**
12417 + * nand_update_bbt - [NAND Interface] update bad block table(s)
12418 + * @mtd:       MTD device structure
12419 + * @offs:      the offset of the newly marked block
12420 + *
12421 + * The function updates the bad block table(s)
12422 +*/
12423 +int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
12424 +{
12425 +       struct nand_chip *this = mtd->priv;
12426 +       int len, res = 0, writeops = 0;
12427 +       int chip, chipsel;
12428 +       uint8_t *buf;
12429 +       struct nand_bbt_descr *td = this->bbt_td;
12430 +       struct nand_bbt_descr *md = this->bbt_md;
12431 +
12432 +       if (!this->bbt || !td)
12433 +               return -EINVAL;
12434 +
12435 +       len = mtd->size >> (this->bbt_erase_shift + 2);
12436 +       /* Allocate a temporary buffer for one eraseblock incl. oob */
12437 +       len = (1 << this->bbt_erase_shift);
12438 +       len += (len >> this->page_shift) * mtd->oobsize;
12439 +       buf = malloc (len);
12440 +       if (!buf) {
12441 +               puts ("nand_update_bbt: Out of memory\r\n");
12442 +               return -ENOMEM;
12443 +       }
12444 +
12445 +       writeops = md != NULL ? 0x03 : 0x01;
12446 +
12447 +       /* Do we have a bbt per chip ? */
12448 +       if (td->options & NAND_BBT_PERCHIP) {
12449 +               chip = (int) (offs >> this->chip_shift);
12450 +               chipsel = chip;
12451 +       } else {
12452 +               chip = 0;
12453 +               chipsel = -1;
12454 +       }
12455 +
12456 +       td->version[chip]++;
12457 +       if (md)
12458 +               md->version[chip]++;
12459 +
12460 +       /* Write the bad block table to the device ? */
12461 +       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
12462 +               res = write_bbt (mtd, buf, td, md, chipsel);
12463 +               if (res < 0)
12464 +                       goto out;
12465 +       }
12466 +       /* Write the mirror bad block table to the device ? */
12467 +       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
12468 +               res = write_bbt (mtd, buf, md, td, chipsel);
12469 +       }
12470 +
12471 +out:
12472 +       free (buf);
12473 +       return res;
12474 +}
12475 +
12476 +/* Define some generic bad / good block scan pattern which are used
12477 + * while scanning a device for factory marked good / bad blocks. */
12478 +static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
12479 +
12480 +static struct nand_bbt_descr smallpage_memorybased = {
12481 +       .options = NAND_BBT_SCAN2NDPAGE,
12482 +       .offs = 5,
12483 +       .len = 1,
12484 +       .pattern = scan_ff_pattern
12485 +};
12486 +
12487 +static struct nand_bbt_descr largepage_memorybased = {
12488 +       .options = 0,
12489 +       .offs = 0,
12490 +       .len = 2,
12491 +       .pattern = scan_ff_pattern
12492 +};
12493 +
12494 +static struct nand_bbt_descr smallpage_flashbased = {
12495 +       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12496 +       .offs = 5,
12497 +       .len = 1,
12498 +       .pattern = scan_ff_pattern
12499 +};
12500 +
12501 +static struct nand_bbt_descr largepage_flashbased = {
12502 +       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12503 +       .offs = 0,
12504 +       .len = 2,
12505 +       .pattern = scan_ff_pattern
12506 +};
12507 +
12508 +static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
12509 +
12510 +static struct nand_bbt_descr agand_flashbased = {
12511 +       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12512 +       .offs = 0x20,
12513 +       .len = 6,
12514 +       .pattern = scan_agand_pattern
12515 +};
12516 +
12517 +/* Generic flash bbt decriptors
12518 +*/
12519 +static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
12520 +static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
12521 +
12522 +static struct nand_bbt_descr bbt_main_descr = {
12523 +       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
12524 +               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
12525 +       .offs = 8,
12526 +       .len = 4,
12527 +       .veroffs = 12,
12528 +       .maxblocks = 4,
12529 +       .pattern = bbt_pattern
12530 +};
12531 +
12532 +static struct nand_bbt_descr bbt_mirror_descr = {
12533 +       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
12534 +               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
12535 +       .offs = 8,
12536 +       .len = 4,
12537 +       .veroffs = 12,
12538 +       .maxblocks = 4,
12539 +       .pattern = mirror_pattern
12540 +};
12541 +
12542 +/**
12543 + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
12544 + * @mtd:       MTD device structure
12545 + *
12546 + * This function selects the default bad block table
12547 + * support for the device and calls the nand_scan_bbt function
12548 + *
12549 +*/
12550 +int nand_default_bbt (struct mtd_info *mtd)
12551 +{
12552 +       struct nand_chip *this = mtd->priv;
12553 +
12554 +       /* Default for AG-AND. We must use a flash based
12555 +        * bad block table as the devices have factory marked
12556 +        * _good_ blocks. Erasing those blocks leads to loss
12557 +        * of the good / bad information, so we _must_ store
12558 +        * this information in a good / bad table during
12559 +        * startup
12560 +       */
12561 +       if (this->options & NAND_IS_AND) {
12562 +               /* Use the default pattern descriptors */
12563 +               if (!this->bbt_td) {
12564 +                       this->bbt_td = &bbt_main_descr;
12565 +                       this->bbt_md = &bbt_mirror_descr;
12566 +               }
12567 +               this->options |= NAND_USE_FLASH_BBT;
12568 +               return nand_scan_bbt (mtd, &agand_flashbased);
12569 +       }
12570 +
12571 +
12572 +       /* Is a flash based bad block table requested ? */
12573 +       if (this->options & NAND_USE_FLASH_BBT) {
12574 +               /* Use the default pattern descriptors */
12575 +               if (!this->bbt_td) {
12576 +                       this->bbt_td = &bbt_main_descr;
12577 +                       this->bbt_md = &bbt_mirror_descr;
12578 +               }
12579 +               if (!this->badblock_pattern) {
12580 +                       this->badblock_pattern = (mtd->oobblock > 512) ?
12581 +                               &largepage_flashbased : &smallpage_flashbased;
12582 +               }
12583 +       } else {
12584 +               this->bbt_td = NULL;
12585 +               this->bbt_md = NULL;
12586 +               if (!this->badblock_pattern) {
12587 +                       this->badblock_pattern = (mtd->oobblock > 512) ?
12588 +                               &largepage_memorybased : &smallpage_memorybased;
12589 +               }
12590 +       }
12591 +       return nand_scan_bbt (mtd, this->badblock_pattern);
12592 +}
12593 +
12594 +/**
12595 + * nand_isbad_bbt - [NAND Interface] Check if a block is bad
12596 + * @mtd:       MTD device structure
12597 + * @offs:      offset in the device
12598 + * @allowbbt:  allow access to bad block table region
12599 + *
12600 +*/
12601 +int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
12602 +{
12603 +       struct nand_chip *this = mtd->priv;
12604 +       int block;
12605 +       uint8_t res;
12606 +
12607 +       /* Get block number * 2 */
12608 +       block = (int) (offs >> (this->bbt_erase_shift - 1));
12609 +       res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
12610 +
12611 +       DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
12612 +               (unsigned int)offs, block >> 1, res);
12613 +
12614 +       switch ((int)res) {
12615 +       case 0x00:      return 0;
12616 +       case 0x01:      return 1;
12617 +       case 0x02:      return allowbbt ? 0 : 1;
12618 +       }
12619 +       return 1;
12620 +}
12621 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.c
12622 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.c        1970-01-01 01:00:00.000000000 +0100
12623 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.c        2006-08-04 16:38:14.000000000 +0200
12624 @@ -0,0 +1,246 @@
12625 +/*
12626 + * This file contains an ECC algorithm from Toshiba that detects and
12627 + * corrects 1 bit errors in a 256 byte block of data.
12628 + * 
12629 + * Taken from drivers/mtd/nand/nand_ecc.c, modified for
12630 + * NAND flash boot on Etrax FS.
12631 + *
12632 + * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
12633 + *                         Toshiba America Electronics Components, Inc.
12634 + *
12635 + * $Id: nand_ecc.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12636 + *
12637 + * This file is free software; you can redistribute it and/or modify it
12638 + * under the terms of the GNU General Public License as published by the
12639 + * Free Software Foundation; either version 2 or (at your option) any
12640 + * later version.
12641 + *
12642 + * This file is distributed in the hope that it will be useful, but WITHOUT
12643 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12644 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12645 + * for more details.
12646 + *
12647 + * You should have received a copy of the GNU General Public License along
12648 + * with this file; if not, write to the Free Software Foundation, Inc.,
12649 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
12650 + *
12651 + * As a special exception, if other files instantiate templates or use
12652 + * macros or inline functions from these files, or you compile these
12653 + * files and link them with other works to produce a work based on these
12654 + * files, these files do not by themselves cause the resulting work to be
12655 + * covered by the GNU General Public License. However the source code for
12656 + * these files must still be made available in accordance with section (3)
12657 + * of the GNU General Public License.
12658 + *
12659 + * This exception does not invalidate any other reasons why a work based on
12660 + * this file might be covered by the GNU General Public License.
12661 + */
12662 +
12663 +#include <linux/types.h>
12664 +#if 0
12665 +#include <linux/kernel.h>
12666 +#include <linux/module.h>
12667 +#endif
12668 +#include "nand_ecc.h"
12669 +
12670 +/*
12671 + * Pre-calculated 256-way 1 byte column parity
12672 + */
12673 +static const u_char nand_ecc_precalc_table[] = {
12674 +       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
12675 +       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
12676 +       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
12677 +       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
12678 +       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
12679 +       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
12680 +       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
12681 +       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
12682 +       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
12683 +       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
12684 +       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
12685 +       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
12686 +       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
12687 +       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
12688 +       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
12689 +       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
12690 +};
12691 +
12692 +
12693 +/**
12694 + * nand_trans_result - [GENERIC] create non-inverted ECC
12695 + * @reg2:      line parity reg 2
12696 + * @reg3:      line parity reg 3
12697 + * @ecc_code:  ecc
12698 + *
12699 + * Creates non-inverted ECC code from line parity
12700 + */
12701 +static void nand_trans_result(u_char reg2, u_char reg3,
12702 +       u_char *ecc_code)
12703 +{
12704 +       u_char a, b, i, tmp1, tmp2;
12705 +
12706 +       /* Initialize variables */
12707 +       a = b = 0x80;
12708 +       tmp1 = tmp2 = 0;
12709 +
12710 +       /* Calculate first ECC byte */
12711 +       for (i = 0; i < 4; i++) {
12712 +               if (reg3 & a)           /* LP15,13,11,9 --> ecc_code[0] */
12713 +                       tmp1 |= b;
12714 +               b >>= 1;
12715 +               if (reg2 & a)           /* LP14,12,10,8 --> ecc_code[0] */
12716 +                       tmp1 |= b;
12717 +               b >>= 1;
12718 +               a >>= 1;
12719 +       }
12720 +
12721 +       /* Calculate second ECC byte */
12722 +       b = 0x80;
12723 +       for (i = 0; i < 4; i++) {
12724 +               if (reg3 & a)           /* LP7,5,3,1 --> ecc_code[1] */
12725 +                       tmp2 |= b;
12726 +               b >>= 1;
12727 +               if (reg2 & a)           /* LP6,4,2,0 --> ecc_code[1] */
12728 +                       tmp2 |= b;
12729 +               b >>= 1;
12730 +               a >>= 1;
12731 +       }
12732 +
12733 +       /* Store two of the ECC bytes */
12734 +       ecc_code[0] = tmp1;
12735 +       ecc_code[1] = tmp2;
12736 +}
12737 +
12738 +/**
12739 + * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block
12740 + * @mtd:       MTD block structure
12741 + * @dat:       raw data
12742 + * @ecc_code:  buffer for ECC
12743 + */
12744 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
12745 +{
12746 +       u_char idx, reg1, reg2, reg3;
12747 +       int j;
12748 +
12749 +       /* Initialize variables */
12750 +       reg1 = reg2 = reg3 = 0;
12751 +       ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
12752 +
12753 +       /* Build up column parity */
12754 +       for(j = 0; j < 256; j++) {
12755 +
12756 +               /* Get CP0 - CP5 from table */
12757 +               idx = nand_ecc_precalc_table[dat[j]];
12758 +               reg1 ^= (idx & 0x3f);
12759 +
12760 +               /* All bit XOR = 1 ? */
12761 +               if (idx & 0x40) {
12762 +                       reg3 ^= (u_char) j;
12763 +                       reg2 ^= ~((u_char) j);
12764 +               }
12765 +       }
12766 +
12767 +       /* Create non-inverted ECC code from line parity */
12768 +       nand_trans_result(reg2, reg3, ecc_code);
12769 +
12770 +       /* Calculate final ECC code */
12771 +       ecc_code[0] = ~ecc_code[0];
12772 +       ecc_code[1] = ~ecc_code[1];
12773 +       ecc_code[2] = ((~reg1) << 2) | 0x03;
12774 +       return 0;
12775 +}
12776 +
12777 +/**
12778 + * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
12779 + * @mtd:       MTD block structure
12780 + * @dat:       raw data read from the chip
12781 + * @read_ecc:  ECC from the chip
12782 + * @calc_ecc:  the ECC calculated from raw data
12783 + *
12784 + * Detect and correct a 1 bit error for 256 byte block
12785 + */
12786 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
12787 +{
12788 +       u_char a, b, c, d1, d2, d3, add, bit, i;
12789 +
12790 +       /* Do error detection */
12791 +       d1 = calc_ecc[0] ^ read_ecc[0];
12792 +       d2 = calc_ecc[1] ^ read_ecc[1];
12793 +       d3 = calc_ecc[2] ^ read_ecc[2];
12794 +
12795 +       if ((d1 | d2 | d3) == 0) {
12796 +               /* No errors */
12797 +               return 0;
12798 +       }
12799 +       else {
12800 +               a = (d1 ^ (d1 >> 1)) & 0x55;
12801 +               b = (d2 ^ (d2 >> 1)) & 0x55;
12802 +               c = (d3 ^ (d3 >> 1)) & 0x54;
12803 +
12804 +               /* Found and will correct single bit error in the data */
12805 +               if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
12806 +                       c = 0x80;
12807 +                       add = 0;
12808 +                       a = 0x80;
12809 +                       for (i=0; i<4; i++) {
12810 +                               if (d1 & c)
12811 +                                       add |= a;
12812 +                               c >>= 2;
12813 +                               a >>= 1;
12814 +                       }
12815 +                       c = 0x80;
12816 +                       for (i=0; i<4; i++) {
12817 +                               if (d2 & c)
12818 +                                       add |= a;
12819 +                               c >>= 2;
12820 +                               a >>= 1;
12821 +                       }
12822 +                       bit = 0;
12823 +                       b = 0x04;
12824 +                       c = 0x80;
12825 +                       for (i=0; i<3; i++) {
12826 +                               if (d3 & c)
12827 +                                       bit |= b;
12828 +                               c >>= 2;
12829 +                               b >>= 1;
12830 +                       }
12831 +                       b = 0x01;
12832 +                       a = dat[add];
12833 +                       a ^= (b << bit);
12834 +                       dat[add] = a;
12835 +                       return 1;
12836 +               }
12837 +               else {
12838 +                       i = 0;
12839 +                       while (d1) {
12840 +                               if (d1 & 0x01)
12841 +                                       ++i;
12842 +                               d1 >>= 1;
12843 +                       }
12844 +                       while (d2) {
12845 +                               if (d2 & 0x01)
12846 +                                       ++i;
12847 +                               d2 >>= 1;
12848 +                       }
12849 +                       while (d3) {
12850 +                               if (d3 & 0x01)
12851 +                                       ++i;
12852 +                               d3 >>= 1;
12853 +                       }
12854 +                       if (i == 1) {
12855 +                               /* ECC Code Error Correction */
12856 +                               read_ecc[0] = calc_ecc[0];
12857 +                               read_ecc[1] = calc_ecc[1];
12858 +                               read_ecc[2] = calc_ecc[2];
12859 +                               return 2;
12860 +                       }
12861 +                       else {
12862 +                               /* Uncorrectable Error */
12863 +                               return -1;
12864 +                       }
12865 +               }
12866 +       }
12867 +
12868 +       /* Should never happen */
12869 +       return -1;
12870 +}
12871 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.h
12872 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.h        1970-01-01 01:00:00.000000000 +0100
12873 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.h        2006-08-04 16:38:14.000000000 +0200
12874 @@ -0,0 +1,30 @@
12875 +/*
12876 + *  drivers/mtd/nand_ecc.h
12877 + *
12878 + *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
12879 + *
12880 + * $Id: nand_ecc.h,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12881 + *
12882 + * This program is free software; you can redistribute it and/or modify
12883 + * it under the terms of the GNU General Public License version 2 as
12884 + * published by the Free Software Foundation.
12885 + *
12886 + * This file is the header for the ECC algorithm.
12887 + */
12888 +
12889 +#ifndef __MTD_NAND_ECC_H__
12890 +#define __MTD_NAND_ECC_H__
12891 +
12892 +struct mtd_info;
12893 +
12894 +/*
12895 + * Calculate 3 byte ECC code for 256 byte block
12896 + */
12897 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
12898 +
12899 +/*
12900 + * Detect and correct a 1 bit error for 256 byte block
12901 + */
12902 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
12903 +
12904 +#endif /* __MTD_NAND_ECC_H__ */
12905 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ids.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ids.c
12906 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ids.c        1970-01-01 01:00:00.000000000 +0100
12907 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ids.c        2006-08-04 16:38:14.000000000 +0200
12908 @@ -0,0 +1,133 @@
12909 +/*
12910 + *  drivers/mtd/nandids.c
12911 + *
12912 + *  Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
12913 + *
12914 + * $Id: nand_ids.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12915 + *
12916 + * This program is free software; you can redistribute it and/or modify
12917 + * it under the terms of the GNU General Public License version 2 as
12918 + * published by the Free Software Foundation.
12919 + *
12920 + */
12921 +#if 0
12922 +#include <linux/module.h>
12923 +#endif
12924 +
12925 +#include "nand.h"
12926 +/*
12927 +*      Chip ID list
12928 +*
12929 +*      Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
12930 +*      options
12931 +*
12932 +*      Pagesize; 0, 256, 512
12933 +*      0       get this information from the extended chip ID
12934 ++      256     256 Byte page size
12935 +*      512     512 Byte page size
12936 +*/
12937 +struct nand_flash_dev nand_flash_ids[] = {
12938 +       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},
12939 +       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},
12940 +       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},
12941 +       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, 0},
12942 +       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, 0},
12943 +       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, 0},
12944 +       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, 0},
12945 +       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, 0},
12946 +       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, 0},
12947 +       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, 0},
12948 +
12949 +       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, 0},
12950 +       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},
12951 +       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
12952 +       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
12953 +
12954 +       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},
12955 +       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},
12956 +       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
12957 +       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
12958 +
12959 +       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, 0},
12960 +       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, 0},
12961 +       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
12962 +       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
12963 +
12964 +       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, 0},
12965 +       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, 0},
12966 +       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
12967 +       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
12968 +
12969 +       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, 0},
12970 +       {"NAND 128MiB 1,8V 8-bit",      0x39, 512, 128, 0x4000, 0},
12971 +       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, 0},
12972 +       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12973 +       {"NAND 128MiB 1,8V 16-bit",     0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12974 +       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12975 +       {"NAND 128MiB 3,3V 16-bit",     0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12976 +
12977 +       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},
12978 +
12979 +       /* These are the new chips with large page size. The pagesize
12980 +       * and the erasesize is determined from the extended id bytes
12981 +       */
12982 +       /*512 Megabit */
12983 +       {"NAND 64MiB 1,8V 8-bit",       0xA2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12984 +       {"NAND 64MiB 3,3V 8-bit",       0xF2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12985 +       {"NAND 64MiB 1,8V 16-bit",      0xB2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12986 +       {"NAND 64MiB 3,3V 16-bit",      0xC2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12987 +
12988 +       /* 1 Gigabit */
12989 +       {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12990 +       {"NAND 128MiB 3,3V 8-bit",      0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12991 +       {"NAND 128MiB 1,8V 16-bit",     0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12992 +       {"NAND 128MiB 3,3V 16-bit",     0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12993 +
12994 +       /* 2 Gigabit */
12995 +       {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12996 +       {"NAND 256MiB 3,3V 8-bit",      0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12997 +       {"NAND 256MiB 1,8V 16-bit",     0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12998 +       {"NAND 256MiB 3,3V 16-bit",     0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12999 +
13000 +       /* 4 Gigabit */
13001 +       {"NAND 512MiB 1,8V 8-bit",      0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13002 +       {"NAND 512MiB 3,3V 8-bit",      0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13003 +       {"NAND 512MiB 1,8V 16-bit",     0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13004 +       {"NAND 512MiB 3,3V 16-bit",     0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13005 +
13006 +       /* 8 Gigabit */
13007 +       {"NAND 1GiB 1,8V 8-bit",        0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13008 +       {"NAND 1GiB 3,3V 8-bit",        0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13009 +       {"NAND 1GiB 1,8V 16-bit",       0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13010 +       {"NAND 1GiB 3,3V 16-bit",       0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13011 +
13012 +       /* 16 Gigabit */
13013 +       {"NAND 2GiB 1,8V 8-bit",        0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13014 +       {"NAND 2GiB 3,3V 8-bit",        0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13015 +       {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13016 +       {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13017 +
13018 +       /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
13019 +        * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
13020 +        * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
13021 +        * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
13022 +        * There are more speed improvements for reads and writes possible, but not implemented now
13023 +        */
13024 +       {"AND 128MiB 3,3V 8-bit",       0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
13025 +
13026 +       {NULL,}
13027 +};
13028 +
13029 +/*
13030 +*      Manufacturer ID list
13031 +*/
13032 +struct nand_manufacturers nand_manuf_ids[] = {
13033 +       {NAND_MFR_TOSHIBA, "Toshiba"},
13034 +       {NAND_MFR_SAMSUNG, "Samsung"},
13035 +       {NAND_MFR_FUJITSU, "Fujitsu"},
13036 +       {NAND_MFR_NATIONAL, "National"},
13037 +       {NAND_MFR_RENESAS, "Renesas"},
13038 +       {NAND_MFR_STMICRO, "ST Micro"},
13039 +        {NAND_MFR_HYNIX, "Hynix"},
13040 +       {0x0, "Unknown"}
13041 +};
13042 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/rescue.ld linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/rescue.ld
13043 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/rescue.ld 2007-01-10 20:10:37.000000000 +0100
13044 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/rescue.ld 2006-10-18 10:52:47.000000000 +0200
13045 @@ -1,20 +1,40 @@
13046 -MEMORY
13047 +/*#OUTPUT_FORMAT(elf32-us-cris) */
13048 +OUTPUT_ARCH (crisv32)
13049 +
13050 +MEMORY 
13051         {
13052 -       flash : ORIGIN = 0x00000000,
13053 -               LENGTH = 0x00100000
13054 +       bootblk : ORIGIN = 0x38000000,
13055 +                 LENGTH = 0x00004000
13056 +       intmem  : ORIGIN = 0x38004000,
13057 +                 LENGTH = 0x00005000
13058         }
13059  
13060  SECTIONS
13061  {
13062         .text :
13063         {
13064 -               stext = . ;
13065 +               _stext = . ;
13066                 *(.text)
13067 -               etext = . ;
13068 -       } > flash
13069 +               *(.rodata)
13070 +               *(.rodata.*)
13071 +               _etext = . ;
13072 +       } > bootblk
13073         .data :
13074         {
13075                 *(.data)
13076 -               edata = . ;
13077 -       } > flash
13078 +               _edata = . ;
13079 +       } > bootblk
13080 +       .bss :
13081 +       {
13082 +               _bss = . ;
13083 +               *(.bss)
13084 +               _end = ALIGN( 0x10 ) ;
13085 +       } > intmem
13086 +
13087 +       /* Get rid of stuff from EXPORT_SYMBOL(foo). */
13088 +       /DISCARD/ :
13089 +       {
13090 +               *(__ksymtab_strings)
13091 +               *(__ksymtab)
13092 +       }
13093  }
13094 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Kconfig
13095 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Kconfig       2007-01-10 20:10:37.000000000 +0100
13096 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Kconfig       2007-01-29 16:14:16.000000000 +0100
13097 @@ -6,14 +6,6 @@
13098           This option enables the ETRAX FS built-in 10/100Mbit Ethernet
13099           controller.
13100  
13101 -config ETRAX_ETHERNET_HW_CSUM
13102 -       bool "Hardware accelerated ethernet checksum and scatter/gather"
13103 -       depends on ETRAX_ETHERNET
13104 -       depends on ETRAX_STREAMCOPROC
13105 -       default y
13106 -       help
13107 -         Hardware acceleration of checksumming and scatter/gather
13108 -
13109  config ETRAX_ETHERNET_IFACE0
13110         depends on ETRAX_ETHERNET
13111         bool "Enable network interface 0"
13112 @@ -23,6 +15,52 @@
13113         bool "Enable network interface 1 (uses DMA6 and DMA7)"
13114  
13115  choice
13116 +       prompt "Eth0 led group"
13117 +       depends on ETRAX_ETHERNET_IFACE0
13118 +       default ETRAX_ETH0_USE_LEDGRP0
13119 +
13120 +config ETRAX_ETH0_USE_LEDGRP0
13121 +       bool "Use LED grp 0"
13122 +       depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
13123 +       help
13124 +         Use LED grp 0 for eth0
13125 +
13126 +config ETRAX_ETH0_USE_LEDGRP1
13127 +       bool "Use LED grp 1"
13128 +       depends on ETRAX_NBR_LED_GRP_TWO
13129 +       help
13130 +         Use LED grp 1 for eth0
13131 +
13132 +config ETRAX_ETH0_USE_LEDGRPNULL
13133 +       bool "Use no LEDs for eth0"
13134 +       help
13135 +         Use no LEDs for eth0
13136 +endchoice
13137 +
13138 +choice
13139 +       prompt "Eth1 led group"
13140 +       depends on ETRAX_ETHERNET_IFACE1
13141 +       default ETRAX_ETH1_USE_LEDGRP1
13142 +
13143 +config ETRAX_ETH1_USE_LEDGRP0
13144 +       bool "Use LED grp 0"
13145 +       depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
13146 +       help
13147 +         Use LED grp 0 for eth1
13148 +
13149 +config ETRAX_ETH1_USE_LEDGRP1
13150 +       bool "Use LED grp 1"
13151 +       depends on ETRAX_NBR_LED_GRP_TWO
13152 +       help
13153 +         Use LED grp 1 for eth1
13154 +
13155 +config ETRAX_ETH1_USE_LEDGRPNULL
13156 +       bool "Use no LEDs for eth1"
13157 +       help
13158 +         Use no LEDs for eth1
13159 +endchoice
13160 +
13161 +choice
13162         prompt "Network LED behavior"
13163         depends on ETRAX_ETHERNET
13164         default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
13165 @@ -56,10 +94,25 @@
13166  config ETRAXFS_SERIAL
13167         bool "Serial-port support"
13168         depends on ETRAX_ARCH_V32
13169 +       select SERIAL_CORE
13170 +       select SERIAL_CORE_CONSOLE
13171         help
13172           Enables the ETRAX FS serial driver for ser0 (ttyS0)
13173           You probably want this enabled.
13174  
13175 +config ETRAX_RS485
13176 +       bool "RS-485 support"
13177 +       depends on ETRAXFS_SERIAL
13178 +       help
13179 +         Enables support for RS-485 serial communication.
13180 +
13181 +config ETRAX_RS485_DISABLE_RECEIVER
13182 +       bool "Disable serial receiver"
13183 +       depends on ETRAX_RS485
13184 +       help
13185 +         It is necessary to disable the serial receiver to avoid serial
13186 +         loopback.  Not all products are able to do this in software only.
13187 +
13188  config ETRAX_SERIAL_PORT0
13189         bool "Serial port 0 enabled"
13190         depends on ETRAXFS_SERIAL
13191 @@ -70,6 +123,31 @@
13192           ser0 can use dma4 or dma6 for output and dma5 or dma7 for input.
13193  
13194  choice
13195 +       prompt "Ser0 default port type "
13196 +       depends on ETRAX_SERIAL_PORT0
13197 +       default ETRAX_SERIAL_PORT0_TYPE_232
13198 +       help
13199 +         Type of serial port.
13200 +
13201 +config ETRAX_SERIAL_PORT0_TYPE_232
13202 +       bool "Ser0 is a RS-232 port"
13203 +       help
13204 +         Configure serial port 0 to be a RS-232 port.
13205 +
13206 +config ETRAX_SERIAL_PORT0_TYPE_485HD
13207 +       bool "Ser0 is a half duplex RS-485 port"
13208 +       depends on ETRAX_RS485
13209 +       help
13210 +         Configure serial port 0 to be a half duplex (two wires) RS-485 port.
13211 +
13212 +config ETRAX_SERIAL_PORT0_TYPE_485FD
13213 +       bool "Ser0 is a full duplex RS-485 port"
13214 +       depends on ETRAX_RS485
13215 +       help
13216 +         Configure serial port 0 to be a full duplex (four wires) RS-485 port.
13217 +endchoice
13218 +
13219 +choice
13220         prompt "Ser0 DMA in channel "
13221         depends on ETRAX_SERIAL_PORT0
13222         default ETRAX_SERIAL_PORT0_NO_DMA_IN
13223 @@ -139,6 +217,31 @@
13224           Enables the ETRAX FS serial driver for ser1 (ttyS1).
13225  
13226  choice
13227 +       prompt "Ser1 default port type"
13228 +       depends on ETRAX_SERIAL_PORT1
13229 +       default ETRAX_SERIAL_PORT1_TYPE_232
13230 +       help
13231 +         Type of serial port.
13232 +
13233 +config ETRAX_SERIAL_PORT1_TYPE_232
13234 +       bool "Ser1 is a RS-232 port"
13235 +       help
13236 +         Configure serial port 1 to be a RS-232 port.
13237 +
13238 +config ETRAX_SERIAL_PORT1_TYPE_485HD
13239 +       bool "Ser1 is a half duplex RS-485 port"
13240 +       depends on ETRAX_RS485
13241 +       help
13242 +         Configure serial port 1 to be a half duplex (two wires) RS-485 port.
13243 +
13244 +config ETRAX_SERIAL_PORT1_TYPE_485FD
13245 +       bool "Ser1 is a full duplex RS-485 port"
13246 +       depends on ETRAX_RS485
13247 +       help
13248 +         Configure serial port 1 to be a full duplex (four wires) RS-485 port.
13249 +endchoice
13250 +
13251 +choice
13252         prompt "Ser1 DMA in channel "
13253         depends on ETRAX_SERIAL_PORT1
13254         default ETRAX_SERIAL_PORT1_NO_DMA_IN
13255 @@ -210,6 +313,31 @@
13256           Enables the ETRAX FS serial driver for ser2 (ttyS2).
13257  
13258  choice
13259 +       prompt "Ser2 default port type"
13260 +       depends on ETRAX_SERIAL_PORT2
13261 +       default ETRAX_SERIAL_PORT2_TYPE_232
13262 +       help
13263 +         What DMA channel to use for ser2
13264 +
13265 +config ETRAX_SERIAL_PORT2_TYPE_232
13266 +       bool "Ser2 is a RS-232 port"
13267 +       help
13268 +         Configure serial port 2 to be a RS-232 port.
13269 +
13270 +config ETRAX_SERIAL_PORT2_TYPE_485HD
13271 +       bool "Ser2 is a half duplex RS-485 port"
13272 +       depends on ETRAX_RS485
13273 +       help
13274 +         Configure serial port 2 to be a half duplex (two wires) RS-485 port.
13275 +
13276 +config ETRAX_SERIAL_PORT2_TYPE_485FD
13277 +       bool "Ser2 is a full duplex RS-485 port"
13278 +       depends on ETRAX_RS485
13279 +       help
13280 +         Configure serial port 2 to be a full duplex (four wires) RS-485 port.
13281 +endchoice
13282 +
13283 +choice
13284         prompt "Ser2 DMA in channel "
13285         depends on ETRAX_SERIAL_PORT2
13286         default ETRAX_SERIAL_PORT2_NO_DMA_IN
13287 @@ -279,6 +407,31 @@
13288           Enables the ETRAX FS serial driver for ser3 (ttyS3).
13289  
13290  choice
13291 +       prompt "Ser3 default port type"
13292 +       depends on ETRAX_SERIAL_PORT3
13293 +       default ETRAX_SERIAL_PORT3_TYPE_232
13294 +       help
13295 +         What DMA channel to use for ser3.
13296 +
13297 +config ETRAX_SERIAL_PORT3_TYPE_232
13298 +       bool "Ser3 is a RS-232 port"
13299 +       help
13300 +         Configure serial port 3 to be a RS-232 port.
13301 +
13302 +config ETRAX_SERIAL_PORT3_TYPE_485HD
13303 +       bool "Ser3 is a half duplex RS-485 port"
13304 +       depends on ETRAX_RS485
13305 +       help
13306 +         Configure serial port 3 to be a half duplex (two wires) RS-485 port.
13307 +
13308 +config ETRAX_SERIAL_PORT3_TYPE_485FD
13309 +       bool "Ser3 is a full duplex RS-485 port"
13310 +       depends on ETRAX_RS485
13311 +       help
13312 +         Configure serial port 3 to be a full duplex (four wires) RS-485 port.
13313 +endchoice
13314 +
13315 +choice
13316         prompt "Ser3 DMA in channel "
13317         depends on ETRAX_SERIAL_PORT3
13318         default ETRAX_SERIAL_PORT3_NO_DMA_IN
13319 @@ -341,38 +494,6 @@
13320         string "Ser 3 CD bit (empty = not used)"
13321         depends on ETRAX_SERIAL_PORT3
13322  
13323 -config ETRAX_RS485
13324 -       bool "RS-485 support"
13325 -       depends on ETRAX_SERIAL
13326 -       help
13327 -         Enables support for RS-485 serial communication.  For a primer on
13328 -         RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
13329 -
13330 -config ETRAX_RS485_DISABLE_RECEIVER
13331 -       bool "Disable serial receiver"
13332 -       depends on ETRAX_RS485
13333 -       help
13334 -         It is necessary to disable the serial receiver to avoid serial
13335 -         loopback.  Not all products are able to do this in software only.
13336 -         Axis 2400/2401 must disable receiver.
13337 -
13338 -config ETRAX_AXISFLASHMAP
13339 -       bool "Axis flash-map support"
13340 -       depends on ETRAX_ARCH_V32
13341 -       select MTD
13342 -       select MTD_CFI
13343 -       select MTD_CFI_AMDSTD
13344 -       select MTD_OBSOLETE_CHIPS
13345 -       select MTD_AMDSTD
13346 -       select MTD_CHAR
13347 -       select MTD_BLOCK
13348 -       select MTD_PARTITIONS
13349 -       select MTD_CONCAT
13350 -       select MTD_COMPLEX_MAPPINGS
13351 -       help
13352 -         This option enables MTD mapping of flash devices.  Needed to use
13353 -         flash memories.  If unsure, say Y.
13354 -
13355  config ETRAX_SYNCHRONOUS_SERIAL
13356         bool "Synchronous serial-port support"
13357         depends on ETRAX_ARCH_V32
13358 @@ -405,6 +526,31 @@
13359             A synchronous serial port can run in manual or DMA mode.
13360             Selecting this option will make it run in DMA mode.
13361  
13362 +config ETRAX_AXISFLASHMAP
13363 +       bool "Axis flash-map support"
13364 +       depends on ETRAX_ARCH_V32
13365 +       select MTD
13366 +       select MTD_CFI
13367 +       select MTD_CFI_AMDSTD
13368 +       select MTD_JEDECPROBE
13369 +       select MTD_CHAR
13370 +       select MTD_BLOCK
13371 +       select MTD_PARTITIONS
13372 +       select MTD_CONCAT
13373 +       select MTD_COMPLEX_MAPPINGS
13374 +       help
13375 +         This option enables MTD mapping of flash devices.  Needed to use
13376 +         flash memories.  If unsure, say Y.
13377 +
13378 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
13379 +       bool "MTD0 is whole boot flash device"
13380 +       depends on ETRAX_AXISFLASHMAP
13381 +       default N
13382 +       help
13383 +         When this option is not set, mtd0 refers to the first partition
13384 +         on the boot flash device. When set, mtd0 refers to the whole
13385 +         device, with mtd1 referring to the first partition etc.
13386 +
13387  config ETRAX_PTABLE_SECTOR
13388         int "Byte-offset of partition table sector"
13389         depends on ETRAX_AXISFLASHMAP
13390 @@ -425,11 +571,19 @@
13391           This option enables MTD mapping of NAND flash devices.  Needed to use
13392           NAND flash memories.  If unsure, say Y.
13393  
13394 +config ETRAX_NANDBOOT
13395 +       bool "Boot from NAND flash"
13396 +       depends on ETRAX_NANDFLASH
13397 +       help
13398 +         This options enables booting from NAND flash devices. 
13399 +         Say Y if your boot code, kernel and root file system is in 
13400 +         NAND flash. Say N if they are in NOR flash.
13401 +
13402  config ETRAX_I2C
13403         bool "I2C driver"
13404         depends on ETRAX_ARCH_V32
13405         help
13406 -         This option enabled the I2C driver used by e.g. the RTC driver.
13407 +         This option enables the I2C driver used by e.g. the RTC driver.
13408  
13409  config ETRAX_I2C_DATA_PORT
13410         string "I2C data pin"
13411 @@ -476,18 +630,19 @@
13412           Remember that you need to setup the port directions appropriately in
13413           the General configuration.
13414  
13415 -config ETRAX_PA_BUTTON_BITMASK
13416 -       hex "PA-buttons bitmask"
13417 +config ETRAX_VIRTUAL_GPIO
13418 +       bool "Virtual GPIO support"
13419         depends on ETRAX_GPIO
13420 -       default "0x02"
13421         help
13422 -         This is a bitmask (8 bits) with information about what bits on PA
13423 -         that are used for buttons.
13424 -         Most products has a so called TEST button on PA1, if that is true
13425 -         use 0x02 here.
13426 -         Use 00 if there are no buttons on PA.
13427 -         If the bitmask is <> 00 a button driver will be included in the gpio
13428 -         driver. ETRAX general I/O support must be enabled.
13429 +         Enables the virtual Etrax general port device (major 120, minor 6).
13430 +         It uses an I/O expander for the I2C-bus.
13431 +
13432 +config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
13433 +       int "Virtual GPIO interrupt pin on PA pin"
13434 +       range 0 7
13435 +       depends on ETRAX_VIRTUAL_GPIO
13436 +       help
13437 +         The pin to use on PA for virtual gpio interrupt.
13438  
13439  config ETRAX_PA_CHANGEABLE_DIR
13440         hex "PA user changeable dir mask"
13441 @@ -584,6 +739,25 @@
13442           that a user can change the value on using ioctl's.
13443           Bit set = changeable.
13444  
13445 +config ETRAX_PV_CHANGEABLE_DIR
13446 +       hex "PV user changeable dir mask"
13447 +       depends on ETRAX_VIRTUAL_GPIO
13448 +       default "0x0000"
13449 +       help
13450 +         This is a bitmask (16 bits) with information of what bits in PV
13451 +         that a user can change direction on using ioctl's.
13452 +         Bit set = changeable.
13453 +         You probably want 0x0000 here, but it depends on your hardware.
13454 +
13455 +config ETRAX_PV_CHANGEABLE_BITS
13456 +       hex "PV user changeable bits mask"
13457 +       depends on ETRAX_VIRTUAL_GPIO
13458 +       default "0x0000"
13459 +       help
13460 +         This is a bitmask (16 bits) with information of what bits in PV
13461 +         that a user can change the value on using ioctl's.
13462 +         Bit set = changeable.
13463 +
13464  config ETRAX_IDE
13465         bool "ATA/IDE support"
13466         depends on ETRAX_ARCH_V32
13467 @@ -603,11 +777,11 @@
13468          select HOTPLUG
13469          select PCCARD_NONSTATIC
13470          help
13471 -        Enabled the ETRAX Carbus driver.
13472 +        Enabled the ETRAX Carbus driver. 
13473  
13474  config PCI
13475         bool
13476 -       depends on ETRAX_CARDBUS
13477 +       depends on ETRAX_CARDBUS     
13478         default y
13479  
13480  config ETRAX_IOP_FW_LOAD
13481 @@ -623,3 +797,175 @@
13482         help
13483           This option enables a driver for the stream co-processor
13484           for cryptographic operations.
13485 +
13486 +source drivers/mmc/Kconfig
13487 +
13488 +config ETRAX_SPI_MMC
13489 +# Make this one of several "choices" (possible simultaneously but
13490 +# suggested uniquely) when an IOP driver emerges for "real" MMC/SD
13491 +# protocol support.
13492 +       tristate
13493 +       depends on MMC
13494 +       default MMC
13495 +       select SPI
13496 +       select MMC_SPI
13497 +       select ETRAX_SPI_MMC_BOARD
13498 +
13499 +# For the parts that can't be a module (due to restrictions in
13500 +# framework elsewhere).
13501 +config ETRAX_SPI_MMC_BOARD
13502 +       boolean
13503 +       default n
13504 +
13505 +# While the board info is MMC_SPI only, the drivers are written to be
13506 +# independent of MMC_SPI, so we'll keep SPI non-dependent on the
13507 +# MMC_SPI config choices (well, except for a single depends-on-line
13508 +# for the board-info file until a separate non-MMC SPI board file
13509 +# emerges).
13510 +# FIXME: When that happens, we'll need to be able to ask for and
13511 +# configure non-MMC SPI ports together with MMC_SPI ports (if multiple
13512 +# SPI ports are enabled).
13513 +
13514 +config ETRAX_SPI_SSER0
13515 +       tristate "SPI using synchronous serial port 0 (sser0)"
13516 +       depends on ETRAX_SPI_MMC
13517 +       default m if MMC_SPI=m
13518 +       default y if MMC_SPI=y
13519 +       default y if MMC_SPI=n
13520 +       select SPI_ETRAX_SSER
13521 +       help
13522 +         Say Y for an MMC/SD socket connected to synchronous serial port 0,
13523 +         or for devices using the SPI protocol on that port.  Say m if you
13524 +         want to build it as a module, which will be named spi_crisv32_sser.
13525 +         (You need to select MMC separately.)
13526 +
13527 +config ETRAX_SPI_SSER0_DMA
13528 +       bool "DMA for SPI on sser0 enabled"
13529 +       depends on ETRAX_SPI_SSER0
13530 +       depends on !ETRAX_SERIAL_PORT1_DMA4_OUT && !ETRAX_SERIAL_PORT1_DMA5_IN
13531 +       default y
13532 +       help
13533 +         Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0.
13534 +
13535 +config ETRAX_SPI_MMC_CD_SSER0_PIN
13536 +       string "MMC/SD card detect pin for SPI on sser0"
13537 +       depends on ETRAX_SPI_SSER0 && MMC_SPI
13538 +       default "pd11"
13539 +       help
13540 +         The pin to use for SD/MMC card detect.  This pin should be pulled up
13541 +         and grounded when a card is present.  If defined as " " (space), no
13542 +         pin is selected.  A card must then always be inserted for proper
13543 +         action.
13544 +
13545 +config ETRAX_SPI_MMC_WP_SSER0_PIN
13546 +       string "MMC/SD card write-protect pin for SPI on sser0"
13547 +       depends on ETRAX_SPI_SSER0 && MMC_SPI
13548 +       default "pd10"
13549 +       help
13550 +         The pin to use for the SD/MMC write-protect signal for a memory
13551 +         card.  If defined as " " (space), the card is considered writable.
13552 +
13553 +config ETRAX_SPI_SSER1
13554 +       tristate "SPI using synchronous serial port 1 (sser1)"
13555 +       depends on ETRAX_SPI_MMC
13556 +       default m if MMC_SPI=m && ETRAX_SPI_SSER0=n
13557 +       default y if MMC_SPI=y && ETRAX_SPI_SSER0=n
13558 +       default y if MMC_SPI=n && ETRAX_SPI_SSER0=n
13559 +       select SPI_ETRAX_SSER
13560 +       help
13561 +         Say Y for an MMC/SD socket connected to synchronous serial port 1,
13562 +         or for devices using the SPI protocol on that port.  Say m if you
13563 +         want to build it as a module, which will be named spi_crisv32_sser.
13564 +         (You need to select MMC separately.)
13565 +
13566 +config ETRAX_SPI_SSER1_DMA
13567 +       bool "DMA for SPI on sser1 enabled"
13568 +       depends on ETRAX_SPI_SSER1 && !ETRAX_ETHERNET_IFACE1
13569 +       depends on !ETRAX_SERIAL_PORT0_DMA6_OUT && !ETRAX_SERIAL_PORT0_DMA7_IN
13570 +       default y
13571 +       help
13572 +         Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1.
13573 +
13574 +config ETRAX_SPI_MMC_CD_SSER1_PIN
13575 +       string "MMC/SD card detect pin for SPI on sser1"
13576 +       depends on ETRAX_SPI_SSER1 && MMC_SPI 
13577 +       default "pd12"
13578 +       help
13579 +         The pin to use for SD/MMC card detect.  This pin should be pulled up
13580 +         and grounded when a card is present.  If defined as " " (space), no
13581 +         pin is selected.  A card must then always be inserted for proper
13582 +         action.
13583 +
13584 +config ETRAX_SPI_MMC_WP_SSER1_PIN
13585 +       string "MMC/SD card write-protect pin for SPI on sser1"
13586 +       depends on ETRAX_SPI_SSER1 && MMC_SPI
13587 +       default "pd9"
13588 +       help
13589 +         The pin to use for the SD/MMC write-protect signal for a memory
13590 +         card.  If defined as " " (space), the card is considered writable.
13591 +
13592 +config ETRAX_SPI_GPIO
13593 +       tristate "Bitbanged SPI using gpio pins"
13594 +       depends on ETRAX_SPI_MMC
13595 +       select SPI_ETRAX_GPIO
13596 +       default m if MMC_SPI=m && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13597 +       default y if MMC_SPI=y && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13598 +       default y if MMC_SPI=n && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13599 +       help
13600 +         Say Y for an MMC/SD socket connected to general I/O pins (but not
13601 +         a complete synchronous serial ports), or for devices using the SPI
13602 +         protocol on general I/O pins.  Slow and slows down the system.
13603 +         Say m to build it as a module, which will be called spi_crisv32_gpio.
13604 +         (You need to select MMC separately.)
13605 +
13606 +# The default match that of sser0, only because that's how it was tested.
13607 +config ETRAX_SPI_CS_PIN
13608 +       string "SPI chip select pin"
13609 +       depends on ETRAX_SPI_GPIO
13610 +       default "pc3"
13611 +       help
13612 +         The pin to use for SPI chip select.
13613 +
13614 +config ETRAX_SPI_CLK_PIN
13615 +       string "SPI clock pin"
13616 +       depends on ETRAX_SPI_GPIO
13617 +       default "pc1"
13618 +       help
13619 +         The pin to use for the SPI clock.
13620 +
13621 +config ETRAX_SPI_DATAIN_PIN
13622 +       string "SPI MISO (data in) pin"
13623 +       depends on ETRAX_SPI_GPIO
13624 +       default "pc16"
13625 +       help
13626 +         The pin to use for SPI data in from the device.
13627 +
13628 +config ETRAX_SPI_DATAOUT_PIN
13629 +       string "SPI MOSI (data out) pin"
13630 +       depends on ETRAX_SPI_GPIO
13631 +       default "pc0"
13632 +       help
13633 +         The pin to use for SPI data out to the device.
13634 +
13635 +config ETRAX_SPI_MMC_CD_GPIO_PIN
13636 +       string "MMC/SD card detect pin for SPI using gpio (space for none)"
13637 +       depends on ETRAX_SPI_GPIO && MMC_SPI
13638 +       default "pd11"
13639 +       help
13640 +         The pin to use for SD/MMC card detect.  This pin should be pulled up
13641 +         and grounded when a card is present.  If defined as " " (space), no
13642 +         pin is selected.  A card must then always be inserted for proper
13643 +         action.
13644 +
13645 +config ETRAX_SPI_MMC_WP_GPIO_PIN
13646 +       string "MMC/SD card write-protect pin for SPI using gpio (space for none)"
13647 +       depends on ETRAX_SPI_GPIO && MMC_SPI
13648 +       default "pd10"
13649 +       help
13650 +         The pin to use for the SD/MMC write-protect signal for a memory
13651 +         card.  If defined as " " (space), the card is considered writable.
13652 +
13653 +# Avoid choices causing non-working configs by conditionalizing the inclusion.
13654 +if ETRAX_SPI_MMC
13655 +source drivers/spi/Kconfig
13656 +endif
13657 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Makefile
13658 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Makefile      2007-01-10 20:10:37.000000000 +0100
13659 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Makefile      2007-01-29 16:14:16.000000000 +0100
13660 @@ -11,3 +11,4 @@
13661  obj-$(CONFIG_ETRAX_I2C)                        += i2c.o
13662  obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
13663  obj-$(CONFIG_PCI)                      += pci/
13664 +obj-$(CONFIG_ETRAX_SPI_MMC_BOARD)      += board_mmcspi.o
13665 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/axisflashmap.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/axisflashmap.c
13666 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/axisflashmap.c        2007-01-10 20:10:37.000000000 +0100
13667 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/axisflashmap.c        2007-02-06 17:37:50.000000000 +0100
13668 @@ -11,7 +11,7 @@
13669   * partition split defined below.
13670   *
13671   * Copy of os/lx25/arch/cris/arch-v10/drivers/axisflashmap.c 1.5
13672 - * with minor changes.
13673 + * with quite a few changes now.
13674   *
13675   */
13676  
13677 @@ -27,6 +27,8 @@
13678  #include <linux/mtd/mtdram.h>
13679  #include <linux/mtd/partitions.h>
13680  
13681 +#include <linux/cramfs_fs.h>
13682 +
13683  #include <asm/arch/hwregs/config_defs.h>
13684  #include <asm/axisflashmap.h>
13685  #include <asm/mmu.h>
13686 @@ -37,16 +39,24 @@
13687  #define FLASH_UNCACHED_ADDR  KSEG_E
13688  #define FLASH_CACHED_ADDR    KSEG_F
13689  
13690 +#define PAGESIZE (512)
13691 +
13692  #if CONFIG_ETRAX_FLASH_BUSWIDTH==1
13693  #define flash_data __u8
13694  #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
13695  #define flash_data __u16
13696  #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
13697 -#define flash_data __u16
13698 +#define flash_data __u32
13699  #endif
13700  
13701  /* From head.S */
13702 -extern unsigned long romfs_start, romfs_length, romfs_in_flash;
13703 +extern unsigned long romfs_in_flash; /* 1 when romfs_start, _length in flash */
13704 +extern unsigned long romfs_start, romfs_length;
13705 +extern unsigned long nand_boot; /* 1 when booted from nand flash */
13706 +
13707 +struct partition_name {
13708 +       char name[6];
13709 +};
13710  
13711  /* The master mtd for the entire flash. */
13712  struct mtd_info* axisflash_mtd = NULL;
13713 @@ -112,32 +122,20 @@
13714         .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
13715  };
13716  
13717 -/* If no partition-table was found, we use this default-set. */
13718 -#define MAX_PARTITIONS         7
13719 -#define NUM_DEFAULT_PARTITIONS 3
13720 +#define MAX_PARTITIONS                 7
13721 +#ifdef CONFIG_ETRAX_NANDBOOT
13722 +#define NUM_DEFAULT_PARTITIONS         4
13723 +#define DEFAULT_ROOTFS_PARTITION_NO    2
13724 +#define DEFAULT_MEDIA_SIZE              0x2000000 /* 32 megs */
13725 +#else
13726 +#define NUM_DEFAULT_PARTITIONS         3
13727 +#define DEFAULT_ROOTFS_PARTITION_NO    (-1)
13728 +#define DEFAULT_MEDIA_SIZE              0x800000 /* 8 megs */
13729 +#endif
13730  
13731 -/*
13732 - * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
13733 - * size of one flash block and "filesystem"-partition needs 5 blocks to be able
13734 - * to use JFFS.
13735 - */
13736 -static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13737 -       {
13738 -               .name = "boot firmware",
13739 -               .size = CONFIG_ETRAX_PTABLE_SECTOR,
13740 -               .offset = 0
13741 -       },
13742 -       {
13743 -               .name = "kernel",
13744 -               .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
13745 -               .offset = CONFIG_ETRAX_PTABLE_SECTOR
13746 -       },
13747 -       {
13748 -               .name = "filesystem",
13749 -               .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
13750 -               .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
13751 -       }
13752 -};
13753 +#if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS)
13754 +#error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS
13755 +#endif
13756  
13757  /* Initialize the ones normally used. */
13758  static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
13759 @@ -178,6 +176,56 @@
13760         },
13761  };
13762  
13763 +
13764 +/* If no partition-table was found, we use this default-set.
13765 + * Default flash size is 8MB (NOR). CONFIG_ETRAX_PTABLE_SECTOR is most 
13766 + * likely the size of one flash block and "filesystem"-partition needs 
13767 + * to be >=5 blocks to be able to use JFFS.
13768 + */
13769 +static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13770 +       {
13771 +               .name = "boot firmware",
13772 +               .size = CONFIG_ETRAX_PTABLE_SECTOR,
13773 +               .offset = 0
13774 +       },
13775 +       {
13776 +               .name = "kernel",
13777 +               .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13778 +               .offset = CONFIG_ETRAX_PTABLE_SECTOR
13779 +       },
13780 +#define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR)
13781 +#ifdef CONFIG_ETRAX_NANDBOOT
13782 +       {
13783 +               .name = "rootfs",
13784 +               .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13785 +               .offset = FILESYSTEM_SECTOR
13786 +       },
13787 +#undef FILESYSTEM_SECTOR
13788 +#define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR)
13789 +#endif
13790 +       {
13791 +               .name = "rwfs",
13792 +               .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR,
13793 +               .offset = FILESYSTEM_SECTOR
13794 +       }
13795 +};
13796 +
13797 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
13798 +/* Main flash device */
13799 +static struct mtd_partition main_partition = {
13800 +       .name = "main",
13801 +       .size = 0,
13802 +       .offset = 0
13803 +};
13804 +#endif
13805 +
13806 +/* Auxilliary partition if we find another flash */
13807 +static struct mtd_partition aux_partition = {
13808 +       .name = "aux",
13809 +       .size = 0,
13810 +       .offset = 0
13811 +};
13812 +
13813  /*
13814   * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
13815   * chips in that order (because the amd_flash-driver is faster).
13816 @@ -186,23 +234,23 @@
13817  {
13818         struct mtd_info *mtd_cs = NULL;
13819  
13820 -       printk(KERN_INFO
13821 +       printk(KERN_INFO 
13822                "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
13823                map_cs->name, map_cs->size, map_cs->map_priv_1);
13824  
13825 -#ifdef CONFIG_MTD_AMDSTD
13826 -       mtd_cs = do_map_probe("amd_flash", map_cs);
13827 -#endif
13828  #ifdef CONFIG_MTD_CFI
13829 +       mtd_cs = do_map_probe("cfi_probe", map_cs);
13830 +#endif
13831 +#ifdef CONFIG_MTD_JEDECPROBE
13832         if (!mtd_cs) {
13833 -               mtd_cs = do_map_probe("cfi_probe", map_cs);
13834 +               mtd_cs = do_map_probe("jedec_probe", map_cs);
13835         }
13836  #endif
13837  
13838         return mtd_cs;
13839  }
13840  
13841 -/*
13842 +/* 
13843   * Probe each chip select individually for flash chips. If there are chips on
13844   * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
13845   * so that MTD partitions can cross chip boundries.
13846 @@ -217,22 +265,17 @@
13847  {
13848         struct mtd_info *mtd_cse0;
13849         struct mtd_info *mtd_cse1;
13850 -       struct mtd_info *mtd_nand = NULL;
13851         struct mtd_info *mtd_total;
13852 -       struct mtd_info *mtds[3];
13853 +       struct mtd_info *mtds[2];
13854         int count = 0;
13855  
13856         if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL)
13857                 mtds[count++] = mtd_cse0;
13858         if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL)
13859                 mtds[count++] = mtd_cse1;
13860 +       
13861  
13862 -#ifdef CONFIG_ETRAX_NANDFLASH
13863 -       if ((mtd_nand = crisv32_nand_flash_probe()) != NULL)
13864 -               mtds[count++] = mtd_nand;
13865 -#endif
13866 -
13867 -       if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) {
13868 +       if (!mtd_cse0 && !mtd_cse1) {
13869                 /* No chip found. */
13870                 return NULL;
13871         }
13872 @@ -248,7 +291,7 @@
13873                  */
13874                 mtd_total = mtd_concat_create(mtds,
13875                                               count,
13876 -                                             "cse0+cse1+nand");
13877 +                                             "cse0+cse1");
13878  #else
13879                 printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "
13880                        "(mis)configuration!\n", map_cse0.name, map_cse1.name);
13881 @@ -260,57 +303,155 @@
13882  
13883                         /* The best we can do now is to only use what we found
13884                          * at cse0.
13885 -                        */
13886 +                        */ 
13887                         mtd_total = mtd_cse0;
13888                         map_destroy(mtd_cse1);
13889                 }
13890         } else {
13891 -               mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand;
13892 -
13893 +               mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1;
13894 +               
13895         }
13896  
13897         return mtd_total;
13898  }
13899  
13900 -extern unsigned long crisv32_nand_boot;
13901 -extern unsigned long crisv32_nand_cramfs_offset;
13902 -
13903  /*
13904   * Probe the flash chip(s) and, if it succeeds, read the partition-table
13905   * and register the partitions with MTD.
13906   */
13907  static int __init init_axis_flash(void)
13908  {
13909 -       struct mtd_info *mymtd;
13910 +       struct mtd_info *main_mtd;
13911 +       struct mtd_info *aux_mtd = NULL;
13912         int err = 0;
13913         int pidx = 0;
13914         struct partitiontable_head *ptable_head = NULL;
13915         struct partitiontable_entry *ptable;
13916 -       int use_default_ptable = 1; /* Until proven otherwise. */
13917 -       const char *pmsg = KERN_INFO "  /dev/flash%d at 0x%08x, size 0x%08x\n";
13918 -       static char page[512];
13919 +       int ptable_ok = 0;
13920 +       static char page[PAGESIZE];
13921         size_t len;
13922 +       int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */
13923 +       int part;
13924 +
13925 +       /* We need a root fs. If it resides in RAM, we need to use an
13926 +        * MTDRAM device, so it must be enabled in the kernel config,
13927 +        * but its size must be configured as 0 so as not to conflict
13928 +        * with our usage.
13929 +        */
13930 +#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
13931 +       if (!romfs_in_flash && !nand_boot) {
13932 +               printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
13933 +                      "device; configure CONFIG_MTD_MTDRAM with size = 0!\n");
13934 +               panic("This kernel cannot boot from RAM!\n");
13935 +       }
13936 +#endif
13937  
13938  #ifndef CONFIG_ETRAXFS_SIM
13939 -       mymtd = flash_probe();
13940 -       mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page);
13941 -       ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET);
13942 +       main_mtd = flash_probe();
13943 +       if (main_mtd)
13944 +               printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n",
13945 +                      main_mtd->name, main_mtd->size);
13946 +
13947 +#ifdef CONFIG_ETRAX_NANDFLASH
13948 +       aux_mtd = crisv32_nand_flash_probe();
13949 +       if (aux_mtd)
13950 +               printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n",
13951 +                       aux_mtd->name, aux_mtd->size);
13952  
13953 -       if (!mymtd) {
13954 +#ifdef CONFIG_ETRAX_NANDBOOT
13955 +       {
13956 +               struct mtd_info *tmp_mtd;
13957 +
13958 +               printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, "
13959 +                      "making NAND flash primary device.\n");
13960 +               tmp_mtd = main_mtd;
13961 +               main_mtd = aux_mtd;
13962 +               aux_mtd = tmp_mtd;
13963 +       }
13964 +#endif /* CONFIG_ETRAX_NANDBOOT */
13965 +#endif /* CONFIG_ETRAX_NANDFLASH */
13966 +
13967 +       if (!main_mtd && !aux_mtd) {
13968                 /* There's no reason to use this module if no flash chip can
13969                  * be identified. Make sure that's understood.
13970                  */
13971                 printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
13972 -       } else {
13973 -               printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
13974 -                      mymtd->name, mymtd->size);
13975 -               axisflash_mtd = mymtd;
13976         }
13977  
13978 -       if (mymtd) {
13979 -               mymtd->owner = THIS_MODULE;
13980 +#if 0 /* Dump flash memory so we can see what is going on */
13981 +       if (main_mtd) {
13982 +               int sectoraddr, i;
13983 +               for (sectoraddr = 0; sectoraddr < 2*65536+4096; sectoraddr += PAGESIZE) {
13984 +                       main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, page);
13985 +                       printk(KERN_INFO
13986 +                              "Sector at %d (length %d):\n",
13987 +                              sectoraddr, len);
13988 +                       for (i = 0; i < PAGESIZE; i += 16) {
13989 +                               printk(KERN_INFO
13990 +                                      "%02x %02x %02x %02x %02x %02x %02x %02x "
13991 +                                      "%02x %02x %02x %02x %02x %02x %02x %02x\n",
13992 +                                      page[i] & 255, page[i+1] & 255, 
13993 +                                      page[i+2] & 255, page[i+3] & 255, 
13994 +                                      page[i+4] & 255, page[i+5] & 255, 
13995 +                                      page[i+6] & 255, page[i+7] & 255,
13996 +                                      page[i+8] & 255, page[i+9] & 255, 
13997 +                                      page[i+10] & 255, page[i+11] & 255, 
13998 +                                      page[i+12] & 255, page[i+13] & 255, 
13999 +                                      page[i+14] & 255, page[i+15] & 255);
14000 +                       }
14001 +                       
14002 +               }
14003 +       }
14004 +#endif
14005 +
14006 +       if (main_mtd) {
14007 +               main_mtd->owner = THIS_MODULE;
14008 +               axisflash_mtd = main_mtd;
14009 +
14010 +               loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR;
14011 +
14012 +               pidx++;  /* First partition (rescue) is always set to the default. */
14013 +#ifdef CONFIG_ETRAX_NANDBOOT
14014 +               /* We know where the partition table should be located,
14015 +                * it will be in first good block after that.
14016 +                */
14017 +               int blockstat;
14018 +               do {
14019 +                       blockstat = main_mtd->block_isbad(main_mtd, ptable_sector);
14020 +                       if (blockstat < 0)
14021 +                               ptable_sector = 0; /* read error */
14022 +                       else if (blockstat)
14023 +                               ptable_sector += main_mtd->erasesize;
14024 +               } while (blockstat && ptable_sector);
14025 +#endif
14026 +               if (ptable_sector) {
14027 +                       main_mtd->read(main_mtd, ptable_sector, PAGESIZE, &len, page);
14028 +                       ptable_head = &((struct partitiontable *) page)->head;
14029 +               }
14030 +
14031 +#if 0 /* Dump partition table so we can see what is going on */
14032 +               printk(KERN_INFO
14033 +                      "axisflashmap: flash read %d bytes at 0x%08x, data: "
14034 +                      "%02x %02x %02x %02x %02x %02x %02x %02x\n",
14035 +                      len, CONFIG_ETRAX_PTABLE_SECTOR, 
14036 +                      page[0] & 255, page[1] & 255, 
14037 +                      page[2] & 255, page[3] & 255, 
14038 +                      page[4] & 255, page[5] & 255, 
14039 +                      page[6] & 255, page[7] & 255);
14040 +               printk(KERN_INFO
14041 +                      "axisflashmap: partition table offset %d, data: "
14042 +                      "%02x %02x %02x %02x %02x %02x %02x %02x\n",
14043 +                      PARTITION_TABLE_OFFSET,
14044 +                      page[PARTITION_TABLE_OFFSET+0] & 255,
14045 +                      page[PARTITION_TABLE_OFFSET+1] & 255,
14046 +                      page[PARTITION_TABLE_OFFSET+2] & 255,
14047 +                      page[PARTITION_TABLE_OFFSET+3] & 255,
14048 +                      page[PARTITION_TABLE_OFFSET+4] & 255,
14049 +                      page[PARTITION_TABLE_OFFSET+5] & 255,
14050 +                      page[PARTITION_TABLE_OFFSET+6] & 255,
14051 +                      page[PARTITION_TABLE_OFFSET+7] & 255);
14052 +#endif
14053         }
14054 -       pidx++;  /* First partition is always set to the default. */
14055  
14056         if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
14057             && (ptable_head->size <
14058 @@ -323,7 +464,6 @@
14059                 /* Looks like a start, sane length and end of a
14060                  * partition table, lets check csum etc.
14061                  */
14062 -               int ptable_ok = 0;
14063                 struct partitiontable_entry *max_addr =
14064                         (struct partitiontable_entry *)
14065                         ((unsigned long)ptable_head + sizeof(*ptable_head) +
14066 @@ -331,7 +471,7 @@
14067                 unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
14068                 unsigned char *p;
14069                 unsigned long csum = 0;
14070 -
14071 +               
14072                 ptable = (struct partitiontable_entry *)
14073                         ((unsigned long)ptable_head + sizeof(*ptable_head));
14074  
14075 @@ -343,108 +483,177 @@
14076                         csum += *p++;
14077                         csum += *p++;
14078                         csum += *p++;
14079 -               }
14080 +               }                
14081                 ptable_ok = (csum == ptable_head->checksum);
14082  
14083                 /* Read the entries and use/show the info.  */
14084 -               printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
14085 +               printk(KERN_INFO "axisflashmap: "
14086 +                      "Found a%s partition table at 0x%p-0x%p.\n",
14087                        (ptable_ok ? " valid" : "n invalid"), ptable_head,
14088                        max_addr);
14089  
14090                 /* We have found a working bootblock.  Now read the
14091 -                * partition table.  Scan the table.  It ends when
14092 -                * there is 0xffffffff, that is, empty flash.
14093 +                * partition table.  Scan the table.  It ends with 0xffffffff.
14094                  */
14095                 while (ptable_ok
14096 -                      && ptable->offset != 0xffffffff
14097 +                      && ptable->offset != PARTITIONTABLE_END_MARKER
14098                        && ptable < max_addr
14099 -                      && pidx < MAX_PARTITIONS) {
14100 +                      && pidx < MAX_PARTITIONS - 1) {
14101  
14102 -                       axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0);
14103 -                       axis_partitions[pidx].size = ptable->size;
14104 -
14105 -                       printk(pmsg, pidx, axis_partitions[pidx].offset,
14106 -                              axis_partitions[pidx].size);
14107 +                       axis_partitions[pidx].offset = offset + ptable->offset;
14108 +#ifdef CONFIG_ETRAX_NANDFLASH
14109 +                       if (main_mtd->type == MTD_NANDFLASH) {
14110 +                               axis_partitions[pidx].size = 
14111 +                                       (((ptable+1)->offset == 
14112 +                                         PARTITIONTABLE_END_MARKER) ? 
14113 +                                         main_mtd->size : 
14114 +                                         ((ptable+1)->offset + offset)) - 
14115 +                                       (ptable->offset + offset);
14116 +
14117 +                       } else
14118 +#endif /* CONFIG_ETRAX_NANDFLASH */
14119 +                               axis_partitions[pidx].size = ptable->size;
14120 +#ifdef CONFIG_ETRAX_NANDBOOT
14121 +                       /* Save partition number of jffs2 ro partition.
14122 +                        * Needed if RAM booting or root file system in RAM.
14123 +                        */
14124 +                       if (!nand_boot &&
14125 +                           ram_rootfs_partition < 0 && /* not already set */
14126 +                           ptable->type == PARTITION_TYPE_JFFS2 &&
14127 +                           (ptable->flags & PARTITION_FLAGS_READONLY_MASK) == 
14128 +                               PARTITION_FLAGS_READONLY)
14129 +                               ram_rootfs_partition = pidx;
14130 +#endif /* CONFIG_ETRAX_NANDBOOT */
14131                         pidx++;
14132                         ptable++;
14133                 }
14134 -               use_default_ptable = !ptable_ok;
14135         }
14136  
14137 -       if (romfs_in_flash) {
14138 -               /* Add an overlapping device for the root partition (romfs). */
14139 +       /* Decide whether to use default partition table. */
14140 +       /* Only use default table if we actually have a device (main_mtd) */
14141  
14142 -               axis_partitions[pidx].name = "romfs";
14143 -               if (crisv32_nand_boot) {
14144 -                       char* data = kmalloc(1024, GFP_KERNEL);
14145 -                       int len;
14146 -                       int offset = crisv32_nand_cramfs_offset & ~(1024-1);
14147 -                       char* tmp;
14148 -
14149 -                       mymtd->read(mymtd, offset, 1024, &len, data);
14150 -                       tmp = &data[crisv32_nand_cramfs_offset % 512];
14151 -                       axis_partitions[pidx].size = *(unsigned*)(tmp + 4);
14152 -                       axis_partitions[pidx].offset = crisv32_nand_cramfs_offset;
14153 -                       kfree(data);
14154 -               } else {
14155 -                       axis_partitions[pidx].size = romfs_length;
14156 -                       axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
14157 -               }
14158 +       struct mtd_partition *partition = &axis_partitions[0];
14159 +       if (main_mtd && !ptable_ok) {
14160 +               memcpy(axis_partitions, axis_default_partitions,
14161 +                      sizeof(axis_default_partitions));
14162 +               pidx = NUM_DEFAULT_PARTITIONS;
14163 +               ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO;
14164 +       }
14165  
14166 +       /* Add artificial partitions for rootfs if necessary */
14167 +       if (romfs_in_flash) {
14168 +               /* rootfs is in directly accessible flash memory = NOR flash.
14169 +                  Add an overlapping device for the rootfs partition. */
14170 +               printk(KERN_INFO "axisflashmap: Adding partition for "
14171 +                      "overlapping root file system image\n");
14172 +               axis_partitions[pidx].size = romfs_length;
14173 +               axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
14174 +               axis_partitions[pidx].name = "romfs";
14175                 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
14176 -
14177 -               printk(KERN_INFO
14178 -                       " Adding readonly flash partition for romfs image:\n");
14179 -               printk(pmsg, pidx, axis_partitions[pidx].offset,
14180 -                      axis_partitions[pidx].size);
14181 +               ram_rootfs_partition = -1;
14182                 pidx++;
14183         }
14184 -
14185 -        if (mymtd) {
14186 -               if (use_default_ptable) {
14187 -                       printk(KERN_INFO " Using default partition table.\n");
14188 -                       err = add_mtd_partitions(mymtd, axis_default_partitions,
14189 -                                                NUM_DEFAULT_PARTITIONS);
14190 -               } else {
14191 -                       err = add_mtd_partitions(mymtd, axis_partitions, pidx);
14192 +       else if (romfs_length && !nand_boot) {
14193 +               /* romfs exists in memory, but not in flash, so must be in RAM.
14194 +                * Configure an MTDRAM partition. */
14195 +               if (ram_rootfs_partition < 0) { /* none set yet */
14196 +                       ram_rootfs_partition = pidx; /* put it at the end */
14197 +                       pidx++;
14198                 }
14199 +               printk(KERN_INFO "axisflashmap: Adding partition for "
14200 +                      "root file system image in RAM\n");
14201 +               axis_partitions[ram_rootfs_partition].size = romfs_length;
14202 +               axis_partitions[ram_rootfs_partition].offset = romfs_start;
14203 +               axis_partitions[ram_rootfs_partition].name = "romfs";
14204 +               axis_partitions[ram_rootfs_partition].mask_flags |= 
14205 +                       MTD_WRITEABLE;
14206 +       }
14207  
14208 -               if (err) {
14209 -                       panic("axisflashmap could not add MTD partitions!\n");
14210 -               }
14211 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
14212 +       if (main_mtd) {
14213 +               main_partition.size = main_mtd->size;
14214 +                err = add_mtd_partitions(main_mtd, &main_partition, 1);
14215 +               if (err)
14216 +                       panic("axisflashmap: Could not initialize "
14217 +                             "partition for whole main mtd device!\n");
14218         }
14219 -/* CONFIG_EXTRAXFS_SIM */
14220  #endif
14221  
14222 -       if (!romfs_in_flash) {
14223 -               /* Create an RAM device for the root partition (romfs). */
14224 +       /* Now, register all partitions with mtd.
14225 +        * We do this one at a time so we can slip in an MTDRAM device
14226 +        * in the proper place if required. */
14227 +
14228 +       for (part = 0; part < pidx; part++) {
14229 +               if (part == ram_rootfs_partition) {
14230 +                       /* add MTDRAM partition here */
14231 +                       struct mtd_info *mtd_ram;
14232 +
14233 +                       mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
14234 +                       if (!mtd_ram)
14235 +                               panic("axisflashmap: Couldn't allocate memory "
14236 +                                     "for mtd_info!\n");
14237 +                       printk(KERN_INFO "axisflashmap: Adding RAM partition "
14238 +                              "for rootfs image.\n");
14239 +                       err = mtdram_init_device(mtd_ram, 
14240 +                                                (void *)partition[part].offset,
14241 +                                                partition[part].size,
14242 +                                                partition[part].name);
14243 +                       if (err)
14244 +                               panic("axisflashmap: Could not initialize "
14245 +                                     "MTD RAM device!\n");
14246 +                       /* JFFS2 likes to have an erasesize. Keep potential
14247 +                        * JFFS2 rootfs happy by providing one. Since image
14248 +                        * was most likely created for main mtd, use that
14249 +                        * erasesize, if available. Otherwise, make a guess. */
14250 +                       mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize :
14251 +                                                        CONFIG_ETRAX_PTABLE_SECTOR);
14252 +               } else {
14253 +                       err = add_mtd_partitions(main_mtd, 
14254 +                                                &partition[part], 1);
14255 +                       if (err)
14256 +                               panic("axisflashmap: Could not add mtd "
14257 +                                     "partition %d\n", part);
14258 +               }
14259 +       }
14260  
14261 -#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
14262 -               /* No use trying to boot this kernel from RAM. Panic! */
14263 -               printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
14264 -                      "device due to kernel (mis)configuration!\n");
14265 -               panic("This kernel cannot boot from RAM!\n");
14266 -#else
14267 -               struct mtd_info *mtd_ram;
14268 +#endif /* CONFIG_EXTRAXFS_SIM */
14269  
14270 -               mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14271 -                                                    GFP_KERNEL);
14272 -               if (!mtd_ram) {
14273 -                       panic("axisflashmap couldn't allocate memory for "
14274 -                             "mtd_info!\n");
14275 -               }
14276 +#ifdef CONFIG_ETRAXFS_SIM
14277 +       /* For simulator, always use a RAM partition.
14278 +        * The rootfs will be found after the kernel in RAM,
14279 +        * with romfs_start and romfs_end indicating location and size.
14280 +        */
14281 +       struct mtd_info *mtd_ram;
14282 +
14283 +       mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14284 +                                            GFP_KERNEL);
14285 +       if (!mtd_ram) {
14286 +               panic("axisflashmap: Couldn't allocate memory for "
14287 +                     "mtd_info!\n");
14288 +       }
14289  
14290 -               printk(KERN_INFO " Adding RAM partition for romfs image:\n");
14291 -               printk(pmsg, pidx, romfs_start, romfs_length);
14292 +       printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, "
14293 +              "at %u, size %u\n",
14294 +              (unsigned) romfs_start, (unsigned) romfs_length);
14295 +
14296 +       err = mtdram_init_device(mtd_ram, (void*)romfs_start, 
14297 +                                romfs_length, "romfs");
14298 +       if (err) {
14299 +               panic("axisflashmap: Could not initialize MTD RAM "
14300 +                     "device!\n");
14301 +       }
14302 +#endif /* CONFIG_EXTRAXFS_SIM */
14303 +
14304 +#ifndef CONFIG_ETRAXFS_SIM
14305 +       if (aux_mtd) {
14306 +               aux_partition.size = aux_mtd->size;
14307 +                err = add_mtd_partitions(aux_mtd, &aux_partition, 1);
14308 +               if (err)
14309 +                       panic("axisflashmap: Could not initialize "
14310 +                             "aux mtd device!\n");
14311  
14312 -               err = mtdram_init_device(mtd_ram, (void*)romfs_start,
14313 -                                        romfs_length, "romfs");
14314 -               if (err) {
14315 -                       panic("axisflashmap could not initialize MTD RAM "
14316 -                             "device!\n");
14317 -               }
14318 -#endif
14319         }
14320 +#endif /* CONFIG_EXTRAXFS_SIM */
14321  
14322         return err;
14323  }
14324 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/board_mmcspi.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/board_mmcspi.c
14325 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/board_mmcspi.c        1970-01-01 01:00:00.000000000 +0100
14326 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/board_mmcspi.c        2007-01-29 15:51:19.000000000 +0100
14327 @@ -0,0 +1,686 @@
14328 +/*
14329 + * Somewhat generic "board-side" code to support SPI drivers for chips
14330 + * with a CRIS v32 and later.  Not really board-specific, and only for
14331 + * registration of SPI devices for MMC, hence the "mmcspi" part of the
14332 + * name instead of a proper board name.
14333 + *
14334 + * Copyright (c) 2007 Axis Communications AB
14335 + *
14336 + * TODO: SDIO interrupt-pin support (though can't be done until
14337 + * there's support added in both the mmc_spi and the mmc frameworks).
14338 + *
14339 + * This program is free software; you can redistribute it and/or modify
14340 + * it under the terms of the GNU General Public License as published by
14341 + * the Free Software Foundation; either version 2 of the License, or
14342 + * (at your option) any later version.
14343 + */
14344 +
14345 +#include <linux/types.h>
14346 +#include <linux/platform_device.h>
14347 +#include <linux/spi/spi.h>
14348 +#include <linux/spi/mmc_spi.h>
14349 +#include <linux/mmc/host.h>
14350 +#include <asm/arch/board.h>
14351 +#include <asm/arch/pinmux.h>
14352 +#include <asm/arch/dma.h>
14353 +#include <linux/err.h>
14354 +
14355 +#include <asm/io.h>
14356 +
14357 +/* We need some housekeeping.  */
14358 +#define CONCAT_(a, b) a ## b
14359 +#define CONCAT(a, b) CONCAT_(a, b)
14360 +#define CONCAT3(a, b, c) CONCAT(CONCAT(a, b), c)
14361 +
14362 +/* Grr.  Why not define them as usual in autoconf, #ifdef REVEAL_MODULES?  */
14363 +#if !defined(CONFIG_SPI_ETRAX_SSER) && defined(CONFIG_SPI_ETRAX_SSER_MODULE)
14364 +#define CONFIG_SPI_ETRAX_SSER
14365 +#endif
14366 +
14367 +#if !defined(CONFIG_ETRAX_SPI_SSER0) && defined(CONFIG_ETRAX_SPI_SSER0_MODULE)
14368 +#define CONFIG_ETRAX_SPI_SSER0
14369 +#endif
14370 +
14371 +#if !defined(CONFIG_ETRAX_SPI_SSER1) && defined(CONFIG_ETRAX_SPI_SSER1_MODULE)
14372 +#define CONFIG_ETRAX_SPI_SSER1
14373 +#endif
14374 +
14375 +#if !defined(CONFIG_SPI_ETRAX_GPIO) && defined(CONFIG_SPI_ETRAX_GPIO_MODULE)
14376 +#define CONFIG_SPI_ETRAX_GPIO
14377 +#endif
14378 +
14379 +#define CONFIGURED_PIN(x) ((x) != NULL && *(x) != 0 && *(x) != ' ')
14380 +
14381 +/* Helper function to configure an iopin for input.  */
14382 +
14383 +static int crisv32_config_pin_in(struct crisv32_iopin *pin, const char *name)
14384 +{
14385 +       int ret = crisv32_io_get_name(pin, name);
14386 +       if (ret)
14387 +               return ret;
14388 +
14389 +       crisv32_io_set_dir(pin, crisv32_io_dir_in);
14390 +       return 0;
14391 +}
14392 +
14393 +/*
14394 + * Writable data pointed to by the constant parts of each MMC_SPI bus
14395 + * interface.  Should only hold MMC-specific state (for the
14396 + * MMC-specific pins), nothing SPI-generic.
14397 + */
14398 +
14399 +struct crisv32_mmc_spi_pinstate {
14400 +       struct crisv32_iopin write_protect_pin;
14401 +       struct crisv32_iopin card_detect_pin;
14402 +
14403 +       /* We must poll for card-detect, which we do each:  */
14404 +#define CARD_DETECT_CHECK_INTERVAL (2*HZ)
14405 +       /* We poll using a self-arming workqueue function.  */
14406 +       struct work_struct cd_work;
14407 +
14408 +       /* When we detect a change in card presence, we call this
14409 +        * function, supplied by the mmc_spi framework: */
14410 +       irqreturn_t (*detectfunc)(int, void *);
14411 +
14412 +       /*
14413 +        * We call that function with this parameter as the second
14414 +        * one.  We must assume the other parameters are unused, as we
14415 +        * don't have an interrupt context.
14416 +        */
14417 +       void *detectfunc_param2;
14418 +
14419 +       /* State for the card-detect worker. */
14420 +       int card_present;
14421 +};
14422 +
14423 +/* Rearming "work" function for card-detect polling.  */
14424 +
14425 +static void crisv32_cd_worker(void *x)
14426 +{
14427 +       struct crisv32_mmc_spi_pinstate *state = x;
14428 +
14429 +       /* It's a pull-up, so a card is present when 0.  */
14430 +       int card_present = crisv32_io_rd(&state->card_detect_pin) == 0;
14431 +
14432 +       if (card_present != state->card_present) {
14433 +               state->card_present = card_present;
14434 +               state->detectfunc(0, state->detectfunc_param2);
14435 +       }
14436 +       schedule_delayed_work(&state->cd_work, CARD_DETECT_CHECK_INTERVAL);
14437 +}
14438 +
14439 +/* The parts of MMC-specific configuration common to GPIO and SSER.  */
14440 +
14441 +static int crisv32_mmcspi_config_common(struct spi_device *spidev,
14442 +                                       irqreturn_t (*intfunc)(int, void *),
14443 +                               struct mmc_host *mmc_host,
14444 +                               const struct crisv32_mmc_spi_pindata *pd)
14445 +{
14446 +       int ret = 0;
14447 +       struct crisv32_mmc_spi_pinstate *ps = pd->pinstate;
14448 +
14449 +       /*
14450 +        * If we don't have a card-detect pin, the card must be
14451 +        * present at startup (including insmod/modprobe).  No
14452 +        * re-scans are done if no card is present at that time.
14453 +        */
14454 +       if (CONFIGURED_PIN(pd->card_detect)) {
14455 +               ret = crisv32_config_pin_in(&ps->card_detect_pin,
14456 +                                           pd->card_detect);
14457 +
14458 +               if (ret != 0)
14459 +                       goto bad_card_detect;
14460 +
14461 +               /* Need to cast away const from pd, unfortunately.  */
14462 +               INIT_WORK(&ps->cd_work, crisv32_cd_worker, (void *) ps);
14463 +               ps->card_present = 1;
14464 +               ps->detectfunc = intfunc;
14465 +               ps->detectfunc_param2 = mmc_host;
14466 +               crisv32_cd_worker(ps);
14467 +       } else
14468 +               ps->detectfunc = NULL;
14469 +
14470 +       /*
14471 +        * We set up for checking for presence of a write-protect pin
14472 +        * as pin.port being non-NULL.
14473 +        */
14474 +       memset(&ps->write_protect_pin, 0, sizeof ps->write_protect_pin);
14475 +       if (CONFIGURED_PIN(pd->write_protect)) {
14476 +               ret = crisv32_config_pin_in(&ps->write_protect_pin,
14477 +                                           pd->write_protect);
14478 +
14479 +               if (ret != 0)
14480 +                       goto bad_write_protect;
14481 +       }
14482 +
14483 +       return 0;
14484 +
14485 + bad_write_protect:
14486 +       if (ps->detectfunc) {
14487 +               cancel_rearming_delayed_work(&ps->cd_work);
14488 +               ps->detectfunc = NULL;
14489 +       }
14490 +
14491 + bad_card_detect:
14492 +       return ret;
14493 +}
14494 +
14495 +/* A function to undo crisv32_mmcspi_config_common.  */
14496 +
14497 +static void crisv32_mmcspi_deconfig_common(const struct
14498 +                                          crisv32_mmc_spi_pindata *pd)
14499 +{
14500 +       if (pd->pinstate->detectfunc) {
14501 +               cancel_rearming_delayed_work(&pd->pinstate->cd_work);
14502 +               pd->pinstate->detectfunc = NULL;
14503 +       }
14504 +
14505 +       /* We don't have to undo the pin allocations, being GPIO.  */
14506 +}
14507 +
14508 +/* Helper function for write-protect sense.  */
14509 +
14510 +static int crisv32_mmcspi_get_ro_helper(struct crisv32_mmc_spi_pinstate *ps)
14511 +{
14512 +       return ps->write_protect_pin.port != NULL
14513 +               && crisv32_io_rd(&ps->write_protect_pin) != 0;
14514 +}
14515 +
14516 +/* The hardware-interface-specific SPI+MMC parts.  */
14517 +
14518 +#ifdef CONFIG_SPI_ETRAX_SSER
14519 +static const char crisv32_matching_spi_sser_driver_name[] __init_or_module
14520 + = "spi_crisv32_sser";
14521 +
14522 +/*
14523 + * Make up something we can use in tables and function without
14524 + * #ifdef-cluttering.
14525 + */
14526 +#ifdef CONFIG_ETRAX_SPI_SSER0_DMA
14527 +#define WITH_ETRAX_SPI_SSER0_DMA 1
14528 +#else
14529 +#define WITH_ETRAX_SPI_SSER0_DMA 0
14530 +#endif
14531 +#ifdef CONFIG_ETRAX_SPI_SSER1_DMA
14532 +#define WITH_ETRAX_SPI_SSER1_DMA 1
14533 +#else
14534 +#define WITH_ETRAX_SPI_SSER1_DMA 0
14535 +#endif
14536 +
14537 +/* Write-protect sense for the SSER interface.  */
14538 +
14539 +static int crisv32_mmcspi_sser_get_ro(struct device *dev)
14540 +{
14541 +       struct spi_device *spidev = to_spi_device(dev);
14542 +       struct crisv32_mmc_spi_sser_hwdata *sser_defs
14543 +               = spidev->controller_data;
14544 +       struct crisv32_mmc_spi_pindata *pd = &sser_defs->mmc;
14545 +       return crisv32_mmcspi_get_ro_helper(pd->pinstate);
14546 +}
14547 +
14548 +/* Initialize the MMC-specific parts of the MMC+SPI interface, SSER.  */
14549 +
14550 +static int crisv32_mmcspi_sser_init(struct device *dev,
14551 +                                   irqreturn_t (*intfunc)(int, void *),
14552 +                                   void *xmmc_host)
14553 +{
14554 +       struct mmc_host *mmc_host = xmmc_host;
14555 +       struct spi_device *spidev = to_spi_device(dev);
14556 +       struct crisv32_mmc_spi_sser_hwdata *sser_defs
14557 +               = spidev->controller_data;
14558 +       int ret = crisv32_mmcspi_config_common(spidev, intfunc, mmc_host,
14559 +                                              &sser_defs->mmc);
14560 +       if (ret != 0)
14561 +               return ret;
14562 +
14563 +       mmc_host->f_max = spidev->max_speed_hz;
14564 +
14565 +       /*
14566 +        * Let's just set this to ceil(100e6/65536).  It wouldn't be
14567 +        * hard to change the base frequency to support down to 450Hz,
14568 +        * but there's no apparent requirement from known hardware.
14569 +        * Would also require adjustments to the SPI code, not just
14570 +        * here.
14571 +        *
14572 +        * On second thought, let's not set f_min unconditionally, as
14573 +        * mmc doesn't treat it as a limit, but as the frequency to
14574 +        * use at initialization.  We stick with what mmc_spi sets, if
14575 +        * it fits.
14576 +        */
14577 +       if (mmc_host->f_min < 1526)
14578 +               mmc_host->f_min = 1526;
14579 +
14580 +       dev_info(dev, "CRIS v32 mmc_spi support hooked to SPI on sser%d"
14581 +                " (cd: %s, wp: %s)\n",
14582 +                spidev->master->bus_num,
14583 +                CONFIGURED_PIN(sser_defs->mmc.card_detect)
14584 +                ? sser_defs->mmc.card_detect : "(none)",
14585 +                CONFIGURED_PIN(sser_defs->mmc.write_protect)
14586 +                ? sser_defs->mmc.write_protect : "(none)");
14587 +       return 0;
14588 +}
14589 +
14590 +/* Similarly, to undo crisv32_mmcspi_sser_init.  */
14591 +
14592 +static void crisv32_mmcspi_sser_exit(struct device *dev, void *xmmc_host)
14593 +{
14594 +       struct spi_device *spidev = to_spi_device(dev);
14595 +       struct crisv32_mmc_spi_sser_hwdata *sser_defs
14596 +               = spidev->controller_data;
14597 +
14598 +       crisv32_mmcspi_deconfig_common(&sser_defs->mmc);
14599 +}
14600 +
14601 +/*
14602 + * Connect sser and DMA channels and return the proper numbers to use.
14603 + *
14604 + * This function exists really only to avoid having the following constants
14605 + * tabled: regi_sserN, SSERn_INTR_VECT, pinmux_sserN, SYNC_SERn_TX_DMA_NBR,
14606 + * SYNC_SERn_RX_DMA_NBR dma_sserN, regi_dmaM, regi_dmaN, DMAm_INTR_VECT,
14607 + * DMAn_INTR_VECT.  I might have missed some. :-)
14608 + */
14609 +static int crisv32_allocate_sser(struct crisv32_regi_n_int *sserp,
14610 +                                struct crisv32_regi_n_int *dmainp,
14611 +                                struct crisv32_regi_n_int *dmaoutp,
14612 +                                u32 sserno)
14613 +{
14614 +       int ret;
14615 +       u32 regi_sser = sserno == 0 ? regi_sser0 : regi_sser1;
14616 +       u32 sser_irq = sserno == 0 ? SSER0_INTR_VECT : SSER1_INTR_VECT;
14617 +       BUG_ON(sserno > 1 || sserp == NULL);
14618 +
14619 +       ret = crisv32_pinmux_alloc_fixed(sserno == 0
14620 +                                        ? pinmux_sser0 : pinmux_sser1);
14621 +       if (ret != 0)
14622 +               return ret;
14623 +
14624 +       sserp->regi = regi_sser;
14625 +       sserp->irq = sser_irq;
14626 +
14627 +       if (dmaoutp) {
14628 +               crisv32_request_dma(sserno == 0
14629 +                                   ? SYNC_SER0_TX_DMA_NBR
14630 +                                   : SYNC_SER1_TX_DMA_NBR,
14631 +                                   "SD/MMC SPI dma tr",
14632 +                                   DMA_VERBOSE_ON_ERROR | DMA_PANIC_ON_ERROR,
14633 +                                   /* Let's be brave and ask for the
14634 +                                      max.  Except it's simplex, so
14635 +                                      let's request half the max
14636 +                                      speed in either direction.  */
14637 +                                   50 * 1000 * 1000 / 8 / 2,
14638 +                                   sserno == 0 ? dma_sser0 : dma_sser1);
14639 +               dmaoutp->regi = sserno == 0
14640 +                       ? CONCAT(regi_dma, SYNC_SER0_TX_DMA_NBR)
14641 +                       : CONCAT(regi_dma, SYNC_SER1_TX_DMA_NBR);
14642 +               dmaoutp->irq = sserno == 0
14643 +                       ? CONCAT3(DMA, SYNC_SER0_TX_DMA_NBR, _INTR_VECT)
14644 +                       : CONCAT3(DMA, SYNC_SER1_TX_DMA_NBR, _INTR_VECT);
14645 +       }
14646 +
14647 +       if (dmainp) {
14648 +               crisv32_request_dma(sserno == 0
14649 +                                   ? SYNC_SER0_RX_DMA_NBR
14650 +                                   : SYNC_SER1_RX_DMA_NBR,
14651 +                                   "SD/MMC SPI dma rec",
14652 +                                   DMA_VERBOSE_ON_ERROR | DMA_PANIC_ON_ERROR,
14653 +                                   50 * 1000 * 1000 / 8 / 2,
14654 +                                   sserno == 0 ? dma_sser0 : dma_sser1);
14655 +               dmainp->regi = sserno == 0
14656 +                       ? CONCAT(regi_dma, SYNC_SER0_RX_DMA_NBR)
14657 +                       : CONCAT(regi_dma, SYNC_SER1_RX_DMA_NBR);
14658 +               dmainp->irq = sserno == 0
14659 +                       ? CONCAT3(DMA, SYNC_SER0_RX_DMA_NBR, _INTR_VECT)
14660 +                       : CONCAT3(DMA, SYNC_SER1_RX_DMA_NBR, _INTR_VECT);
14661 +       }
14662 +
14663 +       return 0;
14664 +}
14665 +
14666 +/* Undo whatever allocations et. al. that crisv32_allocate_sser did.  */
14667 +
14668 +static void crisv32_free_sser(u32 sserno, int with_dma)
14669 +{
14670 +       int ret;
14671 +
14672 +       if (with_dma) {
14673 +               crisv32_free_dma(sserno == 0
14674 +                                ? SYNC_SER0_RX_DMA_NBR
14675 +                                : SYNC_SER1_RX_DMA_NBR);
14676 +               crisv32_free_dma(sserno == 0
14677 +                                ? SYNC_SER0_TX_DMA_NBR
14678 +                                : SYNC_SER1_TX_DMA_NBR);
14679 +       }
14680 +
14681 +       ret = crisv32_pinmux_dealloc_fixed(sserno == 0
14682 +                                          ? pinmux_sser0 : pinmux_sser1);
14683 +
14684 +       if (ret != 0)
14685 +               panic("%s: crisv32_pinmux_dealloc_fixed returned %d\n",
14686 +                      __FUNCTION__, ret);
14687 +}
14688 +
14689 +/* Convenience-macro to avoid typos causing diffs between sser ports.  */
14690 +
14691 +#define SSER_CDATA(n)                                                  \
14692 +       {                                                               \
14693 +               {                                                       \
14694 +                       .using_dma = WITH_ETRAX_SPI_SSER##n##_DMA,      \
14695 +                       .iface_allocate = crisv32_allocate_sser##n,     \
14696 +                       .iface_free = crisv32_free_sser##n              \
14697 +               },                                                      \
14698 +               {                                                       \
14699 +                       .card_detect                                    \
14700 +                               = CONFIG_ETRAX_SPI_MMC_CD_SSER##n##_PIN,\
14701 +                       .write_protect                                  \
14702 +                               = CONFIG_ETRAX_SPI_MMC_WP_SSER##n##_PIN,\
14703 +                       .pinstate                                       \
14704 +                               = &crisv32_mmcspi_sser##n##_pinstate    \
14705 +               }                                                       \
14706 +       }
14707 +
14708 +#ifdef CONFIG_ETRAX_SPI_SSER0
14709 +
14710 +/* Allocate hardware to go with sser0 and fill in the right numbers.  */
14711 +
14712 +static int crisv32_allocate_sser0(struct crisv32_regi_n_int *sserp,
14713 +                                 struct crisv32_regi_n_int *dmainp,
14714 +                                 struct crisv32_regi_n_int *dmaoutp)
14715 +{
14716 +       return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 0);
14717 +}
14718 +
14719 +/* Undo those allocations.  */
14720 +
14721 +static void crisv32_free_sser0(void)
14722 +{
14723 +       crisv32_free_sser(0, WITH_ETRAX_SPI_SSER0_DMA);
14724 +}
14725 +
14726 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser0_pinstate;
14727 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser0_cdata
14728 + = SSER_CDATA(0);
14729 +#endif /* CONFIG_ETRAX_SPI_SSER0 */
14730 +
14731 +#ifdef CONFIG_ETRAX_SPI_SSER1
14732 +
14733 +/* Allocate hardware to go with sser0 and fill in the right numbers.  */
14734 +
14735 +static int crisv32_allocate_sser1(struct crisv32_regi_n_int *sserp,
14736 +                                 struct crisv32_regi_n_int *dmainp,
14737 +                                 struct crisv32_regi_n_int *dmaoutp)
14738 +{
14739 +       return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 1);
14740 +}
14741 +
14742 +/* Undo those allocations.  */
14743 +
14744 +static void crisv32_free_sser1(void)
14745 +{
14746 +       crisv32_free_sser(1, WITH_ETRAX_SPI_SSER1_DMA);
14747 +}
14748 +
14749 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser1_pinstate;
14750 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser1_cdata
14751 + = SSER_CDATA(1);
14752 +
14753 +#endif /* CONFIG_ETRAX_SPI_SSER1 */
14754 +
14755 +static struct mmc_spi_platform_data crisv32_mmcspi_sser_pdata = {
14756 +       .init = crisv32_mmcspi_sser_init,
14757 +       .exit = __devexit_p(crisv32_mmcspi_sser_exit),
14758 +       .detect_delay = 0,
14759 +       .get_ro = crisv32_mmcspi_sser_get_ro,
14760 +       .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
14761 +       .setpower = NULL
14762 +};
14763 +
14764 +#endif /* CONFIG_SPI_ETRAX_SSER */
14765 +
14766 +#ifdef CONFIG_SPI_ETRAX_GPIO
14767 +
14768 +static const char crisv32_matching_spi_gpio_driver_name[] __init_or_module
14769 + = "spi_crisv32_gpio";
14770 +
14771 +/* Write-protect sense for the GPIO interface.  */
14772 +
14773 +static int crisv32_mmcspi_gpio_get_ro(struct device *dev)
14774 +{
14775 +       struct spi_device *spidev = to_spi_device(dev);
14776 +       struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14777 +               = spidev->controller_data;
14778 +       struct crisv32_mmc_spi_pindata *pd = &gpio_defs->mmc;
14779 +
14780 +       return crisv32_mmcspi_get_ro_helper(pd->pinstate);
14781 +}
14782 +
14783 +/* Initialize the MMC-specific parts of the MMC+SPI interface, GPIO.  */
14784 +
14785 +static int crisv32_mmcspi_gpio_init(struct device *dev,
14786 +                                   irqreturn_t (*intfunc)(int, void *),
14787 +                                   void *xmmc_host)
14788 +{
14789 +       struct mmc_host *mmc_host = xmmc_host;
14790 +       struct spi_device *spidev = to_spi_device(dev);
14791 +       struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14792 +               = spidev->controller_data;
14793 +       int ret = crisv32_mmcspi_config_common(spidev, intfunc, mmc_host,
14794 +                                              &gpio_defs->mmc);
14795 +       if (ret)
14796 +               return ret;
14797 +
14798 +       mmc_host->f_max = spidev->max_speed_hz;
14799 +
14800 +       /*
14801 +        * We don't set f_min, as the mmc code doesn't treat it as a
14802 +        * limit, but as the frequency to use at initialization.  We
14803 +        * stick with what mmc_spi sets.
14804 +        */
14805 +       dev_info(dev, "CRIS v32 mmc_spi support hooked to SPI on GPIO"
14806 +                " (bus #%d, cd: %s, wp: %s)\n",
14807 +                spidev->master->bus_num,
14808 +                CONFIGURED_PIN(gpio_defs->mmc.card_detect)
14809 +                ? gpio_defs->mmc.card_detect : "(none)",
14810 +                CONFIGURED_PIN(gpio_defs->mmc.write_protect)
14811 +                ? gpio_defs->mmc.write_protect : "(none)");
14812 +       return 0;
14813 +}
14814 +
14815 +/* Similarly, to undo crisv32_mmcspi_gpio_init.  */
14816 +
14817 +static void crisv32_mmcspi_gpio_exit(struct device *dev, void *xmmc_host)
14818 +{
14819 +       struct spi_device *spidev = to_spi_device(dev);
14820 +       struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14821 +               = spidev->controller_data;
14822 +
14823 +       crisv32_mmcspi_deconfig_common(&gpio_defs->mmc);
14824 +}
14825 +
14826 +static const struct mmc_spi_platform_data crisv32_mmcspi_gpio_pdata = {
14827 +       .init = crisv32_mmcspi_gpio_init,
14828 +       .exit = __devexit_p(crisv32_mmcspi_gpio_exit),
14829 +       .detect_delay = 0,
14830 +       .get_ro = crisv32_mmcspi_gpio_get_ro,
14831 +       .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
14832 +       .setpower = NULL
14833 +};
14834 +
14835 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_gpio_pinstate;
14836 +static const struct crisv32_mmc_spi_gpio_hwdata crisv32_mmcspi_gpio_cdata = {
14837 +       {
14838 +               .cs     = CONFIG_ETRAX_SPI_CS_PIN,
14839 +               .miso   = CONFIG_ETRAX_SPI_DATAIN_PIN,
14840 +               .mosi   = CONFIG_ETRAX_SPI_DATAOUT_PIN,
14841 +               .sclk   = CONFIG_ETRAX_SPI_CLK_PIN
14842 +       },
14843 +       {
14844 +               .card_detect    = CONFIG_ETRAX_SPI_MMC_CD_GPIO_PIN,
14845 +               .write_protect  = CONFIG_ETRAX_SPI_MMC_WP_GPIO_PIN,
14846 +               .pinstate       = &crisv32_mmcspi_gpio_pinstate
14847 +       }
14848 +};
14849 +#endif /* CONFIG_SPI_ETRAX_GPIO */
14850 +
14851 +struct crisv32_s_b_i_and_driver_info {
14852 +       struct spi_board_info sbi;
14853 +       const char *driver_name;
14854 +
14855 +       /*
14856 +        * We have to adjust the platform device at time of creation
14857 +        * below, to allow the Linux DMA framework to handle DMA.  In
14858 +        * the name of simplicity, we state the dma:able property
14859 +        * twice, a bit redundantly; here and in the controller_data
14860 +        * structure pointed to by spi_board_info.
14861 +        */
14862 +       int dma_able;
14863 +};
14864 +
14865 +/* Convenience-macro to avoid typos causing diffs between sser ports.  */
14866 +
14867 +#define SSER_CONFIG(n)                                                 \
14868 +       {                                                               \
14869 +               /*                                                      \
14870 +                * No meaningful values for .irq or .chip_select,       \
14871 +                * so we leave them out.                                \
14872 +                */                                                     \
14873 +               {                                                       \
14874 +                       .modalias               = "mmc_spi",            \
14875 +                       .platform_data                                  \
14876 +                                = &crisv32_mmcspi_sser_pdata,          \
14877 +                       /*                                              \
14878 +                        * Casting to avoid a compiler const-warning.   \
14879 +                        */                                             \
14880 +                       .controller_data                                \
14881 +                               = ((void *)                             \
14882 +                                  &crisv32_mmcspi_sser##n##_cdata),    \
14883 +                       .max_speed_hz           = 50 * 1000 * 1000,     \
14884 +                       .bus_num                = n,                    \
14885 +                       /*                                              \
14886 +                        * We only provide one mode, so it must be      \
14887 +                        * default.                                     \
14888 +                        */                                             \
14889 +                       .mode                   = SPI_MODE_3            \
14890 +               },                                                      \
14891 +               crisv32_matching_spi_sser_driver_name,                  \
14892 +               WITH_ETRAX_SPI_SSER##n##_DMA                            \
14893 +       }
14894 +
14895 +static const struct crisv32_s_b_i_and_driver_info
14896 +crisv32_mmcspi_devices[] __initdata = {
14897 +#ifdef CONFIG_ETRAX_SPI_SSER0
14898 +       SSER_CONFIG(0),
14899 +#endif
14900 +#ifdef CONFIG_ETRAX_SPI_SSER1
14901 +       SSER_CONFIG(1),
14902 +#endif
14903 +#ifdef CONFIG_SPI_ETRAX_GPIO
14904 +       {
14905 +               {
14906 +                       .modalias               = "mmc_spi",
14907 +                       .platform_data          = &crisv32_mmcspi_gpio_pdata,
14908 +                       /* Casting to avoid a compiler const-warning.  */
14909 +                       .controller_data
14910 +                               = (void *) &crisv32_mmcspi_gpio_cdata,
14911 +
14912 +                       /* No, we can't even reach this number with GPIO.  */
14913 +                       .max_speed_hz           = 5 * 1000 * 1000,
14914 +                       .bus_num                = 2
14915 +               },
14916 +               crisv32_matching_spi_gpio_driver_name,
14917 +               0
14918 +       },
14919 +#endif
14920 +};
14921 +
14922 +/* Must not be __initdata.  */
14923 +static const char controller_data_ptr_name[] = "controller_data_ptr";
14924 +static u64 allmem_mask = ~(u32) 0;
14925 +
14926 +/*
14927 + * We have to register the SSER and GPIO "platform_device"s separately
14928 + * from the "spi_board_info"s in order to have the drivers separated
14929 + * from the hardware instance info.
14930 + */
14931 +
14932 +static int __init crisv32_register_mmcspi(void)
14933 +{
14934 +       int ret;
14935 +       void *retp;
14936 +       const struct crisv32_s_b_i_and_driver_info *sbip;
14937 +
14938 +       for (sbip = crisv32_mmcspi_devices;
14939 +            sbip < crisv32_mmcspi_devices
14940 +                    + ARRAY_SIZE(crisv32_mmcspi_devices);
14941 +            sbip++) {
14942 +
14943 +               /*
14944 +                * We have to pass the controller data as a device
14945 +                * "resource" (FIXME: too?), so it can be available
14946 +                * for the setup *before* starting the SPI core -
14947 +                * which is where .controller_data makes it to the SPI
14948 +                * structure!
14949 +                */
14950 +               struct resource mmcspi_res = {
14951 +                       .start = (resource_size_t) sbip->sbi.controller_data,
14952 +                       .end = (resource_size_t) sbip->sbi.controller_data,
14953 +                       .name = controller_data_ptr_name
14954 +               };
14955 +
14956 +               /*
14957 +                * Presumably we could pass the irqs and register
14958 +                * addresses and... as individual resources here
14959 +                * instead of privately in spi_board_info
14960 +                * .controller_data, and make that part a bit more
14961 +                * readable.  Maybe not worthwhile.
14962 +                */
14963 +               /* Need to cast away const here.  FIXME: fix the pdrs API.  */
14964 +               retp = platform_device_alloc(sbip->driver_name,
14965 +                                            sbip->sbi.bus_num);
14966 +               if (IS_ERR_VALUE(PTR_ERR(retp)))
14967 +                       return PTR_ERR(retp);
14968 +
14969 +               /*
14970 +                * We can't use platform_device_register_simple as we
14971 +                * want to set stuff in the device to mark that we'd
14972 +                * prefer buffers explicitly passed as DMA-able.
14973 +                * Disabling/omitting the "if" below, cause testing of
14974 +                * the non-DMA-mem execution path of a DMA-capable
14975 +                * driver.
14976 +                */
14977 +               if (sbip->dma_able) {
14978 +                       struct platform_device *pdev = retp;
14979 +
14980 +                       pdev->dev.dma_mask = &allmem_mask;
14981 +                       pdev->dev.coherent_dma_mask = allmem_mask;
14982 +               }
14983 +
14984 +               if ((ret = platform_device_add_resources(retp, &mmcspi_res, 1)) != 0
14985 +                   || (ret = platform_device_add(retp)) != 0) {
14986 +                       platform_device_put(retp);
14987 +                       return ret;
14988 +               }
14989 +
14990 +               /*
14991 +                * The cost of keeping all info rooted at
14992 +                * crisv32_mmcspi_devices is the allocation overhead
14993 +                * for allocating separately each board info (in the
14994 +                * unlikely event that there's more than one).
14995 +                */
14996 +               ret = spi_register_board_info(&sbip->sbi, 1);
14997 +               if (ret != 0)
14998 +                       return ret;
14999 +       }
15000 +
15001 +       return 0;
15002 +}
15003 +#ifdef MODULE
15004 +#error "Non-module because spi_register_board_info is one-way; there's no unregister function"
15005 +#endif
15006 +
15007 +/*
15008 + * Needs to be called before __initcall/module_init because the SPI
15009 + * bus scanning happens when the actual driver registers with the SPI
15010 + * machinery (spi_bitbang_start/spi_register_master), not when the
15011 + * device registers (spi_register_board_info).
15012 + */
15013 +subsys_initcall(crisv32_register_mmcspi);
15014 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/cryptocop.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/cryptocop.c
15015 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/cryptocop.c   2007-01-10 20:10:37.000000000 +0100
15016 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/cryptocop.c   2007-01-09 10:29:20.000000000 +0100
15017 @@ -1,4 +1,4 @@
15018 -/* $Id: cryptocop.c,v 1.13 2005/04/21 17:27:55 henriken Exp $
15019 +/* $Id: cryptocop.c,v 1.22 2007/01/09 09:29:20 starvik Exp $
15020   *
15021   * Stream co-processor driver for the ETRAX FS
15022   *
15023 @@ -1718,7 +1718,7 @@
15024   *   i = i + 1
15025   * }
15026   * i = Nk
15027 - *
15028 + * 
15029   * while (i < (Nb * (Nr + 1))) {
15030   *   temp = w[i - 1]
15031   *   if ((i mod Nk) == 0) {
15032 @@ -1886,7 +1886,7 @@
15033  }
15034  
15035  static irqreturn_t
15036 -dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs)
15037 +dma_done_interrupt(int irq, void *dev_id)
15038  {
15039         struct cryptocop_prio_job *done_job;
15040         reg_dma_rw_ack_intr ack_intr = {
15041 @@ -2226,6 +2226,7 @@
15042                      &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out)));
15043  
15044         /* Start input DMA. */
15045 +       flush_dma_context(&pj->iop->ctx_in);
15046         DMA_START_CONTEXT(regi_dma9, virt_to_phys(&pj->iop->ctx_in));
15047  
15048         /* Start output DMA. */
15049 @@ -3459,7 +3460,7 @@
15050         int err;
15051         int i;
15052         static int initialized = 0;
15053 -
15054 +        
15055         if (initialized)
15056                 return 0;
15057  
15058 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/gpio.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/gpio.c
15059 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/gpio.c        2007-01-10 20:10:37.000000000 +0100
15060 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/gpio.c        2007-01-09 10:29:20.000000000 +0100
15061 @@ -1,68 +1,15 @@
15062 -/* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $
15063 - *
15064 +/*
15065   * ETRAX CRISv32 general port I/O device
15066   *
15067 - * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
15068 + * Copyright (c) 1999-2006 Axis Communications AB
15069   *
15070   * Authors:    Bjorn Wesen      (initial version)
15071   *             Ola Knutsson     (LED handling)
15072   *             Johan Adolfsson  (read/set directions, write, port G,
15073   *                               port to ETRAX FS.
15074   *
15075 - * $Log: gpio.c,v $
15076 - * Revision 1.16  2005/06/19 17:06:49  starvik
15077 - * Merge of Linux 2.6.12.
15078 - *
15079 - * Revision 1.15  2005/05/25 08:22:20  starvik
15080 - * Changed GPIO port order to fit packages/devices/axis-2.4.
15081 - *
15082 - * Revision 1.14  2005/04/24 18:35:08  starvik
15083 - * Updated with final register headers.
15084 - *
15085 - * Revision 1.13  2005/03/15 15:43:00  starvik
15086 - * dev_id needs to be supplied for shared IRQs.
15087 - *
15088 - * Revision 1.12  2005/03/10 17:12:00  starvik
15089 - * Protect alarm list with spinlock.
15090 - *
15091 - * Revision 1.11  2005/01/05 06:08:59  starvik
15092 - * No need to do local_irq_disable after local_irq_save.
15093 - *
15094 - * Revision 1.10  2004/11/19 08:38:31  starvik
15095 - * Removed old crap.
15096 - *
15097 - * Revision 1.9  2004/05/14 07:58:02  starvik
15098 - * Merge of changes from 2.4
15099 - *
15100 - * Revision 1.8  2003/09/11 07:29:50  starvik
15101 - * Merge of Linux 2.6.0-test5
15102 - *
15103 - * Revision 1.7  2003/07/10 13:25:46  starvik
15104 - * Compiles for 2.5.74
15105 - * Lindented ethernet.c
15106 - *
15107 - * Revision 1.6  2003/07/04 08:27:46  starvik
15108 - * Merge of Linux 2.5.74
15109 - *
15110 - * Revision 1.5  2003/06/10 08:26:37  johana
15111 - * Etrax -> ETRAX CRISv32
15112 - *
15113 - * Revision 1.4  2003/06/05 14:22:48  johana
15114 - * Initialise some_alarms.
15115 - *
15116 - * Revision 1.3  2003/06/05 10:15:46  johana
15117 - * New INTR_VECT macros.
15118 - * Enable interrupts in global config.
15119 - *
15120 - * Revision 1.2  2003/06/03 15:52:50  johana
15121 - * Initial CRIS v32 version.
15122 - *
15123 - * Revision 1.1  2003/06/03 08:53:15  johana
15124 - * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7.
15125 - *
15126   */
15127  
15128 -
15129  #include <linux/module.h>
15130  #include <linux/sched.h>
15131  #include <linux/slab.h>
15132 @@ -85,6 +32,13 @@
15133  #include <asm/system.h>
15134  #include <asm/irq.h>
15135  
15136 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15137 +#include "i2c.h"
15138 +
15139 +#define VIRT_I2C_ADDR 0x40
15140 +#endif
15141 +
15142 +
15143  /* The following gio ports on ETRAX FS is available:
15144   * pa  8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
15145   * pb 18 bits
15146 @@ -111,6 +65,10 @@
15147  static wait_queue_head_t *gpio_wq;
15148  #endif
15149  
15150 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15151 +static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
15152 +                              unsigned long arg);
15153 +#endif
15154  static int gpio_ioctl(struct inode *inode, struct file *file,
15155                       unsigned int cmd, unsigned long arg);
15156  static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
15157 @@ -148,55 +106,75 @@
15158  #define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
15159  #define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
15160  unsigned long led_dummy;
15161 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15162 +static unsigned long virtual_dummy;
15163 +static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
15164 +static unsigned short cached_virtual_gpio_read = 0;
15165 +#endif
15166  
15167 -static volatile unsigned long *data_out[NUM_PORTS] = {
15168 -       GIO_REG_WR_ADDR(rw_pa_dout),
15169 -       GIO_REG_WR_ADDR(rw_pb_dout),
15170 +static volatile unsigned long *data_out[NUM_PORTS] = { 
15171 +       GIO_REG_WR_ADDR(rw_pa_dout), 
15172 +       GIO_REG_WR_ADDR(rw_pb_dout), 
15173         &led_dummy,
15174 -       GIO_REG_WR_ADDR(rw_pc_dout),
15175 -       GIO_REG_WR_ADDR(rw_pd_dout),
15176 +       GIO_REG_WR_ADDR(rw_pc_dout), 
15177 +       GIO_REG_WR_ADDR(rw_pd_dout), 
15178         GIO_REG_WR_ADDR(rw_pe_dout),
15179 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15180 +       &virtual_dummy,
15181 +#endif
15182  };
15183  
15184 -static volatile unsigned long *data_in[NUM_PORTS] = {
15185 -       GIO_REG_RD_ADDR(r_pa_din),
15186 -       GIO_REG_RD_ADDR(r_pb_din),
15187 +static volatile unsigned long *data_in[NUM_PORTS] = { 
15188 +       GIO_REG_RD_ADDR(r_pa_din), 
15189 +       GIO_REG_RD_ADDR(r_pb_din), 
15190         &led_dummy,
15191 -       GIO_REG_RD_ADDR(r_pc_din),
15192 -       GIO_REG_RD_ADDR(r_pd_din),
15193 +       GIO_REG_RD_ADDR(r_pc_din), 
15194 +       GIO_REG_RD_ADDR(r_pd_din), 
15195         GIO_REG_RD_ADDR(r_pe_din),
15196 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15197 +       &virtual_dummy,
15198 +#endif
15199  };
15200  
15201 -static unsigned long changeable_dir[NUM_PORTS] = {
15202 +static unsigned long changeable_dir[NUM_PORTS] = { 
15203         CONFIG_ETRAX_PA_CHANGEABLE_DIR,
15204         CONFIG_ETRAX_PB_CHANGEABLE_DIR,
15205         0,
15206         CONFIG_ETRAX_PC_CHANGEABLE_DIR,
15207 -       CONFIG_ETRAX_PD_CHANGEABLE_DIR,
15208 +       CONFIG_ETRAX_PD_CHANGEABLE_DIR, 
15209         CONFIG_ETRAX_PE_CHANGEABLE_DIR,
15210 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15211 +       CONFIG_ETRAX_PV_CHANGEABLE_DIR,
15212 +#endif
15213  };
15214  
15215 -static unsigned long changeable_bits[NUM_PORTS] = {
15216 +static unsigned long changeable_bits[NUM_PORTS] = { 
15217         CONFIG_ETRAX_PA_CHANGEABLE_BITS,
15218         CONFIG_ETRAX_PB_CHANGEABLE_BITS,
15219         0,
15220         CONFIG_ETRAX_PC_CHANGEABLE_BITS,
15221         CONFIG_ETRAX_PD_CHANGEABLE_BITS,
15222         CONFIG_ETRAX_PE_CHANGEABLE_BITS,
15223 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15224 +       CONFIG_ETRAX_PV_CHANGEABLE_BITS,
15225 +#endif
15226  };
15227  
15228 -static volatile unsigned long *dir_oe[NUM_PORTS] = {
15229 -       GIO_REG_WR_ADDR(rw_pa_oe),
15230 -       GIO_REG_WR_ADDR(rw_pb_oe),
15231 +static volatile unsigned long *dir_oe[NUM_PORTS] = { 
15232 +       GIO_REG_WR_ADDR(rw_pa_oe), 
15233 +       GIO_REG_WR_ADDR(rw_pb_oe), 
15234         &led_dummy,
15235 -       GIO_REG_WR_ADDR(rw_pc_oe),
15236 -       GIO_REG_WR_ADDR(rw_pd_oe),
15237 +       GIO_REG_WR_ADDR(rw_pc_oe), 
15238 +       GIO_REG_WR_ADDR(rw_pd_oe), 
15239         GIO_REG_WR_ADDR(rw_pe_oe),
15240 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15241 +       &virtual_rw_pv_oe,
15242 +#endif
15243  };
15244  
15245  
15246  
15247 -static unsigned int
15248 +static unsigned int 
15249  gpio_poll(struct file *file,
15250           poll_table *wait)
15251  {
15252 @@ -278,7 +256,7 @@
15253                 return 0;
15254  
15255         if ((data & priv->highalarm) ||
15256 -           (~data & priv->lowalarm)) {
15257 +            (~data & priv->lowalarm)) {
15258                 mask = POLLIN|POLLRDNORM;
15259         }
15260  
15261 @@ -288,11 +266,26 @@
15262  
15263  int etrax_gpio_wake_up_check(void)
15264  {
15265 -       struct gpio_private *priv = alarmlist;
15266 +       struct gpio_private *priv;
15267         unsigned long data = 0;
15268 +       unsigned long flags;
15269          int ret = 0;
15270 +       spin_lock_irqsave(&alarm_lock, flags);
15271 +       priv = alarmlist;
15272         while (priv) {
15273 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15274 +               if (priv->minor == GPIO_MINOR_V) {
15275 +                       data = (unsigned long)cached_virtual_gpio_read;
15276 +               }
15277 +               else {
15278 +                       data = *data_in[priv->minor];
15279 +                       if (priv->minor == GPIO_MINOR_A) {
15280 +                               priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15281 +                       }
15282 +               }
15283 +#else
15284                 data = *data_in[priv->minor];
15285 +#endif
15286                 if ((data & priv->highalarm) ||
15287                     (~data & priv->lowalarm)) {
15288                         DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
15289 @@ -301,11 +294,12 @@
15290                 }
15291                 priv = priv->next;
15292         }
15293 +       spin_unlock_irqrestore(&alarm_lock, flags);
15294          return ret;
15295  }
15296  
15297 -static irqreturn_t
15298 -gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15299 +static irqreturn_t 
15300 +gpio_poll_timer_interrupt(int irq, void *dev_id)
15301  {
15302         if (gpio_some_alarms) {
15303                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
15304 @@ -314,14 +308,17 @@
15305  }
15306  
15307  static irqreturn_t
15308 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15309 +gpio_pa_interrupt(int irq, void *dev_id)
15310  {
15311         reg_gio_rw_intr_mask intr_mask;
15312         reg_gio_r_masked_intr masked_intr;
15313         reg_gio_rw_ack_intr ack_intr;
15314         unsigned long tmp;
15315         unsigned long tmp2;
15316 -
15317 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15318 +       unsigned char enable_gpiov_ack = 0;
15319 +#endif
15320 +       
15321         /* Find what PA interrupts are active */
15322         masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
15323         tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
15324 @@ -331,6 +328,17 @@
15325         tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
15326         spin_unlock(&alarm_lock);
15327  
15328 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15329 +       /* Something changed on virtual GPIO. Interrupt is acked by
15330 +        * reading the device.
15331 +        */
15332 +       if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
15333 +               i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
15334 +                         sizeof(cached_virtual_gpio_read));
15335 +               enable_gpiov_ack = 1;
15336 +       }
15337 +#endif
15338 +
15339         /* Ack them */
15340         ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
15341         REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
15342 @@ -339,13 +347,21 @@
15343         intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
15344         tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
15345         tmp2 &= ~tmp;
15346 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15347 +       /* Do not disable interrupt on virtual GPIO. Changes on virtual
15348 +        * pins are only noticed by an interrupt.
15349 +        */
15350 +       if (enable_gpiov_ack)   {
15351 +               tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15352 +       }
15353 +#endif
15354         intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
15355         REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
15356  
15357         if (gpio_some_alarms) {
15358                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
15359         }
15360 -        return IRQ_NONE;
15361 +       return IRQ_NONE;
15362  }
15363  
15364  
15365 @@ -358,8 +374,13 @@
15366         unsigned long shadow;
15367         volatile unsigned long *port;
15368         ssize_t retval = count;
15369 -       /* Only bits 0-7 may be used for write operations but allow all
15370 +       /* Only bits 0-7 may be used for write operations but allow all 
15371            devices except leds... */
15372 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15373 +       if (priv->minor == GPIO_MINOR_V) {
15374 +               return -EFAULT;
15375 +       }
15376 +#endif
15377         if (priv->minor == GPIO_MINOR_LEDS) {
15378                 return -EFAULT;
15379         }
15380 @@ -416,25 +437,24 @@
15381  
15382  static int
15383  gpio_open(struct inode *inode, struct file *filp)
15384 -{
15385 +{      
15386         struct gpio_private *priv;
15387         int p = iminor(inode);
15388  
15389         if (p > GPIO_MINOR_LAST)
15390                 return -EINVAL;
15391  
15392 -       priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
15393 +       priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
15394                                               GFP_KERNEL);
15395  
15396         if (!priv)
15397                 return -ENOMEM;
15398 +       memset(priv, 0, sizeof(*priv));
15399  
15400         priv->minor = p;
15401  
15402 -       /* initialize the io/alarm struct and link it into our alarmlist */
15403 +       /* initialize the io/alarm struct */
15404  
15405 -       priv->next = alarmlist;
15406 -       alarmlist = priv;
15407         priv->clk_mask = 0;
15408         priv->data_mask = 0;
15409         priv->highalarm = 0;
15410 @@ -443,20 +463,30 @@
15411  
15412         filp->private_data = (void *)priv;
15413  
15414 +       /* link it into our alarmlist */
15415 +       spin_lock_irq(&alarm_lock);
15416 +       priv->next = alarmlist;
15417 +       alarmlist = priv;
15418 +       spin_unlock_irq(&alarm_lock);
15419 +
15420         return 0;
15421  }
15422  
15423  static int
15424  gpio_release(struct inode *inode, struct file *filp)
15425  {
15426 -       struct gpio_private *p = alarmlist;
15427 -       struct gpio_private *todel = (struct gpio_private *)filp->private_data;
15428 +       struct gpio_private *p;
15429 +       struct gpio_private *todel;
15430         /* local copies while updating them: */
15431         unsigned long a_high, a_low;
15432         unsigned long some_alarms;
15433  
15434         /* unlink from alarmlist and free the private structure */
15435  
15436 +       spin_lock_irq(&alarm_lock);
15437 +       p = alarmlist;
15438 +       todel = (struct gpio_private *)filp->private_data;
15439 +
15440         if (p == todel) {
15441                 alarmlist = todel->next;
15442         } else {
15443 @@ -473,6 +503,9 @@
15444         a_low = 0;
15445         while (p) {
15446                 if (p->minor == GPIO_MINOR_A) {
15447 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15448 +                       p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15449 +#endif
15450                         a_high |= p->highalarm;
15451                         a_low |= p->lowalarm;
15452                 }
15453 @@ -483,23 +516,30 @@
15454                 p = p->next;
15455         }
15456  
15457 -       spin_lock(&alarm_lock);
15458 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15459 +       /* Variables 'some_alarms' and 'a_low' needs to be set here again
15460 +        * to ensure that interrupt for virtual GPIO is handled.
15461 +        */
15462 +       some_alarms = 1;
15463 +       a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15464 +#endif
15465 +
15466         gpio_some_alarms = some_alarms;
15467         gpio_pa_high_alarms = a_high;
15468         gpio_pa_low_alarms = a_low;
15469 -       spin_unlock(&alarm_lock);
15470 +       spin_unlock_irq(&alarm_lock);
15471  
15472         return 0;
15473  }
15474  
15475 -/* Main device API. ioctl's to read/set/clear bits, as well as to
15476 +/* Main device API. ioctl's to read/set/clear bits, as well as to 
15477   * set alarms to wait for using a subsequent select().
15478   */
15479  
15480  unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
15481  {
15482 -       /* Set direction 0=unchanged 1=input,
15483 -        * return mask with 1=input
15484 +       /* Set direction 0=unchanged 1=input, 
15485 +        * return mask with 1=input 
15486          */
15487         unsigned long flags;
15488         unsigned long dir_shadow;
15489 @@ -512,6 +552,10 @@
15490  
15491         if (priv->minor == GPIO_MINOR_A)
15492                 dir_shadow ^= 0xFF;    /* Only 8 bits */
15493 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15494 +       else if (priv->minor == GPIO_MINOR_V)
15495 +               dir_shadow ^= 0xFFFF;  /* Only 16 bits */
15496 +#endif
15497         else
15498                 dir_shadow ^= 0x3FFFF; /* Only 18 bits */
15499         return dir_shadow;
15500 @@ -546,6 +590,11 @@
15501                 return -EINVAL;
15502         }
15503  
15504 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15505 +       if (priv->minor == GPIO_MINOR_V)
15506 +               return virtual_gpio_ioctl(file, cmd, arg);
15507 +#endif
15508 +
15509         switch (_IOC_NR(cmd)) {
15510         case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
15511                 // read the port
15512 @@ -553,8 +602,6 @@
15513                 break;
15514         case IO_SETBITS:
15515                 local_irq_save(flags);
15516 -                if (arg & 0x04)
15517 -                  printk("GPIO SET 2\n");
15518                 // set changeable bits with a 1 in arg
15519                 shadow = *data_out[priv->minor];
15520                 shadow |=  (arg & changeable_bits[priv->minor]);
15521 @@ -563,8 +610,6 @@
15522                 break;
15523         case IO_CLRBITS:
15524                 local_irq_save(flags);
15525 -                if (arg & 0x04)
15526 -                  printk("GPIO CLR 2\n");
15527                 // clear changeable bits with a 1 in arg
15528                 shadow = *data_out[priv->minor];
15529                 shadow &=  ~(arg & changeable_bits[priv->minor]);
15530 @@ -574,52 +619,52 @@
15531         case IO_HIGHALARM:
15532                 // set alarm when bits with 1 in arg go high
15533                 priv->highalarm |= arg;
15534 -               spin_lock(&alarm_lock);
15535 +               spin_lock_irqsave(&alarm_lock, flags);
15536                 gpio_some_alarms = 1;
15537                 if (priv->minor == GPIO_MINOR_A) {
15538                         gpio_pa_high_alarms |= arg;
15539                 }
15540 -               spin_unlock(&alarm_lock);
15541 +               spin_unlock_irqrestore(&alarm_lock, flags);
15542                 break;
15543         case IO_LOWALARM:
15544                 // set alarm when bits with 1 in arg go low
15545                 priv->lowalarm |= arg;
15546 -               spin_lock(&alarm_lock);
15547 +               spin_lock_irqsave(&alarm_lock, flags);
15548                 gpio_some_alarms = 1;
15549                 if (priv->minor == GPIO_MINOR_A) {
15550                         gpio_pa_low_alarms |= arg;
15551                 }
15552 -               spin_unlock(&alarm_lock);
15553 +               spin_unlock_irqrestore(&alarm_lock, flags);
15554                 break;
15555         case IO_CLRALARM:
15556                 // clear alarm for bits with 1 in arg
15557                 priv->highalarm &= ~arg;
15558                 priv->lowalarm  &= ~arg;
15559 -               spin_lock(&alarm_lock);
15560 +               spin_lock_irqsave(&alarm_lock, flags);
15561                 if (priv->minor == GPIO_MINOR_A) {
15562 -                       if (gpio_pa_high_alarms & arg ||
15563 +                       if (gpio_pa_high_alarms & arg || 
15564                             gpio_pa_low_alarms & arg) {
15565                                 /* Must update the gpio_pa_*alarms masks */
15566                         }
15567                 }
15568 -               spin_unlock(&alarm_lock);
15569 +               spin_unlock_irqrestore(&alarm_lock, flags);
15570                 break;
15571         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
15572                 /* Read direction 0=input 1=output */
15573                 return *dir_oe[priv->minor];
15574         case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
15575 -               /* Set direction 0=unchanged 1=input,
15576 -                * return mask with 1=input
15577 +               /* Set direction 0=unchanged 1=input, 
15578 +                * return mask with 1=input 
15579                  */
15580                 return setget_input(priv, arg);
15581                 break;
15582         case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
15583 -               /* Set direction 0=unchanged 1=output,
15584 -                * return mask with 1=output
15585 +               /* Set direction 0=unchanged 1=output, 
15586 +                * return mask with 1=output 
15587                  */
15588                 return setget_output(priv, arg);
15589  
15590 -       case IO_CFG_WRITE_MODE:
15591 +       case IO_CFG_WRITE_MODE: 
15592         {
15593                 unsigned long dir_shadow;
15594                 dir_shadow = *dir_oe[priv->minor];
15595 @@ -641,7 +686,7 @@
15596                 }
15597                 break;
15598         }
15599 -       case IO_READ_INBITS:
15600 +       case IO_READ_INBITS: 
15601                 /* *arg is result of reading the input pins */
15602                 val = *data_in[priv->minor];
15603                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15604 @@ -654,7 +699,7 @@
15605                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15606                         return -EFAULT;
15607                 break;
15608 -       case IO_SETGET_INPUT:
15609 +       case IO_SETGET_INPUT: 
15610                 /* bits set in *arg is set to input,
15611                  * *arg updated with current input pins.
15612                  */
15613 @@ -684,6 +729,132 @@
15614         return 0;
15615  }
15616  
15617 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15618 +static int
15619 +virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
15620 +{
15621 +       unsigned long flags;
15622 +       unsigned short val;
15623 +       unsigned short shadow;
15624 +       struct gpio_private *priv = (struct gpio_private *)file->private_data;
15625 +
15626 +       switch (_IOC_NR(cmd)) {
15627 +       case IO_SETBITS:
15628 +               local_irq_save(flags);
15629 +               // set changeable bits with a 1 in arg
15630 +               i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15631 +               shadow |= ~*dir_oe[priv->minor];
15632 +               shadow |= (arg & changeable_bits[priv->minor]);
15633 +               i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15634 +               local_irq_restore(flags);
15635 +               break;
15636 +       case IO_CLRBITS:
15637 +               local_irq_save(flags);
15638 +               // clear changeable bits with a 1 in arg
15639 +               i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15640 +               shadow |= ~*dir_oe[priv->minor];
15641 +               shadow &= ~(arg & changeable_bits[priv->minor]);
15642 +               i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15643 +               local_irq_restore(flags);
15644 +               break;
15645 +       case IO_HIGHALARM:
15646 +               // set alarm when bits with 1 in arg go high
15647 +               priv->highalarm |= arg;
15648 +               spin_lock(&alarm_lock);
15649 +               gpio_some_alarms = 1;
15650 +               spin_unlock(&alarm_lock);
15651 +               break;
15652 +       case IO_LOWALARM:
15653 +               // set alarm when bits with 1 in arg go low
15654 +               priv->lowalarm |= arg;
15655 +               spin_lock(&alarm_lock);
15656 +               gpio_some_alarms = 1;
15657 +               spin_unlock(&alarm_lock);
15658 +               break;
15659 +       case IO_CLRALARM:
15660 +               // clear alarm for bits with 1 in arg
15661 +               priv->highalarm &= ~arg;
15662 +               priv->lowalarm  &= ~arg;
15663 +               spin_lock(&alarm_lock);
15664 +               spin_unlock(&alarm_lock);
15665 +               break;
15666 +       case IO_CFG_WRITE_MODE: 
15667 +       {
15668 +               unsigned long dir_shadow;
15669 +               dir_shadow = *dir_oe[priv->minor];
15670 +               
15671 +               priv->clk_mask = arg & 0xFF;
15672 +               priv->data_mask = (arg >> 8) & 0xFF;
15673 +               priv->write_msb = (arg >> 16) & 0x01;
15674 +               /* Check if we're allowed to change the bits and
15675 +                * the direction is correct
15676 +                */
15677 +               if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
15678 +                     (priv->data_mask & changeable_bits[priv->minor]) &&
15679 +                     (priv->clk_mask & dir_shadow) &&
15680 +                     (priv->data_mask & dir_shadow)))
15681 +               {
15682 +                       priv->clk_mask = 0;
15683 +                       priv->data_mask = 0;
15684 +                       return -EPERM;
15685 +               }
15686 +               break;
15687 +       }
15688 +       case IO_READ_INBITS: 
15689 +               /* *arg is result of reading the input pins */
15690 +               val = cached_virtual_gpio_read;
15691 +               val &= ~*dir_oe[priv->minor];
15692 +               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15693 +                       return -EFAULT;
15694 +               return 0;
15695 +               break;
15696 +       case IO_READ_OUTBITS:
15697 +                /* *arg is result of reading the output shadow */
15698 +               i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
15699 +               val &= *dir_oe[priv->minor];
15700 +               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15701 +                       return -EFAULT;
15702 +               break;
15703 +       case IO_SETGET_INPUT:
15704 +       {
15705 +               /* bits set in *arg is set to input,
15706 +                * *arg updated with current input pins.
15707 +                */
15708 +               unsigned short input_mask = ~*dir_oe[priv->minor];
15709 +               if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15710 +                       return -EFAULT;
15711 +               val = setget_input(priv, val);
15712 +               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15713 +                       return -EFAULT;
15714 +               if ((input_mask & val) != input_mask) {
15715 +                       /* Input pins changed. All ports desired as input
15716 +                        * should be set to logic 1.
15717 +                        */
15718 +                       unsigned short change = input_mask ^ val;
15719 +                       i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15720 +                       shadow &= ~change;
15721 +                       shadow |= val;
15722 +                       i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15723 +               }
15724 +               break;
15725 +       }
15726 +       case IO_SETGET_OUTPUT:
15727 +               /* bits set in *arg is set to output,
15728 +                * *arg updated with current output pins.
15729 +                */
15730 +               if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15731 +                       return -EFAULT;
15732 +               val = setget_output(priv, val);
15733 +               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15734 +                       return -EFAULT;
15735 +               break;
15736 +       default:
15737 +               return -EINVAL;
15738 +       } /* switch */
15739 +  return 0;
15740 +}
15741 +#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
15742 +
15743  static int
15744  gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
15745  {
15746 @@ -714,6 +885,66 @@
15747         .release     = gpio_release,
15748  };
15749  
15750 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15751 +static void
15752 +virtual_gpio_init(void)
15753 +{
15754 +       reg_gio_rw_intr_cfg intr_cfg;
15755 +       reg_gio_rw_intr_mask intr_mask;
15756 +       unsigned short shadow;
15757 +
15758 +       shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
15759 +       shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
15760 +       i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15761 +
15762 +       /* Set interrupt mask and on what state the interrupt shall trigger.
15763 +        * For virtual gpio the interrupt shall trigger on logic '0'.
15764 +        */
15765 +       intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
15766 +       intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
15767 +
15768 +       switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
15769 +         case 0:
15770 +          intr_cfg.pa0 = regk_gio_lo;
15771 +          intr_mask.pa0 = regk_gio_yes;
15772 +          break;
15773 +         case 1:
15774 +          intr_cfg.pa1 = regk_gio_lo;
15775 +          intr_mask.pa1 = regk_gio_yes;
15776 +          break;
15777 +         case 2:
15778 +          intr_cfg.pa2 = regk_gio_lo;
15779 +          intr_mask.pa2 = regk_gio_yes;
15780 +          break;
15781 +         case 3:
15782 +          intr_cfg.pa3 = regk_gio_lo;
15783 +          intr_mask.pa3 = regk_gio_yes;
15784 +          break;
15785 +         case 4:
15786 +          intr_cfg.pa4 = regk_gio_lo;
15787 +          intr_mask.pa4 = regk_gio_yes;
15788 +          break;
15789 +         case 5:
15790 +          intr_cfg.pa5 = regk_gio_lo;
15791 +          intr_mask.pa5 = regk_gio_yes;
15792 +          break;
15793 +         case 6:
15794 +          intr_cfg.pa6 = regk_gio_lo;
15795 +          intr_mask.pa6 = regk_gio_yes;
15796 +          break;
15797 +         case 7:
15798 +          intr_cfg.pa7 = regk_gio_lo;
15799 +          intr_mask.pa7 = regk_gio_yes;
15800 +          break;
15801 +       }
15802 +
15803 +       REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
15804 +       REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
15805 +
15806 +       gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15807 +       gpio_some_alarms = 1;
15808 +}
15809 +#endif
15810  
15811  /* main driver initialization routine, called from mem.c */
15812  
15813 @@ -732,17 +963,18 @@
15814         }
15815  
15816         /* Clear all leds */
15817 -       LED_NETWORK_SET(0);
15818 +       LED_NETWORK_GRP0_SET(0);
15819 +       LED_NETWORK_GRP1_SET(0);
15820         LED_ACTIVE_SET(0);
15821         LED_DISK_READ(0);
15822         LED_DISK_WRITE(0);
15823  
15824 -       printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n");
15825 +       printk("ETRAX FS GPIO driver v2.5, (c) 2003-2006 Axis Communications AB\n");
15826         /* We call etrax_gpio_wake_up_check() from timer interrupt and
15827          * from cpu_idle() in kernel/process.c
15828          * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
15829          * in some tests.
15830 -        */
15831 +        */  
15832         if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt,
15833                         IRQF_SHARED | IRQF_DISABLED,"gpio poll", &alarmlist)) {
15834                 printk("err: timer0 irq for gpio\n");
15835 @@ -757,6 +989,10 @@
15836         intr_mask.gen_io = 1;
15837         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
15838  
15839 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15840 +       virtual_gpio_init();
15841 +#endif
15842 +
15843         return res;
15844  }
15845  
15846 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.c
15847 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.c 2007-01-10 20:10:37.000000000 +0100
15848 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.c 2006-11-06 16:48:06.000000000 +0100
15849 @@ -8,11 +8,11 @@
15850  *!
15851  *! Nov 30 1998  Torbjorn Eliasson  Initial version.
15852  *!              Bjorn Wesen        Elinux kernel version.
15853 -*! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff -
15854 +*! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff - 
15855  *!                                 don't use PB_I2C if DS1302 uses same bits,
15856  *!                                 use PB.
15857  *| June 23 2003 Pieter Grimmerink  Added 'i2c_sendnack'. i2c_readreg now
15858 -*|                                 generates nack on last received byte,
15859 +*|                                 generates nack on last received byte, 
15860  *|                                 instead of ack.
15861  *|                                 i2c_getack changed data level while clock
15862  *|                                 was high, causing DS75 to see  a stop condition
15863 @@ -22,7 +22,7 @@
15864  *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
15865  *!
15866  *!***************************************************************************/
15867 -/* $Id: i2c.c,v 1.2 2005/05/09 15:29:49 starvik Exp $ */
15868 +/* $Id: i2c.c,v 1.6 2006/11/06 15:48:06 imres Exp $ */
15869  /****************** INCLUDE FILES SECTION ***********************************/
15870  
15871  #include <linux/module.h>
15872 @@ -60,8 +60,8 @@
15873  #define I2C_DATA_HIGH 1
15874  #define I2C_DATA_LOW 0
15875  
15876 -#define i2c_enable()
15877 -#define i2c_disable()
15878 +#define i2c_enable() 
15879 +#define i2c_disable() 
15880  
15881  /* enable or disable output-enable, to select output or input on the i2c bus */
15882  
15883 @@ -79,6 +79,8 @@
15884  
15885  #define i2c_delay(usecs) udelay(usecs)
15886  
15887 +static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
15888 +
15889  /****************** VARIABLE SECTION ************************************/
15890  
15891  static struct crisv32_iopin cris_i2c_clk;
15892 @@ -154,7 +156,7 @@
15893                 } else {
15894                         i2c_data(I2C_DATA_LOW);
15895                 }
15896 -
15897 +               
15898                 i2c_delay(CLOCK_LOW_TIME/2);
15899                 i2c_clk(I2C_CLOCK_HIGH);
15900                 i2c_delay(CLOCK_HIGH_TIME);
15901 @@ -213,7 +215,7 @@
15902         }
15903         i2c_clk(I2C_CLOCK_HIGH);
15904         i2c_delay(CLOCK_HIGH_TIME);
15905 -
15906 +       
15907         /*
15908          * we leave the clock low, getbyte is usually followed
15909          * by sendack/nack, they assume the clock to be low
15910 @@ -252,6 +254,7 @@
15911          * generate ACK clock pulse
15912          */
15913         i2c_clk(I2C_CLOCK_HIGH);
15914 +#if 0
15915         /*
15916          * Use PORT PB instead of I2C
15917          * for input. (I2C not working)
15918 @@ -264,6 +267,8 @@
15919         i2c_data(1);
15920         i2c_disable();
15921         i2c_dir_in();
15922 +#endif
15923 +
15924         /*
15925          * now wait for ack
15926          */
15927 @@ -285,13 +290,15 @@
15928      * before we enable our output. If we keep data high
15929      * and enable output, we would generate a stop condition.
15930      */
15931 +#if 0
15932     i2c_data(I2C_DATA_LOW);
15933 -
15934 +   
15935         /*
15936          * end clock pulse
15937          */
15938         i2c_enable();
15939         i2c_dir_out();
15940 +#endif
15941         i2c_clk(I2C_CLOCK_LOW);
15942         i2c_delay(CLOCK_HIGH_TIME/4);
15943         /*
15944 @@ -338,7 +345,7 @@
15945          */
15946         i2c_data(I2C_DATA_HIGH);
15947         i2c_delay(CLOCK_LOW_TIME);
15948 -
15949 +       
15950         i2c_dir_in();
15951  }
15952  
15953 @@ -369,24 +376,160 @@
15954         i2c_delay(CLOCK_HIGH_TIME);
15955         i2c_clk(I2C_CLOCK_LOW);
15956         i2c_delay(CLOCK_LOW_TIME);
15957 -
15958 +       
15959         i2c_dir_in();
15960  }
15961  
15962  /*#---------------------------------------------------------------------------
15963  *#
15964 +*# FUNCTION NAME: i2c_write
15965 +*#
15966 +*# DESCRIPTION  : Writes a value to an I2C device
15967 +*#
15968 +*#--------------------------------------------------------------------------*/
15969 +int
15970 +i2c_write(unsigned char theSlave, void *data, size_t nbytes)
15971 +{
15972 +       int error, cntr = 3;
15973 +       unsigned char bytes_wrote = 0;
15974 +       unsigned char value;
15975 +       unsigned long flags;
15976 +
15977 +       spin_lock(&i2c_lock);
15978 +
15979 +       do {
15980 +               error = 0;
15981 +               /*
15982 +                * we don't like to be interrupted
15983 +                */
15984 +                local_irq_save(flags);
15985 +
15986 +               i2c_start();
15987 +               /*
15988 +                * send slave address
15989 +                */
15990 +               i2c_outbyte((theSlave & 0xfe));
15991 +               /*
15992 +                * wait for ack
15993 +                */
15994 +               if(!i2c_getack())
15995 +                       error = 1;
15996 +               /*
15997 +                * send data
15998 +                */
15999 +               for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) {
16000 +                       memcpy(&value, data + bytes_wrote, sizeof value);
16001 +                       i2c_outbyte(value);
16002 +                       /*
16003 +                        * now it's time to wait for ack
16004 +                        */
16005 +                       if (!i2c_getack())
16006 +                               error |= 4;
16007 +               }
16008 +               /*
16009 +                * end byte stream
16010 +                */
16011 +               i2c_stop();
16012 +               /*
16013 +                * enable interrupt again
16014 +                */
16015 +               local_irq_restore(flags);
16016 +               
16017 +       } while(error && cntr--);
16018 +
16019 +       i2c_delay(CLOCK_LOW_TIME);
16020 +       
16021 +       spin_unlock(&i2c_lock);
16022 +
16023 +       return -error;
16024 +}
16025 +
16026 +/*#---------------------------------------------------------------------------
16027 +*#
16028 +*# FUNCTION NAME: i2c_read
16029 +*#
16030 +*# DESCRIPTION  : Reads a value from an I2C device
16031 +*#
16032 +*#--------------------------------------------------------------------------*/
16033 +int
16034 +i2c_read(unsigned char theSlave, void *data, size_t nbytes)
16035 +{
16036 +       unsigned char b = 0;
16037 +       unsigned char bytes_read = 0;
16038 +       int error, cntr = 3;
16039 +       unsigned long flags;
16040 +
16041 +       spin_lock(&i2c_lock);
16042 +
16043 +       do {
16044 +               error = 0;
16045 +               memset(data, 0, nbytes);
16046 +               /*
16047 +                * we don't like to be interrupted
16048 +                */
16049 +                local_irq_save(flags);
16050 +               /*
16051 +                * generate start condition
16052 +                */
16053 +               i2c_start();
16054 +    
16055 +               /*
16056 +                * send slave address
16057 +                */
16058 +               i2c_outbyte((theSlave | 0x01));
16059 +               /*
16060 +                * wait for ack
16061 +                */
16062 +               if(!i2c_getack())
16063 +                       error = 1;
16064 +               /*
16065 +                * fetch data
16066 +                */
16067 +                for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
16068 +                       b = i2c_inbyte();
16069 +                       memcpy(data + bytes_read, &b, sizeof b);
16070 +
16071 +                       if (bytes_read < (nbytes - 1)) {
16072 +                               i2c_sendack();
16073 +                       }
16074 +               }
16075 +               /*
16076 +                * last received byte needs to be nacked
16077 +                * instead of acked
16078 +                */
16079 +               i2c_sendnack();
16080 +               /*
16081 +                * end sequence
16082 +                */
16083 +               i2c_stop();
16084 +               /*
16085 +                * enable interrupt again
16086 +                */
16087 +               local_irq_restore(flags);
16088 +               
16089 +       } while(error && cntr--);
16090 +
16091 +       spin_unlock(&i2c_lock);
16092 +
16093 +       return -error;
16094 +}
16095 +
16096 +/*#---------------------------------------------------------------------------
16097 +*#
16098  *# FUNCTION NAME: i2c_writereg
16099  *#
16100  *# DESCRIPTION  : Writes a value to an I2C device
16101  *#
16102  *#--------------------------------------------------------------------------*/
16103  int
16104 -i2c_writereg(unsigned char theSlave, unsigned char theReg,
16105 +i2c_writereg(unsigned char theSlave, unsigned char theReg, 
16106              unsigned char theValue)
16107  {
16108         int error, cntr = 3;
16109         unsigned long flags;
16110  
16111 +       spin_lock(&i2c_lock);
16112 +
16113         do {
16114                 error = 0;
16115                 /*
16116 @@ -431,10 +574,12 @@
16117                  * enable interrupt again
16118                  */
16119                 local_irq_restore(flags);
16120 -
16121 +               
16122         } while(error && cntr--);
16123  
16124         i2c_delay(CLOCK_LOW_TIME);
16125 +       
16126 +       spin_unlock(&i2c_lock);
16127  
16128         return -error;
16129  }
16130 @@ -453,6 +598,8 @@
16131         int error, cntr = 3;
16132         unsigned long flags;
16133  
16134 +       spin_lock(&i2c_lock);
16135 +
16136         do {
16137                 error = 0;
16138                 /*
16139 @@ -463,7 +610,7 @@
16140                  * generate start condition
16141                  */
16142                 i2c_start();
16143 -
16144 +    
16145                 /*
16146                  * send slave address
16147                  */
16148 @@ -482,7 +629,7 @@
16149                  * now it's time to wait for ack
16150                  */
16151                 if(!i2c_getack())
16152 -                       error = 1;
16153 +                       error |= 2;
16154                 /*
16155                  * repeat start condition
16156                  */
16157 @@ -496,7 +643,7 @@
16158                  * wait for ack
16159                  */
16160                 if(!i2c_getack())
16161 -                       error = 1;
16162 +                       error |= 4;
16163                 /*
16164                  * fetch register
16165                  */
16166 @@ -514,9 +661,11 @@
16167                  * enable interrupt again
16168                  */
16169                 local_irq_restore(flags);
16170 -
16171 +               
16172         } while(error && cntr--);
16173  
16174 +       spin_unlock(&i2c_lock);
16175 +
16176         return b;
16177  }
16178  
16179 @@ -546,7 +695,7 @@
16180         switch (_IOC_NR(cmd)) {
16181                 case I2C_WRITEREG:
16182                         /* write to an i2c slave */
16183 -                       D(printk("i2cw %d %d %d\n",
16184 +                       D(printk("i2cw %d %d %d\n", 
16185                                  I2C_ARGSLAVE(arg),
16186                                  I2C_ARGREG(arg),
16187                                  I2C_ARGVALUE(arg)));
16188 @@ -558,18 +707,18 @@
16189                 {
16190                         unsigned char val;
16191                         /* read from an i2c slave */
16192 -                       D(printk("i2cr %d %d ",
16193 +                       D(printk("i2cr %d %d ", 
16194                                 I2C_ARGSLAVE(arg),
16195                                 I2C_ARGREG(arg)));
16196                         val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
16197                         D(printk("= %d\n", val));
16198                         return val;
16199 -               }
16200 +               }                                           
16201                 default:
16202                         return -EINVAL;
16203  
16204         }
16205 -
16206 +       
16207         return 0;
16208  }
16209  
16210 @@ -583,28 +732,53 @@
16211  int __init
16212  i2c_init(void)
16213  {
16214 -       int res;
16215 +       static int res = 0;
16216 +       static int first = 1;
16217 +       
16218 +       if (!first) {
16219 +               return res;
16220 +       }
16221 +       first = 0;
16222  
16223 -       /* Setup and enable the Port B I2C interface */
16224 +       /* Setup and enable the DATA and CLK pins */
16225  
16226 -        crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT);
16227 -        crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT);
16228 +        res = crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT);
16229 +       if (res < 0) {
16230 +               return res;
16231 +       }
16232 +       
16233 +        res = crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT);
16234 +       crisv32_io_set_dir(&cris_i2c_clk, crisv32_io_dir_out);
16235 +       
16236 +       return res;
16237 +}
16238  
16239 -       /* register char device */
16240  
16241 +int __init
16242 +i2c_register(void)
16243 +{
16244 +
16245 +       int res;
16246 +       
16247 +       res = i2c_init();
16248 +       if (res < 0) {
16249 +               return res;
16250 +       }
16251 +       
16252 +       /* register char device */
16253         res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
16254         if(res < 0) {
16255                 printk(KERN_ERR "i2c: couldn't get a major number.\n");
16256                 return res;
16257         }
16258  
16259 -       printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
16260 -
16261 +       printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");
16262 +       
16263         return 0;
16264  }
16265  
16266  /* this makes sure that i2c_init is called during boot */
16267  
16268 -module_init(i2c_init);
16269 +module_init(i2c_register);
16270  
16271  /****************** END OF FILE i2c.c ********************************/
16272 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.h linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.h
16273 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.h 2007-01-10 20:10:37.000000000 +0100
16274 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.h 2006-11-06 16:48:06.000000000 +0100
16275 @@ -3,6 +3,8 @@
16276  
16277  /* High level I2C actions */
16278  int __init i2c_init(void);
16279 +int i2c_write(unsigned char theSlave, void *data, size_t nbytes);
16280 +int i2c_read(unsigned char theSlave, void *data, size_t nbytes);
16281  int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
16282  unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
16283  
16284 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/iop_fw_load.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/iop_fw_load.c
16285 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/iop_fw_load.c 2007-01-10 20:10:37.000000000 +0100
16286 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/iop_fw_load.c 2005-04-07 11:27:46.000000000 +0200
16287 @@ -67,12 +67,12 @@
16288                 return -ENODEV;
16289  
16290         /* get firmware */
16291 -       retval = request_firmware(&fw_entry,
16292 -                                 fw_name,
16293 +       retval = request_firmware(&fw_entry, 
16294 +                                 fw_name, 
16295                                   &iop_spu_device[spu_inst]);
16296         if (retval != 0)
16297         {
16298 -               printk(KERN_ERR
16299 +               printk(KERN_ERR 
16300                        "iop_load_spu: Failed to load firmware \"%s\"\n",
16301                        fw_name);
16302                 return retval;
16303 @@ -123,7 +123,7 @@
16304         return retval;
16305  }
16306  
16307 -int iop_fw_load_mpu(unsigned char *fw_name)
16308 +int iop_fw_load_mpu(unsigned char *fw_name) 
16309  {
16310         const unsigned int start_addr = 0;
16311         reg_iop_mpu_rw_ctrl mpu_ctrl;
16312 @@ -135,13 +135,13 @@
16313         retval = request_firmware(&fw_entry, fw_name, &iop_mpu_device);
16314         if (retval != 0)
16315         {
16316 -               printk(KERN_ERR
16317 +               printk(KERN_ERR 
16318                        "iop_load_spu: Failed to load firmware \"%s\"\n",
16319                        fw_name);
16320                 return retval;
16321         }
16322         data = (u32 *) fw_entry->data;
16323 -
16324 +       
16325         /* disable MPU */
16326         mpu_ctrl.en = regk_iop_mpu_no;
16327         REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
16328 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/nandflash.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/nandflash.c
16329 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/nandflash.c   2007-01-10 20:10:37.000000000 +0100
16330 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/nandflash.c   2006-10-16 14:56:46.000000000 +0200
16331 @@ -5,8 +5,8 @@
16332   *
16333   *  Derived from drivers/mtd/nand/spia.c
16334   *       Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
16335 - *
16336 - * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $
16337 + * 
16338 + * $Id: nandflash.c,v 1.8 2006/10/16 12:56:46 ricardw Exp $
16339   *
16340   * This program is free software; you can redistribute it and/or modify
16341   * it under the terms of the GNU General Public License version 2 as
16342 @@ -32,37 +32,53 @@
16343  #define ALE_BIT 6
16344  #define BY_BIT 7
16345  
16346 +/* Bitmask for control pins */
16347 +#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
16348 +
16349 +/* Bitmask for mtd nand control bits */
16350 +#define CTRL_BITMASK (NAND_NCE | NAND_CLE | NAND_ALE)
16351 +
16352 +
16353  static struct mtd_info *crisv32_mtd = NULL;
16354 -/*
16355 +/* 
16356   *     hardware specific access to control-lines
16357  */
16358 -static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
16359 +static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
16360 +                             unsigned int ctrl)
16361  {
16362         unsigned long flags;
16363 -       reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
16364 +       reg_gio_rw_pa_dout dout;
16365 +       struct nand_chip *this = mtd->priv;
16366  
16367         local_irq_save(flags);
16368 -       switch(cmd){
16369 -               case NAND_CTL_SETCLE:
16370 -                    dout.data |= (1<<CLE_BIT);
16371 -                    break;
16372 -               case NAND_CTL_CLRCLE:
16373 -                    dout.data &= ~(1<<CLE_BIT);
16374 -                    break;
16375 -               case NAND_CTL_SETALE:
16376 -                    dout.data |= (1<<ALE_BIT);
16377 -                    break;
16378 -               case NAND_CTL_CLRALE:
16379 -                    dout.data &= ~(1<<ALE_BIT);
16380 -                    break;
16381 -               case NAND_CTL_SETNCE:
16382 -                    dout.data |= (1<<CE_BIT);
16383 -                    break;
16384 -               case NAND_CTL_CLRNCE:
16385 -                    dout.data &= ~(1<<CE_BIT);
16386 -                    break;
16387 +
16388 +       /* control bits change */
16389 +       if (ctrl & NAND_CTRL_CHANGE) {
16390 +               dout = REG_RD(gio, regi_gio, rw_pa_dout);
16391 +               dout.data &= ~PIN_BITMASK;
16392 +
16393 +#if (CE_BIT == 4 && NAND_NCE == 1 &&  \
16394 +     CLE_BIT == 5 && NAND_CLE == 2 && \
16395 +     ALE_BIT == 6 && NAND_ALE == 4)
16396 +               /* Pins in same order as control bits, but shifted.
16397 +                * Optimize for this case; works for 2.6.18 */
16398 +               dout.data |= ((ctrl & CTRL_BITMASK) ^ NAND_NCE) << CE_BIT;
16399 +#else
16400 +               /* the slow way */
16401 +               if (!(ctrl & NAND_NCE))
16402 +                       dout.data |= (1 << CE_BIT);
16403 +               if (ctrl & NAND_CLE)
16404 +                       dout.data |= (1 << CLE_BIT);
16405 +               if (ctrl & NAND_ALE)
16406 +                       dout.data |= (1 << ALE_BIT);
16407 +#endif
16408 +               REG_WR(gio, regi_gio, rw_pa_dout, dout);
16409         }
16410 -       REG_WR(gio, regi_gio, rw_pa_dout, dout);
16411 +
16412 +       /* command to chip */
16413 +       if (cmd != NAND_CMD_NONE)
16414 +               writeb(cmd, this->IO_ADDR_W);
16415 +
16416         local_irq_restore(flags);
16417  }
16418  
16419 @@ -129,26 +145,26 @@
16420         /* Set address of NAND IO lines */
16421         this->IO_ADDR_R = read_cs;
16422         this->IO_ADDR_W = write_cs;
16423 -       this->hwcontrol = crisv32_hwcontrol;
16424 +       this->cmd_ctrl = crisv32_hwcontrol;
16425         this->dev_ready = crisv32_device_ready;
16426         /* 20 us command delay time */
16427 -       this->chip_delay = 20;
16428 -       this->eccmode = NAND_ECC_SOFT;
16429 +       this->chip_delay = 20;          
16430 +       this->ecc.mode = NAND_ECC_SOFT;
16431  
16432         /* Enable the following for a flash based bad block table */
16433 -       this->options = NAND_USE_FLASH_BBT;
16434 +       /* this->options = NAND_USE_FLASH_BBT; */
16435  
16436         /* Scan to find existance of the device */
16437         if (nand_scan (crisv32_mtd, 1)) {
16438                 err = -ENXIO;
16439                 goto out_ior;
16440         }
16441 -
16442 +       
16443         return crisv32_mtd;
16444 -
16445 +       
16446  out_ior:
16447         iounmap((void *)read_cs);
16448 -       iounmap((void *)write_cs);
16449 +       iounmap((void *)write_cs);      
16450  out_mtd:
16451         kfree (crisv32_mtd);
16452          return NULL;
16453 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pcf8563.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pcf8563.c
16454 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pcf8563.c     2007-01-10 20:10:37.000000000 +0100
16455 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pcf8563.c     2006-10-27 17:22:13.000000000 +0200
16456 @@ -10,7 +10,7 @@
16457   * 400 kbits/s. The built-in word address register is incremented
16458   * automatically after each written or read byte.
16459   *
16460 - * Copyright (c) 2002-2003, Axis Communications AB
16461 + * Copyright (c) 2002-2006, Axis Communications AB
16462   * All rights reserved.
16463   *
16464   * Author: Tobias Anderberg <tobiasa@axis.com>.
16465 @@ -37,24 +37,27 @@
16466  #define PCF8563_MAJOR  121     /* Local major number. */
16467  #define DEVICE_NAME    "rtc"   /* Name which is registered in /proc/devices. */
16468  #define PCF8563_NAME   "PCF8563"
16469 -#define DRIVER_VERSION "$Revision: 1.1 $"
16470 +#define DRIVER_VERSION "$Revision: 1.9 $"
16471  
16472  /* Two simple wrapper macros, saves a few keystrokes. */
16473  #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
16474  #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
16475  
16476 +static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
16477 +
16478  static const unsigned char days_in_month[] =
16479         { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
16480  
16481  int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
16482 -int pcf8563_open(struct inode *, struct file *);
16483 -int pcf8563_release(struct inode *, struct file *);
16484 +
16485 +/* Cache VL bit value read at driver init since writing the RTC_SECOND 
16486 + * register clears the VL status.
16487 + */
16488 +static int voltage_low = 0;
16489  
16490  static struct file_operations pcf8563_fops = {
16491         owner: THIS_MODULE,
16492         ioctl: pcf8563_ioctl,
16493 -       open: pcf8563_open,
16494 -       release: pcf8563_release,
16495  };
16496  
16497  unsigned char
16498 @@ -62,7 +65,7 @@
16499  {
16500         unsigned char res = rtc_read(reg);
16501  
16502 -       /* The PCF8563 does not return 0 for unimplemented bits */
16503 +       /* The PCF8563 does not return 0 for unimplemented bits. */
16504         switch (reg) {
16505                 case RTC_SECONDS:
16506                 case RTC_MINUTES:
16507 @@ -95,11 +98,6 @@
16508  void
16509  pcf8563_writereg(int reg, unsigned char val)
16510  {
16511 -#ifdef CONFIG_ETRAX_RTC_READONLY
16512 -       if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
16513 -               return;
16514 -#endif
16515 -
16516         rtc_write(reg, val);
16517  }
16518  
16519 @@ -114,11 +112,13 @@
16520         tm->tm_mon  = rtc_read(RTC_MONTH);
16521         tm->tm_year = rtc_read(RTC_YEAR);
16522  
16523 -       if (tm->tm_sec & 0x80)
16524 +       if (tm->tm_sec & 0x80) {
16525                 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16526                        "information is no longer guaranteed!\n", PCF8563_NAME);
16527 +       }
16528  
16529 -       tm->tm_year  = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
16530 +       tm->tm_year  = BCD_TO_BIN(tm->tm_year) +
16531 +                      ((tm->tm_mon & 0x80) ? 100 : 0);
16532         tm->tm_sec  &= 0x7F;
16533         tm->tm_min  &= 0x7F;
16534         tm->tm_hour &= 0x3F;
16535 @@ -137,8 +137,20 @@
16536  int __init
16537  pcf8563_init(void)
16538  {
16539 +       static int res = 0;
16540 +       static int first = 1;
16541 +
16542 +       if (!first) {
16543 +               return res;
16544 +       }
16545 +       first = 0;
16546 +
16547         /* Initiate the i2c protocol. */
16548 -       i2c_init();
16549 +       res = i2c_init();
16550 +       if (res < 0) {
16551 +               printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
16552 +               return res;
16553 +       }
16554  
16555         /*
16556          * First of all we need to reset the chip. This is done by
16557 @@ -170,31 +182,28 @@
16558         if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
16559                 goto err;
16560  
16561 -       if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
16562 -               printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
16563 -                      PCF8563_NAME, PCF8563_MAJOR);
16564 -               return -1;
16565 +       /* Check for low voltage, and warn about it. */
16566 +       if (rtc_read(RTC_SECONDS) & 0x80) {
16567 +               voltage_low = 1;
16568 +               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16569 +                      "date/time information is no longer guaranteed!\n",
16570 +                      PCF8563_NAME);
16571         }
16572  
16573 -       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
16574 -
16575 -       /* Check for low voltage, and warn about it.. */
16576 -       if (rtc_read(RTC_SECONDS) & 0x80)
16577 -               printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16578 -                      "information is no longer guaranteed!\n", PCF8563_NAME);
16579 -
16580 -       return 0;
16581 +       return res;
16582  
16583  err:
16584         printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
16585 -       return -1;
16586 +       res = -1;
16587 +       return res;
16588  }
16589  
16590  void __exit
16591  pcf8563_exit(void)
16592  {
16593         if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
16594 -               printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
16595 +               printk(KERN_INFO "%s: Unable to unregister device.\n",
16596 +                      PCF8563_NAME);
16597         }
16598  }
16599  
16600 @@ -203,7 +212,8 @@
16601   * POSIX says so!
16602   */
16603  int
16604 -pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
16605 +pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
16606 +              unsigned long arg)
16607  {
16608         /* Some sanity checks. */
16609         if (_IOC_TYPE(cmd) != RTC_MAGIC)
16610 @@ -217,31 +227,35 @@
16611                 {
16612                         struct rtc_time tm;
16613  
16614 -                       memset(&tm, 0, sizeof (struct rtc_time));
16615 +                       spin_lock(&rtc_lock);
16616 +                       memset(&tm, 0, sizeof tm);
16617                         get_rtc_time(&tm);
16618  
16619 -                       if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
16620 +                       if (copy_to_user((struct rtc_time *) arg, &tm,
16621 +                                        sizeof tm)) {
16622 +                               spin_unlock(&rtc_lock);
16623                                 return -EFAULT;
16624                         }
16625  
16626 +                       spin_unlock(&rtc_lock);
16627 +
16628                         return 0;
16629                 }
16630 -
16631                 case RTC_SET_TIME:
16632                 {
16633 -#ifdef CONFIG_ETRAX_RTC_READONLY
16634 -                       return -EPERM;
16635 -#else
16636                         int leap;
16637                         int year;
16638                         int century;
16639                         struct rtc_time tm;
16640  
16641 +                       memset(&tm, 0, sizeof tm);
16642                         if (!capable(CAP_SYS_TIME))
16643                                 return -EPERM;
16644  
16645 -                       if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
16646 +                       if (copy_from_user(&tm, (struct rtc_time *) arg,
16647 +                                          sizeof tm)) {
16648                                 return -EFAULT;
16649 +                       }
16650  
16651                         /* Convert from struct tm to struct rtc_time. */
16652                         tm.tm_year += 1900;
16653 @@ -253,7 +267,8 @@
16654                          * that years divisible by 400 _are_ leap years.
16655                          */
16656                         year = tm.tm_year;
16657 -                       leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
16658 +                       leap = (tm.tm_mon == 2) && 
16659 +                               ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
16660  
16661                         /* Perform some sanity checks. */
16662                         if ((tm.tm_year < 1970) ||
16663 @@ -263,19 +278,23 @@
16664                             (tm.tm_wday >= 7) ||
16665                             (tm.tm_hour >= 24) ||
16666                             (tm.tm_min >= 60) ||
16667 -                           (tm.tm_sec >= 60))
16668 +                           (tm.tm_sec >= 60)) {
16669                                 return -EINVAL;
16670 +                       }
16671  
16672                         century = (tm.tm_year >= 2000) ? 0x80 : 0;
16673                         tm.tm_year = tm.tm_year % 100;
16674  
16675                         BIN_TO_BCD(tm.tm_year);
16676 +                       BIN_TO_BCD(tm.tm_mon);
16677                         BIN_TO_BCD(tm.tm_mday);
16678                         BIN_TO_BCD(tm.tm_hour);
16679                         BIN_TO_BCD(tm.tm_min);
16680                         BIN_TO_BCD(tm.tm_sec);
16681                         tm.tm_mon |= century;
16682  
16683 +                       spin_lock(&rtc_lock);
16684 +
16685                         rtc_write(RTC_YEAR, tm.tm_year);
16686                         rtc_write(RTC_MONTH, tm.tm_mon);
16687                         rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
16688 @@ -284,36 +303,40 @@
16689                         rtc_write(RTC_MINUTES, tm.tm_min);
16690                         rtc_write(RTC_SECONDS, tm.tm_sec);
16691  
16692 +                       spin_unlock(&rtc_lock);
16693 +
16694                         return 0;
16695 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
16696                 }
16697 -
16698                 case RTC_VLOW_RD:
16699 -               {
16700 -                       int vl_bit = 0;
16701 -
16702 -                       if (rtc_read(RTC_SECONDS) & 0x80) {
16703 -                               vl_bit = 1;
16704 -                               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16705 -                                      "date/time information is no longer guaranteed!\n",
16706 -                                      PCF8563_NAME);
16707 +                       if (voltage_low) {
16708 +                               printk(KERN_WARNING "%s: RTC Voltage Low - "
16709 +                                      "reliable date/time information is no "
16710 +                                      "longer guaranteed!\n", PCF8563_NAME);
16711                         }
16712 -                       if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
16713 -                               return -EFAULT;
16714  
16715 +                       if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
16716 +                               return -EFAULT;
16717 +                       }
16718 +                       
16719                         return 0;
16720 -               }
16721  
16722                 case RTC_VLOW_SET:
16723                 {
16724 -                       /* Clear the VL bit in the seconds register */
16725 +                       /* Clear the VL bit in the seconds register in case 
16726 +                        * the time has not been set already (which would
16727 +                        * have cleared it). This does not really matter 
16728 +                        * because of the cached voltage_low value but do it
16729 +                        * anyway for consistency. */
16730 +
16731                         int ret = rtc_read(RTC_SECONDS);
16732  
16733                         rtc_write(RTC_SECONDS, (ret & 0x7F));
16734  
16735 +                       /* Clear the cached value. */
16736 +                       voltage_low = 0;
16737 +
16738                         return 0;
16739                 }
16740 -
16741                 default:
16742                         return -ENOTTY;
16743         }
16744 @@ -321,17 +344,32 @@
16745         return 0;
16746  }
16747  
16748 -int
16749 -pcf8563_open(struct inode *inode, struct file *filp)
16750 +static int __init 
16751 +pcf8563_register(void)
16752  {
16753 -       return 0;
16754 -}
16755 +       if (pcf8563_init() < 0) {
16756 +               printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
16757 +                      "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
16758 +               return -1;
16759 +       }
16760 +
16761 +       if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
16762 +               printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
16763 +                      "device.\n", PCF8563_NAME, PCF8563_MAJOR);
16764 +               return -1;
16765 +       }
16766 +
16767 +       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
16768 +              DRIVER_VERSION);
16769 +
16770 +       /* Check for low voltage, and warn about it. */
16771 +       if (voltage_low) {
16772 +               printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16773 +                      "information is no longer guaranteed!\n", PCF8563_NAME);
16774 +       }
16775  
16776 -int
16777 -pcf8563_release(struct inode *inode, struct file *filp)
16778 -{
16779         return 0;
16780  }
16781  
16782 -module_init(pcf8563_init);
16783 +module_init(pcf8563_register);
16784  module_exit(pcf8563_exit);
16785 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/bios.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/bios.c
16786 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/bios.c    2007-01-10 20:10:37.000000000 +0100
16787 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/bios.c    2006-10-13 14:43:15.000000000 +0200
16788 @@ -60,7 +60,7 @@
16789         u16 cmd, old_cmd;
16790         int idx;
16791         struct resource *r;
16792 -
16793 +        
16794         pci_read_config_word(dev, PCI_COMMAND, &cmd);
16795         old_cmd = cmd;
16796         for(idx=0; idx<6; idx++) {
16797 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/dma.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/dma.c
16798 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/dma.c     2007-01-10 20:10:37.000000000 +0100
16799 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/dma.c     2005-10-31 09:48:04.000000000 +0100
16800 @@ -62,7 +62,7 @@
16801  {
16802         struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
16803         int order = get_order(size);
16804 -
16805 +       
16806         if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
16807                 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
16808  
16809 @@ -120,7 +120,7 @@
16810  void dma_release_declared_memory(struct device *dev)
16811  {
16812         struct dma_coherent_mem *mem = dev->dma_mem;
16813 -
16814 +       
16815         if(!mem)
16816                 return;
16817         dev->dma_mem = NULL;
16818 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/sync_serial.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/sync_serial.c
16819 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/sync_serial.c 2007-01-10 20:10:37.000000000 +0100
16820 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/sync_serial.c 2007-01-09 10:29:20.000000000 +0100
16821 @@ -50,7 +50,7 @@
16822  /*    readp          writep                                              */
16823  /*                                                                       */
16824  /* If the application keeps up the pace readp will be right after writep.*/
16825 -/* If the application can't keep the pace we have to throw away data.    */
16826 +/* If the application can't keep the pace we have to throw away data.    */ 
16827  /* The idea is that readp should be ready with the data pointed out by  */
16828  /* Descr[i] when the DMA has filled in Descr[i+1].                       */
16829  /* Otherwise we will discard                                            */
16830 @@ -65,6 +65,7 @@
16831  #define IN_DESCR_SIZE 256
16832  #define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
16833  #define OUT_BUFFER_SIZE 4096
16834 +#define NUM_OUT_DESCRS 4
16835  
16836  #define DEFAULT_FRAME_RATE 0
16837  #define DEFAULT_WORD_RATE 7
16838 @@ -112,7 +113,7 @@
16839  
16840         dma_descr_data in_descr[NUM_IN_DESCR] __attribute__ ((__aligned__(16)));
16841         dma_descr_context in_context __attribute__ ((__aligned__(32)));
16842 -       dma_descr_data out_descr __attribute__ ((__aligned__(16)));
16843 +       dma_descr_data out_descr[NUM_OUT_DESCRS] __attribute__ ((__aligned__(16)));
16844         dma_descr_context out_context __attribute__ ((__aligned__(32)));
16845         wait_queue_head_t out_wait_q;
16846         wait_queue_head_t in_wait_q;
16847 @@ -130,9 +131,9 @@
16848  
16849  static int sync_serial_ioctl(struct inode*, struct file*,
16850                              unsigned int cmd, unsigned long arg);
16851 -static ssize_t sync_serial_write(struct file * file, const char * buf,
16852 +static ssize_t sync_serial_write(struct file * file, const char * buf, 
16853                                  size_t count, loff_t *ppos);
16854 -static ssize_t sync_serial_read(struct file *file, char *buf,
16855 +static ssize_t sync_serial_read(struct file *file, char *buf, 
16856                                 size_t count, loff_t *ppos);
16857  
16858  #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
16859 @@ -146,8 +147,8 @@
16860  static void start_dma(struct sync_port *port, const char* data, int count);
16861  static void start_dma_in(sync_port* port);
16862  #ifdef SYNC_SER_DMA
16863 -static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16864 -static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16865 +static irqreturn_t tr_interrupt(int irq, void *dev_id);
16866 +static irqreturn_t rx_interrupt(int irq, void *dev_id);
16867  #endif
16868  
16869  #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
16870 @@ -157,7 +158,7 @@
16871  #define SYNC_SER_MANUAL
16872  #endif
16873  #ifdef SYNC_SER_MANUAL
16874 -static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16875 +static irqreturn_t manual_interrupt(int irq, void *dev_id);
16876  #endif
16877  
16878  /* The ports */
16879 @@ -201,8 +202,8 @@
16880  {
16881         ports[0].enabled = 0;
16882         ports[1].enabled = 0;
16883 -
16884 -       if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
16885 +       
16886 +       if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) 
16887         {
16888                 printk("unable to get major for synchronous serial port\n");
16889                 return -EBUSY;
16890 @@ -243,13 +244,13 @@
16891  
16892         DEBUG(printk("Init sync serial port %d\n", portnbr));
16893  
16894 -       port->port_nbr = portnbr;
16895 +       port->port_nbr = portnbr;       
16896         port->init_irqs = 1;
16897  
16898         port->outp = port->out_buffer;
16899         port->output = 1;
16900         port->input = 0;
16901 -
16902 +       
16903         port->readp = port->flip;
16904         port->writep = port->flip;
16905         port->in_buffer_size = IN_BUFFER_SIZE;
16906 @@ -286,11 +287,16 @@
16907         tr_cfg.sample_size = 7;
16908         tr_cfg.sh_dir = regk_sser_msbfirst;
16909         tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
16910 +#if 0
16911         tr_cfg.rate_ctrl = regk_sser_bulk;
16912         tr_cfg.data_pin_use = regk_sser_dout;
16913 +#else
16914 +       tr_cfg.rate_ctrl = regk_sser_iso;
16915 +       tr_cfg.data_pin_use = regk_sser_dout;
16916 +#endif
16917         tr_cfg.bulk_wspace = 1;
16918         REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
16919 -
16920 +       
16921         rec_cfg.sample_size = 7;
16922         rec_cfg.sh_dir = regk_sser_msbfirst;
16923         rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
16924 @@ -303,17 +309,17 @@
16925         int avail;
16926         unsigned char *start;
16927         unsigned char *end;
16928 -
16929 +       
16930         start = (unsigned char*)port->readp; /* cast away volatile */
16931         end = (unsigned char*)port->writep;  /* cast away volatile */
16932         /* 0123456789  0123456789
16933          *  -----      -    -----
16934          *  ^rp  ^wp    ^wp ^rp
16935          */
16936 -
16937 +               
16938         if (end >= start)
16939                 avail = end - start;
16940 -       else
16941 +       else 
16942                 avail = port->in_buffer_size - (start - end);
16943         return avail;
16944  }
16945 @@ -323,17 +329,17 @@
16946         int avail;
16947         unsigned char *start;
16948         unsigned char *end;
16949 -
16950 +       
16951         start = (unsigned char*)port->readp; /* cast away volatile */
16952         end = (unsigned char*)port->writep;  /* cast away volatile */
16953         /* 0123456789  0123456789
16954          *  -----           -----
16955          *  ^rp  ^wp    ^wp ^rp
16956          */
16957 -
16958 +               
16959         if (end >= start)
16960                 avail = end - start;
16961 -       else
16962 +       else 
16963                 avail = port->flip + port->in_buffer_size - start;
16964         return avail;
16965  }
16966 @@ -343,10 +349,10 @@
16967         int dev = iminor(inode);
16968         sync_port* port;
16969         reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
16970 -       reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
16971 -
16972 -       DEBUG(printk("Open sync serial port %d\n", dev));
16973 +       reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};        
16974  
16975 +       DEBUG(printk("Open sync serial port %d\n", dev)); 
16976 +  
16977         if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
16978         {
16979                 DEBUG(printk("Invalid minor %d\n", dev));
16980 @@ -354,7 +360,7 @@
16981         }
16982         port = &ports[dev];
16983         /* Allow open this device twice (assuming one reader and one writer) */
16984 -       if (port->busy == 2)
16985 +       if (port->busy == 2) 
16986         {
16987                 DEBUG(printk("Device is busy.. \n"));
16988                 return -EBUSY;
16989 @@ -422,8 +428,8 @@
16990                                                                 DMA_VERBOSE_ON_ERROR,
16991                                                                 0,
16992                                                                 dma_sser1)) {
16993 -                                       free_irq(21, &ports[1]);
16994 -                                       free_irq(20, &ports[1]);
16995 +                                       free_irq(DMA6_INTR_VECT, &ports[1]);
16996 +                                       free_irq(DMA7_INTR_VECT, &ports[1]);
16997                                         printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
16998                                         return -EBUSY;
16999                                 } else if (crisv32_request_dma(SYNC_SER1_RX_DMA_NBR,
17000 @@ -446,7 +452,7 @@
17001                         /* Enable DMA IRQs */
17002                         REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
17003                         REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
17004 -                       /* Set up wordsize = 2 for DMAs. */
17005 +                       /* Set up wordsize = 1 for DMAs. */
17006                         DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1);
17007                         DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1);
17008  
17009 @@ -497,7 +503,7 @@
17010         port = &ports[dev];
17011         if (port->busy)
17012                 port->busy--;
17013 -       if (!port->busy)
17014 +       if (!port->busy) 
17015            /* XXX */ ;
17016         return 0;
17017  }
17018 @@ -508,17 +514,29 @@
17019         unsigned int mask = 0;
17020         sync_port* port;
17021         DEBUGPOLL( static unsigned int prev_mask = 0; );
17022 -
17023 +       
17024         port = &ports[dev];
17025 +
17026 +       if (!port->started)
17027 +       {
17028 +               reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
17029 +               reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
17030 +               cfg.en = regk_sser_yes;
17031 +               rec_cfg.rec_en = port->input;
17032 +               REG_WR(sser, port->regi_sser, rw_cfg, cfg);
17033 +               REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17034 +               port->started = 1;
17035 +       }
17036 +
17037         poll_wait(file, &port->out_wait_q, wait);
17038         poll_wait(file, &port->in_wait_q, wait);
17039         /* Some room to write */
17040 -       if (port->out_count < OUT_BUFFER_SIZE)
17041 +       if (port->output && port->out_count < OUT_BUFFER_SIZE)
17042                 mask |=  POLLOUT | POLLWRNORM;
17043         /* At least an inbufchunk of data */
17044 -       if (sync_data_avail(port) >= port->inbufchunk)
17045 +       if (port->input && sync_data_avail(port) >= port->inbufchunk)
17046                 mask |= POLLIN | POLLRDNORM;
17047 -
17048 +       
17049         DEBUGPOLL(if (mask != prev_mask)
17050               printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
17051                      mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
17052 @@ -531,14 +549,15 @@
17053                   unsigned int cmd, unsigned long arg)
17054  {
17055         int return_val = 0;
17056 +       int dma_w_size = regk_dma_set_w_size1;
17057         int dev = iminor(file->f_dentry->d_inode);
17058         sync_port* port;
17059         reg_sser_rw_tr_cfg tr_cfg;
17060         reg_sser_rw_rec_cfg rec_cfg;
17061 -       reg_sser_rw_frm_cfg frm_cfg;
17062 +       reg_sser_rw_frm_cfg frm_cfg;    
17063         reg_sser_rw_cfg gen_cfg;
17064         reg_sser_rw_intr_mask intr_mask;
17065 -
17066 +        
17067         if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
17068         {
17069                 DEBUG(printk("Invalid minor %d\n", dev));
17070 @@ -558,9 +577,32 @@
17071         case SSP_SPEED:
17072                 if (GET_SPEED(arg) == CODEC)
17073                 {
17074 +                       unsigned int freq;
17075 +
17076                         gen_cfg.base_freq = regk_sser_f32;
17077 -                       /* FREQ = 0 => 4 MHz => clk_div = 7*/
17078 -                       gen_cfg.clk_div = 6 + (1 << GET_FREQ(arg));
17079 +
17080 +                       /* Clock divider will internally be
17081 +                        * gen_cfg.clk_div + 1.
17082 +                        */
17083 +
17084 +                       freq = GET_FREQ(arg);
17085 +                       switch (freq)
17086 +                       {
17087 +                               case FREQ_32kHz:
17088 +                               case FREQ_64kHz:
17089 +                               case FREQ_128kHz:
17090 +                               case FREQ_256kHz:
17091 +                                       gen_cfg.clk_div = 125 * (1 << (freq - FREQ_256kHz)) - 1;
17092 +                               break;
17093 +                               case FREQ_512kHz:
17094 +                                       gen_cfg.clk_div = 62;
17095 +                               break;
17096 +                               case FREQ_1MHz:
17097 +                               case FREQ_2MHz:
17098 +                               case FREQ_4MHz:
17099 +                                       gen_cfg.clk_div = 8 * (1 << freq) - 1;
17100 +                               break;
17101 +                        }
17102                 }
17103                 else
17104                 {
17105 @@ -625,87 +667,118 @@
17106                         case MASTER_OUTPUT:
17107                                 port->output = 1;
17108                                 port->input = 0;
17109 +                               frm_cfg.out_on = regk_sser_tr;
17110 +                               frm_cfg.frame_pin_dir = regk_sser_out;
17111                                 gen_cfg.clk_dir = regk_sser_out;
17112                                 break;
17113                         case SLAVE_OUTPUT:
17114                                 port->output = 1;
17115                                 port->input = 0;
17116 +                               frm_cfg.frame_pin_dir = regk_sser_in;
17117                                 gen_cfg.clk_dir = regk_sser_in;
17118                                 break;
17119                         case MASTER_INPUT:
17120                                 port->output = 0;
17121                                 port->input = 1;
17122 +                               frm_cfg.frame_pin_dir = regk_sser_out;
17123 +                               frm_cfg.out_on = regk_sser_intern_tb;
17124                                 gen_cfg.clk_dir = regk_sser_out;
17125                                 break;
17126                         case SLAVE_INPUT:
17127                                 port->output = 0;
17128                                 port->input = 1;
17129 +                               frm_cfg.frame_pin_dir = regk_sser_in;
17130                                 gen_cfg.clk_dir = regk_sser_in;
17131                                 break;
17132                         case MASTER_BIDIR:
17133                                 port->output = 1;
17134                                 port->input = 1;
17135 +                               frm_cfg.frame_pin_dir = regk_sser_out;
17136 +                               frm_cfg.out_on = regk_sser_intern_tb;
17137                                 gen_cfg.clk_dir = regk_sser_out;
17138                                 break;
17139                         case SLAVE_BIDIR:
17140                                 port->output = 1;
17141                                 port->input = 1;
17142 +                               frm_cfg.frame_pin_dir = regk_sser_in;
17143                                 gen_cfg.clk_dir = regk_sser_in;
17144                                 break;
17145                         default:
17146                                 spin_unlock_irq(&port->lock);
17147                                 return -EINVAL;
17148 -
17149 +                                                            
17150                 }
17151                 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT))
17152                         intr_mask.rdav = regk_sser_yes;
17153                 break;
17154         case SSP_FRAME_SYNC:
17155 -               if (arg & NORMAL_SYNC)
17156 +               if (arg & NORMAL_SYNC) {
17157 +                       frm_cfg.rec_delay = 1;
17158                         frm_cfg.tr_delay = 1;
17159 +               }
17160                 else if (arg & EARLY_SYNC)
17161 -                       frm_cfg.tr_delay = 0;
17162 +                       frm_cfg.rec_delay = frm_cfg.tr_delay = 0;
17163 +               else if (arg & SECOND_WORD_SYNC) {
17164 +                       frm_cfg.rec_delay = 17;
17165 +                       frm_cfg.tr_delay = 1;
17166 +               }
17167 +               
17168 +                       
17169  
17170                 tr_cfg.bulk_wspace = frm_cfg.tr_delay;
17171                 frm_cfg.early_wend = regk_sser_yes;
17172 -               if (arg & BIT_SYNC)
17173 +               if (arg & BIT_SYNC) 
17174                         frm_cfg.type = regk_sser_edge;
17175                 else if (arg & WORD_SYNC)
17176                         frm_cfg.type = regk_sser_level;
17177                 else if (arg & EXTENDED_SYNC)
17178                         frm_cfg.early_wend = regk_sser_no;
17179 -
17180 +               
17181                 if (arg & SYNC_ON)
17182                         frm_cfg.frame_pin_use = regk_sser_frm;
17183                 else if (arg & SYNC_OFF)
17184                         frm_cfg.frame_pin_use = regk_sser_gio0;
17185 -
17186 -               if (arg & WORD_SIZE_8)
17187 +               
17188 +               if (arg & WORD_SIZE_8) {
17189                         rec_cfg.sample_size = tr_cfg.sample_size = 7;
17190 -               else if (arg & WORD_SIZE_12)
17191 +                       dma_w_size = regk_dma_set_w_size1;
17192 +               }
17193 +               else if (arg & WORD_SIZE_12) { 
17194                         rec_cfg.sample_size = tr_cfg.sample_size = 11;
17195 -               else if (arg & WORD_SIZE_16)
17196 +                       dma_w_size = regk_dma_set_w_size2;
17197 +               }
17198 +               else if (arg & WORD_SIZE_16) {                  
17199                         rec_cfg.sample_size = tr_cfg.sample_size = 15;
17200 -               else if (arg & WORD_SIZE_24)
17201 +                       dma_w_size = regk_dma_set_w_size2;
17202 +               }
17203 +               else if (arg & WORD_SIZE_24) {
17204                         rec_cfg.sample_size = tr_cfg.sample_size = 23;
17205 -               else if (arg & WORD_SIZE_32)
17206 +                       dma_w_size = regk_dma_set_w_size2;
17207 +               }
17208 +               else if (arg & WORD_SIZE_32) {
17209                         rec_cfg.sample_size = tr_cfg.sample_size = 31;
17210 +                       dma_w_size = regk_dma_set_w_size2;
17211 +               }
17212  
17213                 if (arg & BIT_ORDER_MSB)
17214                         rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_msbfirst;
17215                 else if (arg & BIT_ORDER_LSB)
17216                         rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst;
17217 -
17218 -               if (arg & FLOW_CONTROL_ENABLE)
17219 +               
17220 +               if (arg & FLOW_CONTROL_ENABLE) {
17221 +                       frm_cfg.status_pin_use = regk_sser_frm;
17222                         rec_cfg.fifo_thr = regk_sser_thr16;
17223 -               else if (arg & FLOW_CONTROL_DISABLE)
17224 +               }
17225 +               else if (arg & FLOW_CONTROL_DISABLE) {
17226 +                       frm_cfg.status_pin_use = regk_sser_gio0;
17227                         rec_cfg.fifo_thr = regk_sser_inf;
17228 +               }
17229  
17230                 if (arg & CLOCK_NOT_GATED)
17231                         gen_cfg.gate_clk = regk_sser_no;
17232                 else if (arg & CLOCK_GATED)
17233                         gen_cfg.gate_clk = regk_sser_yes;
17234 -
17235 +               
17236                 break;
17237         case SSP_IPOLARITY:
17238                 /* NOTE!! negedge is considered NORMAL */
17239 @@ -713,12 +786,12 @@
17240                         rec_cfg.clk_pol = regk_sser_neg;
17241                 else if (arg & CLOCK_INVERT)
17242                         rec_cfg.clk_pol = regk_sser_pos;
17243 -
17244 +               
17245                 if (arg & FRAME_NORMAL)
17246                         frm_cfg.level = regk_sser_pos_hi;
17247                 else if (arg & FRAME_INVERT)
17248                         frm_cfg.level = regk_sser_neg_lo;
17249 -
17250 +               
17251                 if (arg & STATUS_NORMAL)
17252                         gen_cfg.hold_pol = regk_sser_pos;
17253                 else if (arg & STATUS_INVERT)
17254 @@ -726,15 +799,15 @@
17255                 break;
17256         case SSP_OPOLARITY:
17257                 if (arg & CLOCK_NORMAL)
17258 -                       gen_cfg.out_clk_pol = regk_sser_neg;
17259 -               else if (arg & CLOCK_INVERT)
17260                         gen_cfg.out_clk_pol = regk_sser_pos;
17261 -
17262 +               else if (arg & CLOCK_INVERT)
17263 +                       gen_cfg.out_clk_pol = regk_sser_neg;
17264 +               
17265                 if (arg & FRAME_NORMAL)
17266                         frm_cfg.level = regk_sser_pos_hi;
17267                 else if (arg & FRAME_INVERT)
17268                         frm_cfg.level = regk_sser_neg_lo;
17269 -
17270 +               
17271                 if (arg & STATUS_NORMAL)
17272                         gen_cfg.hold_pol = regk_sser_pos;
17273                 else if (arg & STATUS_INVERT)
17274 @@ -772,9 +845,10 @@
17275  
17276         if (port->started)
17277         {
17278 -               tr_cfg.tr_en = port->output;
17279                 rec_cfg.rec_en = port->input;
17280 +               gen_cfg.en = (port->output | port->input);
17281         }
17282 +        
17283  
17284         REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17285         REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17286 @@ -782,11 +856,24 @@
17287         REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
17288         REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17289  
17290 +
17291 +       if (cmd == SSP_FRAME_SYNC && 
17292 +           (arg & (WORD_SIZE_8 | WORD_SIZE_12 | WORD_SIZE_16 | WORD_SIZE_24 | WORD_SIZE_32))) {
17293 +               int en = gen_cfg.en;
17294 +               gen_cfg.en = 0;
17295 +               REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17296 +               /* ##### Should DMA be stoped before we change dma size? */
17297 +               DMA_WR_CMD (port->regi_dmain, dma_w_size);
17298 +               DMA_WR_CMD (port->regi_dmaout, dma_w_size);
17299 +               gen_cfg.en = en;
17300 +               REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17301 +       }
17302 +
17303         spin_unlock_irq(&port->lock);
17304         return return_val;
17305  }
17306  
17307 -static ssize_t sync_serial_write(struct file * file, const char * buf,
17308 +static ssize_t sync_serial_write(struct file * file, const char * buf, 
17309                                   size_t count, loff_t *ppos)
17310  {
17311         int dev = iminor(file->f_dentry->d_inode);
17312 @@ -807,7 +894,7 @@
17313  
17314         DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
17315         /* Space to end of buffer */
17316 -       /*
17317 +       /* 
17318          * out_buffer <c1>012345<-   c    ->OUT_BUFFER_SIZE
17319          *            outp^    +out_count
17320                                 ^free_outp
17321 @@ -824,7 +911,7 @@
17322         free_outp = outp + port->out_count;
17323         spin_unlock_irqrestore(&port->lock, flags);
17324         out_buffer = (unsigned long)port->out_buffer;
17325 -
17326 +       
17327         /* Find out where and how much to write */
17328         if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
17329                 free_outp -= OUT_BUFFER_SIZE;
17330 @@ -834,7 +921,7 @@
17331                 c = outp - free_outp;
17332         if (c > count)
17333                 c = count;
17334 -
17335 +       
17336  //     DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c));
17337         if (copy_from_user((void*)free_outp, buf, c))
17338                 return -EFAULT;
17339 @@ -854,13 +941,10 @@
17340         if (!port->started)
17341         {
17342                 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
17343 -               reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17344                 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
17345                 cfg.en = regk_sser_yes;
17346 -               tr_cfg.tr_en = port->output;
17347                 rec_cfg.rec_en = port->input;
17348                 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
17349 -               REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17350                 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17351                 port->started = 1;
17352         }
17353 @@ -887,7 +971,7 @@
17354         }
17355  
17356         /* Sleep until all sent */
17357 -
17358 +       
17359         add_wait_queue(&port->out_wait_q, &wait);
17360         set_current_state(TASK_INTERRUPTIBLE);
17361         spin_lock_irqsave(&port->lock, flags);
17362 @@ -916,13 +1000,13 @@
17363         return count;
17364  }
17365  
17366 -static ssize_t sync_serial_read(struct file * file, char * buf,
17367 +static ssize_t sync_serial_read(struct file * file, char * buf, 
17368                                 size_t count, loff_t *ppos)
17369  {
17370         int dev = iminor(file->f_dentry->d_inode);
17371         int avail;
17372         sync_port *port;
17373 -       unsigned char* start;
17374 +       unsigned char* start; 
17375         unsigned char* end;
17376         unsigned long flags;
17377  
17378 @@ -949,7 +1033,7 @@
17379                 port->started = 1;
17380         }
17381  
17382 -
17383 +       
17384         /* Calculate number of available bytes */
17385         /* Save pointers to avoid that they are modified by interrupt */
17386         spin_lock_irqsave(&port->lock, flags);
17387 @@ -958,11 +1042,12 @@
17388         spin_unlock_irqrestore(&port->lock, flags);
17389         while ((start == end) && !port->full) /* No data */
17390         {
17391 +               DEBUGREAD(printk("&"));
17392                 if (file->f_flags & O_NONBLOCK)
17393 -               {
17394 +               {  
17395                         return -EAGAIN;
17396                 }
17397 -
17398 +          
17399                 interruptible_sleep_on(&port->in_wait_q);
17400                 if (signal_pending(current))
17401                 {
17402 @@ -979,9 +1064,9 @@
17403                 avail = port->in_buffer_size;
17404         else if (end > start)
17405                 avail = end - start;
17406 -       else
17407 +       else 
17408                 avail = port->flip + port->in_buffer_size - start;
17409 -
17410 +  
17411         count = count > avail ? avail : count;
17412         if (copy_to_user(buf, start, count))
17413                 return -EFAULT;
17414 @@ -1016,7 +1101,7 @@
17415                 data |= *port->outp++;
17416                 port->out_count-=2;
17417                 tr_data.data = data;
17418 -               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17419 +               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);  
17420                 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
17421                         port->outp = port->out_buffer;
17422         }
17423 @@ -1032,7 +1117,7 @@
17424         case 24:
17425                 port->out_count-=3;
17426                 tr_data.data = *(unsigned short *)port->outp;
17427 -               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17428 +               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);             
17429                 port->outp+=2;
17430                 tr_data.data = *port->outp++;
17431                 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17432 @@ -1042,10 +1127,10 @@
17433         case 32:
17434                 port->out_count-=4;
17435                 tr_data.data = *(unsigned short *)port->outp;
17436 -               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17437 +               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);             
17438                 port->outp+=2;
17439                 tr_data.data = *(unsigned short *)port->outp;
17440 -               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17441 +               REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);             
17442                 port->outp+=2;
17443                 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
17444                         port->outp = port->out_buffer;
17445 @@ -1056,15 +1141,27 @@
17446  
17447  static void start_dma(struct sync_port* port, const char* data, int count)
17448  {
17449 +       int i;
17450 +       reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17451         port->tr_running = 1;
17452 -       port->out_descr.buf = (char*)virt_to_phys((char*)data);
17453 -       port->out_descr.after = port->out_descr.buf + count;
17454 -       port->out_descr.eol = port->out_descr.intr = 1;
17455 +       for (i = 0; i < NUM_OUT_DESCRS; i++) 
17456 +       {
17457 +               port->out_descr[i].buf = (char*)virt_to_phys(port->out_buffer + 1024*i);
17458 +               port->out_descr[i].after = port->out_descr[i].buf + 1024;
17459 +               port->out_descr[i].eol = 0;
17460 +               port->out_descr[i].intr = 1;
17461 +               port->out_descr[i].next = virt_to_phys(&port->out_descr[i+1]);
17462 +       }
17463 +       port->out_descr[i-1].next = virt_to_phys(&port->out_descr[0]);
17464  
17465 -       port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr);
17466 -       port->out_context.saved_data_buf = port->out_descr.buf;
17467 +       port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr[0]);
17468 +       port->out_context.saved_data_buf = port->out_descr[0].buf;
17469  
17470         DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context));
17471 +
17472 +       tr_cfg.tr_en = regk_sser_yes;
17473 +       REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17474 +
17475         DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
17476  }
17477  
17478 @@ -1073,7 +1170,7 @@
17479         int i;
17480         char* buf;
17481         port->writep = port->flip;
17482 -
17483 +       
17484         if (port->writep > port->flip + port->in_buffer_size)
17485         {
17486                 panic("Offset too large in sync serial driver\n");
17487 @@ -1099,7 +1196,7 @@
17488  }
17489  
17490  #ifdef SYNC_SER_DMA
17491 -static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17492 +static irqreturn_t tr_interrupt(int irq, void *dev_id)
17493  {
17494         reg_dma_r_masked_intr masked;
17495         reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
17496 @@ -1108,7 +1205,7 @@
17497         unsigned int sentl;
17498         int found = 0;
17499  
17500 -       for (i = 0; i < NUMBER_OF_PORTS; i++)
17501 +       for (i = 0; i < NUMBER_OF_PORTS; i++) 
17502         {
17503                 sync_port *port = &ports[i];
17504                 if (!port->enabled  || !port->use_dma )
17505 @@ -1133,18 +1230,21 @@
17506                                 if (c > port->out_count)
17507                                         c = port->out_count;
17508                                 DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c));
17509 -                               start_dma(port, port->outp, c);
17510 +                               //start_dma(port, port->outp, c);
17511                         } else  {
17512 -                               DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
17513 +                               reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17514 +                               DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));                              
17515                                 port->tr_running = 0;
17516 +                               tr_cfg.tr_en = regk_sser_no;
17517 +                               REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17518                         }
17519                         wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
17520 -               }
17521 +               } 
17522         }
17523         return IRQ_RETVAL(found);
17524  } /* tr_interrupt */
17525  
17526 -static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17527 +static irqreturn_t rx_interrupt(int irq, void *dev_id)
17528  {
17529         reg_dma_r_masked_intr masked;
17530         reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
17531 @@ -1152,7 +1252,7 @@
17532         int i;
17533         int found = 0;
17534  
17535 -       for (i = 0; i < NUMBER_OF_PORTS; i++)
17536 +       for (i = 0; i < NUMBER_OF_PORTS; i++) 
17537         {
17538                 sync_port *port = &ports[i];
17539  
17540 @@ -1164,17 +1264,17 @@
17541                 if (masked.data) /* Descriptor interrupt */
17542                 {
17543                         found = 1;
17544 -                       while (REG_RD(dma, port->regi_dmain, rw_data) !=
17545 +                       while (REG_RD(dma, port->regi_dmain, rw_data) != 
17546                                virt_to_phys(port->next_rx_desc)) {
17547 -
17548 +                               DEBUGRXINT(printk("!"));
17549                                 if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
17550                                         int first_size = port->flip + port->in_buffer_size - port->writep;
17551                                         memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size);
17552                                         memcpy(port->flip, phys_to_virt((unsigned)port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
17553                                         port->writep = port->flip + port->inbufchunk - first_size;
17554                                 } else {
17555 -                                       memcpy((char*)port->writep,
17556 -                                              phys_to_virt((unsigned)port->next_rx_desc->buf),
17557 +                                       memcpy((char*)port->writep, 
17558 +                                              phys_to_virt((unsigned)port->next_rx_desc->buf), 
17559                                                port->inbufchunk);
17560                                         port->writep += port->inbufchunk;
17561                                         if (port->writep >= port->flip + port->in_buffer_size)
17562 @@ -1184,11 +1284,13 @@
17563                                  {
17564                                   port->full = 1;
17565                                  }
17566 -
17567 -                               port->next_rx_desc->eol = 0;
17568 -                               port->prev_rx_desc->eol = 1;
17569 -                               port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc);
17570 +                                
17571 +                               port->next_rx_desc->eol = 1;
17572 +                               port->prev_rx_desc->eol = 0;
17573 +                               flush_dma_descr(port->prev_rx_desc,0); // Cache bug workaround
17574 +                               port->prev_rx_desc = port->next_rx_desc;
17575                                 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
17576 +                               flush_dma_descr(port->prev_rx_desc,1); // Cache bug workaround
17577                                 wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
17578                                 DMA_CONTINUE(port->regi_dmain);
17579                                 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
17580 @@ -1201,7 +1303,7 @@
17581  #endif /* SYNC_SER_DMA */
17582  
17583  #ifdef SYNC_SER_MANUAL
17584 -static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17585 +static irqreturn_t manual_interrupt(int irq, void *dev_id)
17586  {
17587         int i;
17588         int found = 0;
17589 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/Makefile
17590 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/Makefile       2007-01-10 20:10:37.000000000 +0100
17591 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/Makefile       2006-12-06 14:17:02.000000000 +0100
17592 @@ -1,4 +1,4 @@
17593 -# $Id: Makefile,v 1.11 2004/12/17 10:16:13 starvik Exp $
17594 +# $Id: Makefile,v 1.13 2006/12/06 13:17:02 starvik Exp $
17595  #
17596  # Makefile for the linux kernel.
17597  #
17598 @@ -8,7 +8,7 @@
17599  
17600  obj-y   := entry.o traps.o irq.o debugport.o dma.o pinmux.o \
17601            process.o ptrace.o setup.o signal.o traps.o time.o \
17602 -          arbiter.o io.o
17603 +          arbiter.o io.o cache.o cacheflush.o
17604  
17605  obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
17606  
17607 @@ -16,6 +16,7 @@
17608  obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
17609  obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
17610  obj-$(CONFIG_MODULES)    += crisksyms.o
17611 +obj-$(CONFIG_CPU_FREQ)   += cpufreq.o
17612  
17613  clean:
17614  
17615 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/arbiter.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/arbiter.c
17616 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/arbiter.c      2007-01-10 20:10:37.000000000 +0100
17617 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/arbiter.c      2006-10-13 14:43:13.000000000 +0200
17618 @@ -6,7 +6,7 @@
17619   * bandwidth (e.g. ethernet) and then the remaining slots are divided
17620   * on all the active clients.
17621   *
17622 - * Copyright (c) 2004, 2005 Axis Communications AB.
17623 + * Copyright (c) 2004, 2005, 2006 Axis Communications AB.
17624   */
17625  
17626  #include <asm/arch/hwregs/reg_map.h>
17627 @@ -44,35 +44,88 @@
17628    {regi_marb_bp3}
17629  };
17630  
17631 -static int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17632 -static int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17633 +static u8 requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17634 +static u8 active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17635  static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH};
17636  
17637  DEFINE_SPINLOCK(arbiter_lock);
17638  
17639 -static irqreturn_t
17640 +static irqreturn_t 
17641  crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs);
17642  
17643 -static void crisv32_arbiter_config(int region)
17644 +/*
17645 + * "I'm the arbiter, I know the score.
17646 + *  From square one I'll be watching all 64."
17647 + * (memory arbiter slots, that is)
17648 + *
17649 + *  Or in other words:
17650 + * Program the memory arbiter slots for "region" according to what's
17651 + * in requested_slots[] and active_clients[], while minimizing
17652 + * latency. A caller may pass a non-zero positive amount for
17653 + * "unused_slots", which must then be the unallocated, remaining
17654 + * number of slots, free to hand out to any client.
17655 + */
17656 +
17657 +static void crisv32_arbiter_config(int region, int unused_slots)
17658  {
17659         int slot;
17660         int client;
17661         int interval = 0;
17662 -       int val[NBR_OF_SLOTS];
17663 +
17664 +       /*
17665 +        * This vector corresponds to the hardware arbiter slots (see
17666 +        * the hardware documentation for semantics). We initialize
17667 +        * each slot with a suitable sentinel value outside the valid
17668 +        * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
17669 +        * client indexes. Then it's fed to the hardware.
17670 +        */
17671 +       s8 val[NBR_OF_SLOTS];
17672  
17673         for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17674 -           val[slot] = NBR_OF_CLIENTS + 1;
17675 +           val[slot] = -1;
17676  
17677         for (client = 0; client < NBR_OF_CLIENTS; client++)
17678         {
17679             int pos;
17680 +           /* Allocate the requested non-zero number of slots, but
17681 +            * also give clients with zero-requests one slot each
17682 +            * while stocks last. We do the latter here, in client
17683 +            * order. This makes sure zero-request clients are the
17684 +            * first to get to any spare slots, else those slots
17685 +            * could, when bandwidth is allocated close to the limit,
17686 +            * all be allocated to low-index non-zero-request clients
17687 +            * in the default-fill loop below. Another positive but
17688 +            * secondary effect is a somewhat better spread of the
17689 +            * zero-bandwidth clients in the vector, avoiding some of
17690 +            * the latency that could otherwise be caused by the
17691 +            * partitioning of non-zero-bandwidth clients at low
17692 +            * indexes and zero-bandwidth clients at high
17693 +            * indexes. (Note that this spreading can only affect the
17694 +            * unallocated bandwidth.)  All the above only matters for
17695 +            * memory-intensive situations, of course.
17696 +            */
17697             if (!requested_slots[region][client])
17698 -              continue;
17699 -           interval = NBR_OF_SLOTS / requested_slots[region][client];
17700 +           {
17701 +               /*
17702 +                * Skip inactive clients. Also skip zero-slot
17703 +                * allocations in this pass when there are no known
17704 +                * free slots.
17705 +                */
17706 +               if (!active_clients[region][client] || unused_slots <= 0)
17707 +                       continue;
17708 +
17709 +               unused_slots--;
17710 +
17711 +               /* Only allocate one slot for this client. */
17712 +               interval = NBR_OF_SLOTS;
17713 +           }
17714 +           else
17715 +               interval = NBR_OF_SLOTS / requested_slots[region][client];
17716 +
17717             pos = 0;
17718             while (pos < NBR_OF_SLOTS)
17719             {
17720 -               if (val[pos] != NBR_OF_CLIENTS + 1)
17721 +               if (val[pos] >= 0)
17722                    pos++;
17723                 else
17724                 {
17725 @@ -85,7 +138,13 @@
17726         client = 0;
17727         for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17728         {
17729 -               if (val[slot] == NBR_OF_CLIENTS + 1)
17730 +               /*
17731 +                * Allocate remaining slots in round-robin
17732 +                * client-number order for active clients. For this
17733 +                * pass, we ignore requested bandwidth and previous
17734 +                * allocations.
17735 +                */
17736 +               if (val[slot] < 0)
17737                 {
17738                         int first = client;
17739                         while(!active_clients[region][client]) {
17740 @@ -100,7 +159,7 @@
17741                    REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, val[slot]);
17742                 else if (region == INT_REGION)
17743                    REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, val[slot]);
17744 -       }
17745 +       }       
17746  }
17747  
17748  extern char _stext, _etext;
17749 @@ -111,18 +170,28 @@
17750  
17751         if (initialized)
17752                 return;
17753 -
17754 +  
17755         initialized = 1;
17756  
17757 -       /* CPU caches are active. */
17758 -       active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
17759 -        crisv32_arbiter_config(EXT_REGION);
17760 -        crisv32_arbiter_config(INT_REGION);
17761 +       /*
17762 +        * CPU caches are always set to active, but with zero
17763 +        * bandwidth allocated. It should be ok to allocate zero
17764 +        * bandwidth for the caches, because DMA for other channels
17765 +        * will supposedly finish, once their programmed amount is
17766 +        * done, and then the caches will get access according to the
17767 +        * "fixed scheme" for unclaimed slots. Though, if for some
17768 +        * use-case somewhere, there's a maximum CPU latency for
17769 +        * e.g. some interrupt, we have to start allocating specific
17770 +        * bandwidth for the CPU caches too.
17771 +        */
17772 +       active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1; 
17773 +        crisv32_arbiter_config(EXT_REGION, 0);
17774 +        crisv32_arbiter_config(INT_REGION, 0);
17775  
17776         if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
17777                          "arbiter", NULL))
17778                 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
17779 -
17780 +        
17781  #ifndef CONFIG_ETRAX_KGDB
17782          /* Global watch for writes to kernel text segment. */
17783          crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
17784 @@ -130,6 +199,7 @@
17785  #endif
17786  }
17787  
17788 +/* Main entry for bandwidth allocation. */
17789  
17790  
17791  int crisv32_arbiter_allocate_bandwidth(int client, int region,
17792 @@ -141,39 +211,76 @@
17793         int req;
17794  
17795         crisv32_arbiter_init();
17796 -
17797 +       
17798         for (i = 0; i < NBR_OF_CLIENTS; i++)
17799         {
17800                 total_assigned += requested_slots[region][i];
17801                 total_clients += active_clients[region][i];
17802         }
17803 -       req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
17804  
17805 -       if (total_assigned + total_clients + req + 1 > NBR_OF_SLOTS)
17806 +       /* Avoid division by 0 for 0-bandwidth requests. */
17807 +       req = bandwidth == 0
17808 +               ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
17809 +
17810 +       /*
17811 +        * We make sure that there are enough slots only for non-zero
17812 +        * requests. Requesting 0 bandwidth *may* allocate slots,
17813 +        * though if all bandwidth is allocated, such a client won't
17814 +        * get any and will have to rely on getting memory access
17815 +        * according to the fixed scheme that's the default when one
17816 +        * of the slot-allocated clients doesn't claim their slot.
17817 +        */
17818 +       if (total_assigned + req > NBR_OF_SLOTS)
17819            return -ENOMEM;
17820  
17821         active_clients[region][client] = 1;
17822         requested_slots[region][client] = req;
17823 -       crisv32_arbiter_config(region);
17824 +       crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
17825  
17826         return 0;
17827  }
17828  
17829 +/*
17830 + * Main entry for bandwidth deallocation.
17831 + *
17832 + * Strictly speaking, for a somewhat constant set of clients where
17833 + * each client gets a constant bandwidth and is just enabled or
17834 + * disabled (somewhat dynamically), no action is necessary here to
17835 + * avoid starvation for non-zero-allocation clients, as the allocated
17836 + * slots will just be unused. However, handing out those unused slots
17837 + * to active clients avoids needless latency if the "fixed scheme"
17838 + * would give unclaimed slots to an eager low-index client.
17839 + */
17840 +
17841 +void crisv32_arbiter_deallocate_bandwidth(int client, int region)
17842 +{
17843 +       int i;
17844 +       int total_assigned = 0;
17845 +
17846 +       requested_slots[region][client] = 0;
17847 +       active_clients[region][client] = 0;
17848 +
17849 +       for (i = 0; i < NBR_OF_CLIENTS; i++)
17850 +               total_assigned += requested_slots[region][i];
17851 +
17852 +       crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
17853 +}
17854 +
17855  int crisv32_arbiter_watch(unsigned long start, unsigned long size,
17856                            unsigned long clients, unsigned long accesses,
17857                            watch_callback* cb)
17858  {
17859         int i;
17860 -
17861 +  
17862         crisv32_arbiter_init();
17863 -
17864 +  
17865         if (start > 0x80000000) {
17866                 printk("Arbiter: %lX doesn't look like a physical address", start);
17867                 return -EFAULT;
17868         }
17869  
17870         spin_lock(&arbiter_lock);
17871 -
17872 +        
17873         for (i = 0; i < NUMBER_OF_BP; i++) {
17874                 if (!watches[i].used) {
17875                         reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
17876 @@ -214,7 +321,7 @@
17877         crisv32_arbiter_init();
17878  
17879         spin_lock(&arbiter_lock);
17880 -
17881 +  
17882         if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
17883                 spin_unlock(&arbiter_lock);
17884                 return -EINVAL;
17885 @@ -239,7 +346,7 @@
17886  
17887  extern void show_registers(struct pt_regs *regs);
17888  
17889 -static irqreturn_t
17890 +static irqreturn_t 
17891  crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs)
17892  {
17893         reg_marb_r_masked_intr masked_intr = REG_RD(marb, regi_marb, r_masked_intr);
17894 @@ -248,10 +355,10 @@
17895         reg_marb_bp_r_brk_op r_op;
17896         reg_marb_bp_r_brk_first_client r_first;
17897         reg_marb_bp_r_brk_size r_size;
17898 -       reg_marb_bp_rw_ack ack = {0};
17899 +       reg_marb_bp_rw_ack ack = {0};  
17900         reg_marb_rw_ack_intr ack_intr = {.bp0=1,.bp1=1,.bp2=1,.bp3=1};
17901         struct crisv32_watch_entry* watch;
17902 -
17903 +  
17904         if (masked_intr.bp0) {
17905                 watch = &watches[0];
17906                 ack_intr.bp0 = regk_marb_yes;
17907 @@ -291,6 +398,6 @@
17908         if (watch->cb)
17909                 watch->cb();
17910  
17911 -
17912 +                        
17913         return IRQ_HANDLED;
17914  }
17915 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/asm-offsets.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/asm-offsets.c
17916 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/asm-offsets.c  2007-01-10 20:10:37.000000000 +0100
17917 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/asm-offsets.c  2003-06-02 10:39:38.000000000 +0200
17918 @@ -16,8 +16,8 @@
17919  {
17920  #define ENTRY(entry) DEFINE(PT_ ## entry, offsetof(struct pt_regs, entry))
17921         ENTRY(orig_r10);
17922 -       ENTRY(r13);
17923 -       ENTRY(r12);
17924 +       ENTRY(r13); 
17925 +       ENTRY(r12); 
17926         ENTRY(r11);
17927          ENTRY(r10);
17928          ENTRY(r9);
17929 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cache.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cache.c
17930 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cache.c        1970-01-01 01:00:00.000000000 +0100
17931 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cache.c        2007-01-23 13:09:57.000000000 +0100
17932 @@ -0,0 +1,31 @@
17933 +#include <linux/module.h>
17934 +#include <asm/io.h>
17935 +#include <asm/arch/cache.h>
17936 +#include <asm/arch/hwregs/dma.h>
17937 +
17938 +// This file is used to workaround a cache bug, Guinness TR 106
17939 +
17940 +inline void flush_dma_descr(dma_descr_data* descr, int flush_buf)
17941 +{
17942 +       // Flush descriptor to make sure we get correct in_eop and after
17943 +       asm volatile ("ftagd [%0]" :: "r" (descr));
17944 +       // Flush buffer pointed out by descriptor
17945 +       if (flush_buf)
17946 +               cris_flush_cache_range(phys_to_virt((unsigned)descr->buf),                                     (unsigned)(descr->after - descr->buf));
17947 +}
17948 +
17949 +void flush_dma_list(dma_descr_data* descr)
17950 +{
17951 +  while(1)
17952 +  {
17953 +    flush_dma_descr(descr, 1);
17954 +    if (descr->eol)
17955 +      break;
17956 +    descr = phys_to_virt((unsigned)descr->next);
17957 +  }
17958 +}
17959 +
17960 +EXPORT_SYMBOL(flush_dma_list);
17961 +EXPORT_SYMBOL(flush_dma_descr);
17962 +EXPORT_SYMBOL(cris_flush_cache);
17963 +EXPORT_SYMBOL(cris_flush_cache_range);
17964 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cacheflush.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cacheflush.S
17965 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cacheflush.S   1970-01-01 01:00:00.000000000 +0100
17966 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cacheflush.S   2006-12-06 14:17:02.000000000 +0100
17967 @@ -0,0 +1,93 @@
17968 +       .global cris_flush_cache_range
17969 +cris_flush_cache_range:
17970 +       move.d 1024, $r12
17971 +       cmp.d $r11, $r12
17972 +       bhi cris_flush_1KB
17973 +       nop
17974 +       add.d $r10, $r11
17975 +cris_flush_last:
17976 +       addq 32, $r10
17977 +       cmp.d $r11, $r10
17978 +       blt cris_flush_last
17979 +       ftagd [$r10]
17980 +       ret
17981 +       nop
17982 +cris_flush_1KB:
17983 +       ftagd [$r10]
17984 +       addq 32, $r10
17985 +       ftagd [$r10]
17986 +       addq 32, $r10
17987 +       ftagd [$r10]
17988 +       addq 32, $r10
17989 +       ftagd [$r10]
17990 +       addq 32, $r10
17991 +       ftagd [$r10]
17992 +       addq 32, $r10
17993 +       ftagd [$r10]
17994 +       addq 32, $r10
17995 +       ftagd [$r10]
17996 +       addq 32, $r10
17997 +       ftagd [$r10]
17998 +       addq 32, $r10
17999 +       ftagd [$r10]
18000 +       addq 32, $r10
18001 +       ftagd [$r10]
18002 +       addq 32, $r10
18003 +       ftagd [$r10]
18004 +       addq 32, $r10
18005 +       ftagd [$r10]
18006 +       addq 32, $r10
18007 +       ftagd [$r10]
18008 +       addq 32, $r10
18009 +       ftagd [$r10]
18010 +       addq 32, $r10
18011 +       ftagd [$r10]
18012 +       addq 32, $r10
18013 +       ftagd [$r10]
18014 +       addq 32, $r10
18015 +       ftagd [$r10]
18016 +       addq 32, $r10
18017 +       ftagd [$r10]
18018 +       addq 32, $r10
18019 +       ftagd [$r10]
18020 +       addq 32, $r10
18021 +       ftagd [$r10]
18022 +       addq 32, $r10
18023 +       ftagd [$r10]
18024 +       addq 32, $r10
18025 +       ftagd [$r10]
18026 +       addq 32, $r10
18027 +       ftagd [$r10]
18028 +       addq 32, $r10
18029 +       ftagd [$r10]
18030 +       addq 32, $r10
18031 +       ftagd [$r10]
18032 +       addq 32, $r10
18033 +       ftagd [$r10]
18034 +       addq 32, $r10
18035 +       ftagd [$r10]
18036 +       addq 32, $r10
18037 +       ftagd [$r10]
18038 +       addq 32, $r10
18039 +       ftagd [$r10]
18040 +       addq 32, $r10
18041 +       ftagd [$r10]
18042 +       addq 32, $r10
18043 +       ftagd [$r10]
18044 +       addq 32, $r10
18045 +       ftagd [$r10]
18046 +       addq 32, $r10
18047 +       ba cris_flush_cache_range
18048 +       sub.d $r12, $r11
18049 +
18050 +       .global cris_flush_cache
18051 +cris_flush_cache:
18052 +       moveq 0, $r10
18053 +cris_flush_line:               
18054 +       move.d 16*1024, $r11
18055 +       addq 16, $r10
18056 +       cmp.d $r10, $r11
18057 +       blt cris_flush_line
18058 +       fidxd [$r10]
18059 +       ret
18060 +       nop     
18061 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cpufreq.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cpufreq.c
18062 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cpufreq.c      1970-01-01 01:00:00.000000000 +0100
18063 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cpufreq.c      2006-11-03 11:35:52.000000000 +0100
18064 @@ -0,0 +1,147 @@
18065 +#include <linux/init.h>
18066 +#include <linux/module.h>
18067 +#include <linux/cpufreq.h>
18068 +#include <asm/arch/hwregs/reg_map.h>
18069 +#include <asm/arch/hwregs/reg_rdwr.h>
18070 +#include <asm/arch/hwregs/config_defs.h>
18071 +#include <asm/arch/hwregs/bif_core_defs.h>
18072 +
18073 +static int
18074 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
18075 +
18076 +static struct notifier_block cris_sdram_freq_notifier_block = {
18077 +        .notifier_call  = cris_sdram_freq_notifier
18078 +};
18079 +
18080 +static struct cpufreq_frequency_table cris_freq_table[] = {
18081 +       {0x01,  6000},
18082 +       {0x02,  200000},
18083 +       {0,     CPUFREQ_TABLE_END},
18084 +};
18085 +
18086 +static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
18087 +{
18088 +       reg_config_rw_clk_ctrl clk_ctrl;
18089 +       clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
18090 +       return clk_ctrl.pll ? 200000 : 6000;
18091 +}
18092 +
18093 +static void cris_freq_set_cpu_state (unsigned int state)
18094 +{
18095 +       int i;
18096 +       struct cpufreq_freqs freqs;
18097 +       reg_config_rw_clk_ctrl clk_ctrl;
18098 +       clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
18099 +
18100 +       for_each_cpu(i) {
18101 +               freqs.old = cris_freq_get_cpu_frequency(i);
18102 +               freqs.new = cris_freq_table[state].frequency;
18103 +               freqs.cpu = i;
18104 +       }
18105 +
18106 +       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
18107
18108 +       local_irq_disable();
18109 +
18110 +       // Even though we may be SMP they will share the same clock
18111 +       // so all settings are made on CPU0.
18112 +       if (cris_freq_table[state].frequency == 200000)
18113 +               clk_ctrl.pll = 1;
18114 +       else
18115 +               clk_ctrl.pll = 0;
18116 +       REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
18117 +
18118 +       local_irq_enable();
18119 +
18120 +       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
18121 +};
18122 +
18123 +static int cris_freq_verify (struct cpufreq_policy *policy)
18124 +{
18125 +       return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
18126 +}
18127 +
18128 +static int cris_freq_target (struct cpufreq_policy *policy,
18129 +                           unsigned int target_freq,
18130 +                           unsigned int relation)
18131 +{
18132 +       unsigned int newstate = 0;
18133 +
18134 +       if (cpufreq_frequency_table_target(policy, cris_freq_table, target_freq, relation, &newstate))
18135 +               return -EINVAL;
18136 +
18137 +       cris_freq_set_cpu_state(newstate);
18138 +
18139 +       return 0;
18140 +}
18141 +
18142 +static int cris_freq_cpu_init(struct cpufreq_policy *policy)
18143 +{
18144 +       int result;
18145 +
18146 +       /* cpuinfo and default policy values */
18147 +       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
18148 +       policy->cpuinfo.transition_latency = 1000000; /* 1ms */
18149 +       policy->cur = cris_freq_get_cpu_frequency(0);
18150 +
18151 +       result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
18152 +       if (result)
18153 +               return (result);
18154 +
18155 +       cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
18156 +
18157 +       return 0;
18158 +}
18159 +
18160 +
18161 +static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
18162 +{
18163 +       cpufreq_frequency_table_put_attr(policy->cpu);
18164 +       return 0;
18165 +}
18166 +
18167 +
18168 +static struct freq_attr* cris_freq_attr[] = {
18169 +       &cpufreq_freq_attr_scaling_available_freqs,
18170 +       NULL,
18171 +};
18172 +
18173 +static struct cpufreq_driver cris_freq_driver = {
18174 +       .get    = cris_freq_get_cpu_frequency,
18175 +       .verify = cris_freq_verify,
18176 +       .target = cris_freq_target,
18177 +       .init   = cris_freq_cpu_init,
18178 +       .exit   = cris_freq_cpu_exit,
18179 +       .name   = "cris_freq",
18180 +       .owner  = THIS_MODULE,
18181 +       .attr   = cris_freq_attr,
18182 +};
18183 +
18184 +static int __init cris_freq_init(void)
18185 +{
18186 +       int ret;
18187 +       ret = cpufreq_register_driver(&cris_freq_driver);
18188 +       cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
18189 +                                  CPUFREQ_TRANSITION_NOTIFIER);
18190 +       return ret;
18191 +}
18192 +
18193 +static int
18194 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
18195 +{
18196 +       int i;
18197 +       struct cpufreq_freqs *freqs = data;
18198 +       if (val == CPUFREQ_PRECHANGE) {
18199 +               reg_bif_core_rw_sdram_timing timing = 
18200 +                 REG_RD(bif_core, regi_bif_core, rw_sdram_timing);
18201 +               timing.cpd = (freqs->new == 200000 ? 0 : 1);
18202 +
18203 +               if (freqs->new == 200000)
18204 +                       for (i = 0; i < 50000; i++);
18205 +               REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
18206 +       }
18207 +        return 0;
18208 +}
18209 +
18210 +
18211 +module_init(cris_freq_init);
18212 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/crisksyms.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/crisksyms.c
18213 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/crisksyms.c    2007-01-10 20:10:37.000000000 +0100
18214 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/crisksyms.c    2006-11-21 04:21:34.000000000 +0100
18215 @@ -3,6 +3,7 @@
18216  #include <asm/arch/dma.h>
18217  #include <asm/arch/intmem.h>
18218  #include <asm/arch/pinmux.h>
18219 +#include <asm/arch/io.h>
18220  
18221  /* Functions for allocating DMA channels */
18222  EXPORT_SYMBOL(crisv32_request_dma);
18223 @@ -16,7 +17,11 @@
18224  
18225  /* Functions for handling pinmux */
18226  EXPORT_SYMBOL(crisv32_pinmux_alloc);
18227 +EXPORT_SYMBOL(crisv32_pinmux_alloc_fixed);
18228  EXPORT_SYMBOL(crisv32_pinmux_dealloc);
18229 +EXPORT_SYMBOL(crisv32_pinmux_dealloc_fixed);
18230 +EXPORT_SYMBOL(crisv32_io_get_name);
18231 +EXPORT_SYMBOL(crisv32_io_get);
18232  
18233  /* Functions masking/unmasking interrupts */
18234  EXPORT_SYMBOL(mask_irq);
18235 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/debugport.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/debugport.c
18236 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/debugport.c    2007-01-10 20:10:37.000000000 +0100
18237 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/debugport.c    2006-10-13 14:43:13.000000000 +0200
18238 @@ -4,18 +4,13 @@
18239  
18240  #include <linux/console.h>
18241  #include <linux/init.h>
18242 -#include <linux/major.h>
18243 -#include <linux/delay.h>
18244 -#include <linux/tty.h>
18245  #include <asm/system.h>
18246 -#include <asm/io.h>
18247 +#include <asm/arch/hwregs/reg_rdwr.h>
18248 +#include <asm/arch/hwregs/reg_map.h>
18249  #include <asm/arch/hwregs/ser_defs.h>
18250  #include <asm/arch/hwregs/dma_defs.h>
18251  #include <asm/arch/pinmux.h>
18252  
18253 -#include <asm/irq.h>
18254 -#include <asm/arch/hwregs/intr_vect_defs.h>
18255 -
18256  struct dbg_port
18257  {
18258         unsigned char nbr;
18259 @@ -26,7 +21,7 @@
18260         unsigned int bits;
18261  };
18262  
18263 -struct dbg_port ports[] =
18264 +struct dbg_port ports[] = 
18265  {
18266    {
18267      0,
18268 @@ -89,15 +84,6 @@
18269  #endif
18270  #endif
18271  
18272 -#ifdef CONFIG_ETRAXFS_SIM
18273 -extern void print_str( const char *str );
18274 -static char buffer[1024];
18275 -static char msg[] = "Debug: ";
18276 -static int buffer_pos = sizeof(msg) - 1;
18277 -#endif
18278 -
18279 -extern struct tty_driver *serial_driver;
18280 -
18281  static void
18282  start_port(struct dbg_port* p)
18283  {
18284 @@ -118,7 +104,7 @@
18285         /* Set up serial port registers */
18286         reg_ser_rw_tr_ctrl tr_ctrl = {0};
18287         reg_ser_rw_tr_dma_en tr_dma_en = {0};
18288 -
18289 +               
18290         reg_ser_rw_rec_ctrl rec_ctrl = {0};
18291         reg_ser_rw_tr_baud_div tr_baud_div = {0};
18292         reg_ser_rw_rec_baud_div rec_baud_div = {0};
18293 @@ -148,6 +134,7 @@
18294                 tr_ctrl.data_bits = regk_ser_bits7;
18295                 rec_ctrl.data_bits = regk_ser_bits7;
18296         }
18297 +       
18298  
18299         REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
18300         REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
18301 @@ -156,124 +143,21 @@
18302         REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
18303  }
18304  
18305 -/* No debug */
18306 -#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
18307 -
18308 -static void
18309 -console_write(struct console *co, const char *buf, unsigned int len)
18310 -{
18311 -       return;
18312 -}
18313 -
18314 -/* Target debug */
18315 -#elif !defined(CONFIG_ETRAXFS_SIM)
18316 -
18317 -static void
18318 -console_write_direct(struct console *co, const char *buf, unsigned int len)
18319 -{
18320 -       int i;
18321 -       reg_ser_r_stat_din stat;
18322 -       reg_ser_rw_tr_dma_en tr_dma_en, old;
18323 -
18324 -       /* Switch to manual mode */
18325 -       tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
18326 -       if (tr_dma_en.en == regk_ser_yes) {
18327 -               tr_dma_en.en = regk_ser_no;
18328 -               REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
18329 -       }
18330 -
18331 -       /* Send data */
18332 -       for (i = 0; i < len; i++) {
18333 -               /* LF -> CRLF */
18334 -               if (buf[i] == '\n') {
18335 -                       do {
18336 -                               stat = REG_RD (ser, port->instance, r_stat_din);
18337 -                       } while (!stat.tr_rdy);
18338 -                       REG_WR_INT (ser, port->instance, rw_dout, '\r');
18339 -               }
18340 -               /* Wait until transmitter is ready and send.*/
18341 -               do {
18342 -                       stat = REG_RD (ser, port->instance, r_stat_din);
18343 -               } while (!stat.tr_rdy);
18344 -               REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
18345 -       }
18346 -
18347 -       /* Restore mode */
18348 -       if (tr_dma_en.en != old.en)
18349 -               REG_WR(ser, port->instance, rw_tr_dma_en, old);
18350 -}
18351 -
18352 -static void
18353 -console_write(struct console *co, const char *buf, unsigned int len)
18354 -{
18355 -       if (!port)
18356 -               return;
18357 -        console_write_direct(co, buf, len);
18358 -}
18359 -
18360 -
18361 -
18362 -#else
18363 -
18364 -/* VCS debug */
18365 -
18366 -static void
18367 -console_write(struct console *co, const char *buf, unsigned int len)
18368 -{
18369 -       char* pos;
18370 -       pos = memchr(buf, '\n', len);
18371 -       if (pos) {
18372 -               int l = ++pos - buf;
18373 -               memcpy(buffer + buffer_pos, buf, l);
18374 -               memcpy(buffer, msg, sizeof(msg) - 1);
18375 -               buffer[buffer_pos + l] = '\0';
18376 -               print_str(buffer);
18377 -               buffer_pos = sizeof(msg) - 1;
18378 -               if (pos - buf != len) {
18379 -                       memcpy(buffer + buffer_pos, pos, len - l);
18380 -                       buffer_pos += len - l;
18381 -               }
18382 -       } else {
18383 -               memcpy(buffer + buffer_pos, buf, len);
18384 -               buffer_pos += len;
18385 -       }
18386 -}
18387 -
18388 -#endif
18389 -
18390 -int raw_printk(const char *fmt, ...)
18391 -{
18392 -       static char buf[1024];
18393 -       int printed_len;
18394 -       va_list args;
18395 -       va_start(args, fmt);
18396 -       printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
18397 -       va_end(args);
18398 -       console_write(NULL, buf, strlen(buf));
18399 -       return printed_len;
18400 -}
18401 -
18402 -void
18403 -stupid_debug(char* buf)
18404 -{
18405 -  console_write(NULL, buf, strlen(buf));
18406 -}
18407 -
18408  #ifdef CONFIG_ETRAX_KGDB
18409  /* Use polling to get a single character from the kernel debug port */
18410  int
18411  getDebugChar(void)
18412  {
18413 -       reg_ser_rs_status_data stat;
18414 +       reg_ser_rs_stat_din stat;
18415         reg_ser_rw_ack_intr ack_intr = { 0 };
18416  
18417         do {
18418 -               stat = REG_RD(ser, kgdb_instance, rs_status_data);
18419 -       } while (!stat.data_avail);
18420 +               stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
18421 +       } while (!stat.dav);
18422  
18423         /* Ack the data_avail interrupt. */
18424 -       ack_intr.data_avail = 1;
18425 -       REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
18426 +       ack_intr.dav = 1;
18427 +       REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
18428  
18429         return stat.data;
18430  }
18431 @@ -282,173 +166,18 @@
18432  void
18433  putDebugChar(int val)
18434  {
18435 -       reg_ser_r_status_data stat;
18436 +       reg_ser_r_stat_din stat;
18437         do {
18438 -               stat = REG_RD (ser, kgdb_instance, r_status_data);
18439 -       } while (!stat.tr_ready);
18440 -       REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
18441 +               stat = REG_RD (ser, kgdb_port->instance, r_stat_din);
18442 +       } while (!stat.tr_rdy);
18443 +       REG_WR_INT (ser, kgdb_port->instance, rw_dout, val);
18444  }
18445  #endif /* CONFIG_ETRAX_KGDB */
18446  
18447 -static int __init
18448 -console_setup(struct console *co, char *options)
18449 -{
18450 -       char* s;
18451 -
18452 -       if (options) {
18453 -               port = &ports[co->index];
18454 -               port->baudrate = 115200;
18455 -               port->parity = 'N';
18456 -               port->bits = 8;
18457 -               port->baudrate = simple_strtoul(options, NULL, 10);
18458 -               s = options;
18459 -               while(*s >= '0' && *s <= '9')
18460 -                       s++;
18461 -               if (*s) port->parity = *s++;
18462 -               if (*s) port->bits   = *s++ - '0';
18463 -               port->started = 0;
18464 -               start_port(port);
18465 -       }
18466 -       return 0;
18467 -}
18468 -
18469 -/* This is a dummy serial device that throws away anything written to it.
18470 - * This is used when no debug output is wanted.
18471 - */
18472 -static struct tty_driver dummy_driver;
18473 -
18474 -static int dummy_open(struct tty_struct *tty, struct file * filp)
18475 -{
18476 -       return 0;
18477 -}
18478 -
18479 -static void dummy_close(struct tty_struct *tty, struct file * filp)
18480 -{
18481 -}
18482 -
18483 -static int dummy_write(struct tty_struct * tty,
18484 -                       const unsigned char *buf, int count)
18485 -{
18486 -       return count;
18487 -}
18488 -
18489 -static int
18490 -dummy_write_room(struct tty_struct *tty)
18491 -{
18492 -       return 8192;
18493 -}
18494 -
18495 -void __init
18496 -init_dummy_console(void)
18497 -{
18498 -       memset(&dummy_driver, 0, sizeof(struct tty_driver));
18499 -       dummy_driver.driver_name = "serial";
18500 -       dummy_driver.name = "ttyS";
18501 -       dummy_driver.major = TTY_MAJOR;
18502 -       dummy_driver.minor_start = 68;
18503 -       dummy_driver.num = 1;       /* etrax100 has 4 serial ports */
18504 -       dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
18505 -       dummy_driver.subtype = SERIAL_TYPE_NORMAL;
18506 -       dummy_driver.init_termios = tty_std_termios;
18507 -       dummy_driver.init_termios.c_cflag =
18508 -               B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
18509 -       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
18510 -
18511 -       dummy_driver.open = dummy_open;
18512 -       dummy_driver.close = dummy_close;
18513 -       dummy_driver.write = dummy_write;
18514 -       dummy_driver.write_room = dummy_write_room;
18515 -       if (tty_register_driver(&dummy_driver))
18516 -               panic("Couldn't register dummy serial driver\n");
18517 -}
18518 -
18519 -static struct tty_driver*
18520 -crisv32_console_device(struct console* co, int *index)
18521 -{
18522 -       if (port)
18523 -               *index = port->nbr;
18524 -        return port ? serial_driver : &dummy_driver;
18525 -}
18526 -
18527 -static struct console sercons = {
18528 -       name : "ttyS",
18529 -       write: console_write,
18530 -       read : NULL,
18531 -       device : crisv32_console_device,
18532 -       unblank : NULL,
18533 -       setup : console_setup,
18534 -       flags : CON_PRINTBUFFER,
18535 -       index : -1,
18536 -       cflag : 0,
18537 -       next : NULL
18538 -};
18539 -static struct console sercons0 = {
18540 -       name : "ttyS",
18541 -       write: console_write,
18542 -       read : NULL,
18543 -       device : crisv32_console_device,
18544 -       unblank : NULL,
18545 -       setup : console_setup,
18546 -       flags : CON_PRINTBUFFER,
18547 -       index : 0,
18548 -       cflag : 0,
18549 -       next : NULL
18550 -};
18551 -
18552 -static struct console sercons1 = {
18553 -       name : "ttyS",
18554 -       write: console_write,
18555 -       read : NULL,
18556 -       device : crisv32_console_device,
18557 -       unblank : NULL,
18558 -       setup : console_setup,
18559 -       flags : CON_PRINTBUFFER,
18560 -       index : 1,
18561 -       cflag : 0,
18562 -       next : NULL
18563 -};
18564 -static struct console sercons2 = {
18565 -       name : "ttyS",
18566 -       write: console_write,
18567 -       read : NULL,
18568 -       device : crisv32_console_device,
18569 -       unblank : NULL,
18570 -       setup : console_setup,
18571 -       flags : CON_PRINTBUFFER,
18572 -       index : 2,
18573 -       cflag : 0,
18574 -       next : NULL
18575 -};
18576 -static struct console sercons3 = {
18577 -       name : "ttyS",
18578 -       write: console_write,
18579 -       read : NULL,
18580 -       device : crisv32_console_device,
18581 -       unblank : NULL,
18582 -       setup : console_setup,
18583 -       flags : CON_PRINTBUFFER,
18584 -       index : 3,
18585 -       cflag : 0,
18586 -       next : NULL
18587 -};
18588 -
18589  /* Register console for printk's, etc. */
18590  int __init
18591  init_etrax_debug(void)
18592  {
18593 -       static int first = 1;
18594 -
18595 -       if (!first) {
18596 -               unregister_console(&sercons);
18597 -               register_console(&sercons0);
18598 -               register_console(&sercons1);
18599 -               register_console(&sercons2);
18600 -               register_console(&sercons3);
18601 -               init_dummy_console();
18602 -               return 0;
18603 -       }
18604 -       first = 0;
18605 -        register_console(&sercons);
18606          start_port(port);
18607  
18608  #ifdef CONFIG_ETRAX_KGDB
18609 @@ -456,5 +185,3 @@
18610  #endif /* CONFIG_ETRAX_KGDB */
18611         return 0;
18612  }
18613 -
18614 -__initcall(init_etrax_debug);
18615 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/dma.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/dma.c
18616 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/dma.c  2007-01-10 20:10:37.000000000 +0100
18617 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/dma.c  2007-02-02 08:45:22.000000000 +0100
18618 @@ -12,6 +12,16 @@
18619  #include <asm/system.h>
18620  #include <asm/arch/arbiter.h>
18621  
18622 +/*
18623 + * The memory region we allocated bandwidth for is stored in
18624 + * used_dma_channels as an in-use flag.
18625 + */
18626 +enum dma_region_allocated_marker {
18627 +  DMA_NO_REGION_ALLOCATED = 0,
18628 +  DMA_INT_REGION_ALLOCATED = 1,
18629 +  DMA_EXT_REGION_ALLOCATED = 2
18630 +};
18631 +
18632  static char used_dma_channels[MAX_DMA_CHANNELS];
18633  static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
18634  
18635 @@ -74,7 +84,7 @@
18636                 if (options & DMA_VERBOSE_ON_ERROR) {
18637                         printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1);
18638                 }
18639 -
18640 +               
18641                 if (options & DMA_PANIC_ON_ERROR)
18642                         panic("request_dma error!");
18643                 return -EINVAL;
18644 @@ -202,13 +212,14 @@
18645                 if (dmanr == 3)
18646                         strmux_cfg.dma3 = regk_strmux_ext3;
18647                 else if (dmanr == 9)
18648 -                       strmux_cfg.dma9 = regk_strmux_ext2;
18649 +                       strmux_cfg.dma9 = regk_strmux_ext3;
18650                 else
18651 -                       panic("Invalid DMA channel for ext2\n");
18652 +                       panic("Invalid DMA channel for ext3\n");
18653                 break;
18654         }
18655  
18656 -       used_dma_channels[dmanr] = 1;
18657 +       used_dma_channels[dmanr] = options & DMA_INT_MEM
18658 +               ? DMA_INT_REGION_ALLOCATED : DMA_EXT_REGION_ALLOCATED;
18659         used_dma_channels_users[dmanr] = device_id;
18660         REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
18661         REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
18662 @@ -218,7 +229,12 @@
18663  
18664  void crisv32_free_dma(unsigned int dmanr)
18665  {
18666 +       int region;
18667 +
18668         spin_lock(&dma_lock);
18669 +       region = used_dma_channels[dmanr] == DMA_INT_REGION_ALLOCATED
18670 +               ? INT_REGION : EXT_REGION;
18671         used_dma_channels[dmanr] = 0;
18672 +       crisv32_arbiter_deallocate_bandwidth(dmanr, region);
18673         spin_unlock(&dma_lock);
18674  }
18675 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/entry.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/entry.S
18676 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/entry.S        2007-01-10 20:10:37.000000000 +0100
18677 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/entry.S        2007-01-09 10:29:19.000000000 +0100
18678 @@ -11,7 +11,7 @@
18679   *
18680   * Stack layout in 'ret_from_system_call':
18681   *     ptrace needs to have all regs on the stack.
18682 - *     if the order here is changed, it needs to be
18683 + *     if the order here is changed, it needs to be 
18684   *     updated in fork.c:copy_process, signal.c:do_signal,
18685   *     ptrace.c and ptrace.h
18686   *
18687 @@ -40,7 +40,7 @@
18688         .globl sys_call_table
18689  
18690         ; Check if preemptive kernel scheduling should be done.
18691 -#ifdef CONFIG_PREEMPT
18692 +#ifdef CONFIG_PREEMPT  
18693  _resume_kernel:
18694         di
18695         ; Load current task struct.
18696 @@ -81,7 +81,7 @@
18697         nop
18698         ba  ret_from_sys_call
18699         nop
18700 -
18701 +               
18702  ret_from_intr:
18703         ;; Check for resched if preemptive kernel, or if we're going back to
18704         ;; user-mode. This test matches the user_regs(regs) macro. Don't simply
18705 @@ -93,7 +93,7 @@
18706         bpl     _resume_kernel
18707  
18708         ; Note that di below is in delay slot.
18709 -
18710 +       
18711  _resume_userspace:
18712         di                      ; So need_resched and sigpending don't change.
18713  
18714 @@ -107,19 +107,19 @@
18715         nop
18716         ba      _Rexit
18717         nop
18718 -
18719 +       
18720         ;; The system_call is called by a BREAK instruction, which looks pretty
18721         ;; much like any other exception.
18722         ;;
18723         ;; System calls can't be made from interrupts but we still stack ERP
18724         ;; to have a complete stack frame.
18725 -       ;;
18726 +       ;; 
18727         ;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,
18728         ;; r13,mof,srp
18729         ;;
18730         ;; This function looks on the _surface_ like spaghetti programming, but it's
18731 -       ;; really designed so that the fast-path does not force cache-loading of
18732 -       ;; non-used instructions. Only the non-common cases cause the outlined code
18733 +       ;; really designed so that the fast-path does not force cache-loading of 
18734 +       ;; non-used instructions. Only the non-common cases cause the outlined code 
18735         ;; to run..
18736  
18737  system_call:
18738 @@ -151,7 +151,7 @@
18739         or.d (1<<9), $r0
18740         move $r0, $ccs
18741  #endif
18742 -
18743 +       
18744         movs.w  -ENOSYS, $r0
18745         addoq   +PT_r10, $sp, $acr
18746         move.d  $r0, [$acr]
18747 @@ -166,9 +166,9 @@
18748         bmi     _syscall_trace_entry
18749         nop
18750  
18751 -_syscall_traced:
18752 +_syscall_traced:       
18753         ;; Check for sanity in the requested syscall number.
18754 -       cmpu.w  NR_syscalls, $r9
18755 +       cmpu.w  NR_syscalls, $r9        
18756         bhs     ret_from_sys_call
18757         lslq    2, $r9          ;  Multiply by 4, in the delay slot.
18758  
18759 @@ -177,7 +177,7 @@
18760         move.d  $sp, $r0
18761         subq    4, $sp
18762         move.d  $r0, [$sp]
18763 -
18764 +       
18765         ;; The registers carrying parameters (R10-R13) are intact. The optional
18766         ;; fifth and sixth parameters is in MOF and SRP respectivly. Put them
18767         ;; back on the stack.
18768 @@ -185,33 +185,33 @@
18769         move    $srp, [$sp]
18770         subq    4, $sp
18771         move    $mof, [$sp]
18772 -
18773 +       
18774         ;; Actually to the system call.
18775         addo.d  +sys_call_table, $r9, $acr
18776         move.d  [$acr], $acr
18777         jsr     $acr
18778         nop
18779 -
18780 +       
18781         addq    3*4, $sp                ; Pop the mof, srp and regs parameters.
18782         addoq   +PT_r10, $sp, $acr
18783         move.d  $r10, [$acr]            ; Save the return value.
18784  
18785 -       moveq   1, $r9                  ; "Parameter" to ret_from_sys_call to
18786 +       moveq   1, $r9                  ; "Parameter" to ret_from_sys_call to 
18787                                         ; show it was a sys call.
18788 -
18789 +       
18790         ;; Fall through into ret_from_sys_call to return.
18791 -
18792 +       
18793  ret_from_sys_call:
18794         ;; R9 is a parameter:
18795         ;;  >= 1 from syscall
18796         ;;     0 from irq
18797 -
18798 +               
18799         ;; Get the current task-struct pointer.
18800 -       movs.w  -8192, $r0      ; THREAD_SIZE == 8192
18801 +       movs.w  -8192, $r0      ; THREAD_SIZE == 8192 
18802         and.d   $sp, $r0
18803  
18804         di              ; Make sure need_resched and sigpending don't change.
18805 -
18806 +       
18807         addoq   +TI_flags, $r0, $acr
18808         move.d  [$acr], $r1
18809         and.d   _TIF_ALLWORK_MASK, $r1
18810 @@ -253,14 +253,14 @@
18811         move.d  $r1, $r9
18812         ba      _resume_userspace
18813         nop
18814 -
18815 +       
18816  _work_pending:
18817         addoq   +TI_flags, $r0, $acr
18818         move.d  [$acr], $r10
18819         btstq   TIF_NEED_RESCHED, $r10  ; Need resched?
18820         bpl     _work_notifysig         ; No, must be signal/notify.
18821         nop
18822 -
18823 +       
18824  _work_resched:
18825         move.d  $r9, $r1                ; Preserve R9.
18826         jsr     schedule
18827 @@ -281,28 +281,26 @@
18828         ;; Deal with pending signals and notify-resume requests.
18829  
18830         addoq   +TI_flags, $r0, $acr
18831 -       move.d  [$acr], $r13            ; The thread_info_flags parameter.
18832 -       move.d  $r9, $r10               ; do_notify_resume syscall/irq param.
18833 -       moveq   0, $r11                 ; oldset param - 0 in this case.
18834 -       move.d  $sp, $r12               ; The regs param.
18835 +       move.d  [$acr], $r12            ; The thread_info_flags parameter.
18836 +       move.d  $sp, $r11               ; The regs param.
18837         jsr     do_notify_resume
18838 -       nop
18839 -
18840 +       move.d  $r9, $r10               ; do_notify_resume syscall/irq param.
18841 +       
18842         ba _Rexit
18843         nop
18844  
18845         ;; We get here as a sidetrack when we've entered a syscall with the
18846         ;; trace-bit set. We need to call do_syscall_trace and then continue
18847         ;; with the call.
18848 -
18849 +       
18850  _syscall_trace_entry:
18851         ;; PT_r10 in the frame contains -ENOSYS as required, at this point.
18852 -
18853 +       
18854         jsr     do_syscall_trace
18855         nop
18856  
18857         ;; Now re-enter the syscall code to do the syscall itself. We need to
18858 -       ;; restore R9 here to contain the wanted syscall, and the other
18859 +       ;; restore R9 here to contain the wanted syscall, and the other 
18860         ;; parameter-bearing registers.
18861         addoq   +PT_r9, $sp, $acr
18862         move.d  [$acr], $r9
18863 @@ -318,10 +316,10 @@
18864         move    [$acr], $mof
18865         addoq   +PT_srp, $sp, $acr
18866         move    [$acr], $srp
18867 -
18868 +       
18869         ba      _syscall_traced
18870         nop
18871 -
18872 +       
18873         ;; Resume performs the actual task-switching, by switching stack
18874         ;; pointers. Input arguments are:
18875         ;;
18876 @@ -331,7 +329,7 @@
18877         ;;
18878         ;; Returns old current in R10.
18879  
18880 -resume:
18881 +resume:        
18882         subq    4, $sp
18883         move    $srp, [$sp]             ; Keep old/new PC on the stack.
18884         add.d   $r12, $r10              ; R10 = current tasks tss.
18885 @@ -341,14 +339,14 @@
18886  
18887         addoq   +THREAD_usp, $r10, $acr
18888         move    $usp, [$acr]            ; Save user-mode stackpointer.
18889 -
18890 +       
18891         ;; See copy_thread for the reason why register R9 is saved.
18892         subq    10*4, $sp
18893         movem   $r9, [$sp]              ; Save non-scratch registers and R9.
18894 -
18895 +       
18896         addoq   +THREAD_ksp, $r10, $acr
18897         move.d  $sp, [$acr]             ; Save kernel SP for old task.
18898 -
18899 +       
18900         move.d  $sp, $r10               ; Return last running task in R10.
18901         and.d   -8192, $r10             ; Get thread_info from stackpointer.
18902         addoq   +TI_task, $r10, $acr
18903 @@ -360,7 +358,7 @@
18904  
18905         addoq   +THREAD_usp, $r11, $acr
18906         move    [$acr], $usp            ; Restore user-mode stackpointer.
18907 -
18908 +       
18909         addoq   +THREAD_ccs, $r11, $acr
18910         move    [$acr], $ccs            ; Restore IRQ enable status.
18911         move.d  [$sp+], $acr
18912 @@ -407,7 +405,7 @@
18913         movem   [$sp+], $r13
18914         move.d  [$sp+], $acr
18915         move    [$sp], $srs
18916 -       addq    4, $sp
18917 +       addq    4, $sp 
18918         move    [$sp+], $mof
18919         move    [$sp+], $spc
18920         move    [$sp+], $ccs
18921 @@ -419,7 +417,7 @@
18922  
18923         .comm   cause_of_death, 4       ;; Don't declare this anywhere.
18924  
18925 -spurious_interrupt:
18926 +spurious_interrupt:    
18927         di
18928         jump hard_reset_now
18929         nop
18930 @@ -494,31 +492,38 @@
18931         ;; thread_info as first parameter
18932         move.d  $r9, $r10
18933         moveq   5, $r11                 ; SIGTRAP as second argument.
18934 -       jsr     ugdb_trap_user
18935 +       jsr     ugdb_trap_user       
18936         nop
18937         jump    ret_from_intr           ; Use the return routine for interrupts.
18938         nop
18939 -
18940 -gdb_handle_exception:
18941 +       
18942 +gdb_handle_exception:  
18943         subq    4, $sp
18944         move.d  $r0, [$sp]
18945  #ifdef CONFIG_ETRAX_KGDB
18946 -       move    $ccs, $r0               ; U-flag not affected by previous insns.
18947 +       move    $ccs, $r0               ; U-flag not affected by previous insns. 
18948         btstq   16, $r0                 ; Test the U-flag.
18949 -       bmi     _ugdb_handle_exception  ; Go to user mode debugging.
18950 -       nop                             ; Empty delay-slot (cannot pop R0 here).
18951 +       bmi     _ugdb_handle_exception  ; Go to user mode debugging. 
18952 +       nop                             ; Empty delay-slot (cannot pop R0 here). 
18953         ba      kgdb_handle_exception   ; Go to kernel debugging.
18954         move.d  [$sp+], $r0             ; Restore R0 in delay slot.
18955  #endif
18956 -
18957 +       
18958  _ugdb_handle_exception:
18959         ba      do_sigtrap              ; SIGTRAP the offending process.
18960         move.d  [$sp+], $r0             ; Restore R0 in delay slot.
18961  
18962 +       .global kernel_execve
18963 +kernel_execve:
18964 +       move.d __NR_execve, $r9
18965 +       break 13
18966 +       ret
18967 +       nop
18968 +               
18969         .data
18970  
18971         .section .rodata,"a"
18972 -sys_call_table:
18973 +sys_call_table:        
18974         .long sys_restart_syscall       ; 0 - old "setup()" system call, used
18975                                         ; for restarting.
18976         .long sys_exit
18977 @@ -647,7 +652,7 @@
18978         .long sys_adjtimex
18979         .long sys_mprotect      /* 125 */
18980         .long sys_sigprocmask
18981 -       .long sys_ni_syscall    /* old "create_module" */
18982 +       .long sys_ni_syscall    /* old "create_module" */ 
18983         .long sys_init_module
18984         .long sys_delete_module
18985         .long sys_ni_syscall    /* 130: old "get_kernel_syms" */
18986 @@ -789,7 +794,7 @@
18987         .long sys_clock_getres
18988         .long sys_clock_nanosleep
18989         .long sys_statfs64
18990 -       .long sys_fstatfs64
18991 +       .long sys_fstatfs64     
18992         .long sys_tgkill        /* 270 */
18993         .long sys_utimes
18994         .long sys_fadvise64_64
18995 @@ -805,7 +810,43 @@
18996         .long sys_mq_getsetattr
18997         .long sys_ni_syscall            /* reserved for kexec */
18998         .long sys_waitid
18999 -
19000 +       .long sys_ni_syscall            /* 285 */ /* available */
19001 +       .long sys_add_key
19002 +       .long sys_request_key
19003 +       .long sys_keyctl
19004 +       .long sys_ioprio_set
19005 +       .long sys_ioprio_get            /* 290 */
19006 +       .long sys_inotify_init
19007 +       .long sys_inotify_add_watch
19008 +       .long sys_inotify_rm_watch
19009 +       .long sys_migrate_pages
19010 +       .long sys_openat                /* 295 */
19011 +       .long sys_mkdirat
19012 +       .long sys_mknodat
19013 +       .long sys_fchownat
19014 +       .long sys_futimesat
19015 +       .long sys_fstatat64             /* 300 */
19016 +       .long sys_unlinkat
19017 +       .long sys_renameat
19018 +       .long sys_linkat
19019 +       .long sys_symlinkat
19020 +       .long sys_readlinkat            /* 305 */
19021 +       .long sys_fchmodat
19022 +       .long sys_faccessat
19023 +       .long sys_pselect6
19024 +       .long sys_ppoll
19025 +       .long sys_unshare               /* 310 */
19026 +       .long sys_set_robust_list 
19027 +       .long sys_set_robust_list
19028 +       .long sys_get_robust_list
19029 +       .long sys_splice
19030 +       .long sys_sync_file_range
19031 +       .long sys_tee                   /* 315 */
19032 +       .long sys_vmsplice
19033 +       .long sys_move_pages
19034 +       .long sys_getcpu
19035 +       .long sys_epoll_pwait
19036 +                       
19037          /*
19038           * NOTE!! This doesn't have to be exact - we just have
19039           * to make sure we have _enough_ of the "sys_ni_syscall"
19040 @@ -816,4 +857,4 @@
19041         .rept NR_syscalls - (.-sys_call_table) / 4
19042                 .long sys_ni_syscall
19043         .endr
19044 -
19045 +       
19046 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/fasttimer.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/fasttimer.c
19047 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/fasttimer.c    2007-01-10 20:10:37.000000000 +0100
19048 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/fasttimer.c    2007-01-09 10:29:19.000000000 +0100
19049 @@ -1,110 +1,10 @@
19050 -/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $
19051 +/*
19052   * linux/arch/cris/kernel/fasttimer.c
19053   *
19054   * Fast timers for ETRAX FS
19055   * This may be useful in other OS than Linux so use 2 space indentation...
19056   *
19057 - * $Log: fasttimer.c,v $
19058 - * Revision 1.11  2005/01/04 11:15:46  starvik
19059 - * Don't share timer IRQ.
19060 - *
19061 - * Revision 1.10  2004/12/07 09:19:38  starvik
19062 - * Corrected includes.
19063 - * Use correct interrupt macros.
19064 - *
19065 - * Revision 1.9  2004/05/14 10:18:58  starvik
19066 - * Export fast_timer_list
19067 - *
19068 - * Revision 1.8  2004/05/14 07:58:03  starvik
19069 - * Merge of changes from 2.4
19070 - *
19071 - * Revision 1.7  2003/07/10 12:06:14  starvik
19072 - * Return IRQ_NONE if irq wasn't handled
19073 - *
19074 - * Revision 1.6  2003/07/04 08:27:49  starvik
19075 - * Merge of Linux 2.5.74
19076 - *
19077 - * Revision 1.5  2003/06/05 10:16:22  johana
19078 - * New INTR_VECT macros.
19079 - *
19080 - * Revision 1.4  2003/06/03 08:49:45  johana
19081 - * Fixed typo.
19082 - *
19083 - * Revision 1.3  2003/06/02 12:51:27  johana
19084 - * Now compiles.
19085 - * Commented some include files that probably can be removed.
19086 - *
19087 - * Revision 1.2  2003/06/02 12:09:41  johana
19088 - * Ported to ETRAX FS using the trig interrupt instead of timer1.
19089 - *
19090 - * Revision 1.3  2002/12/12 08:26:32  starvik
19091 - * Don't use C-comments inside CVS comments
19092 - *
19093 - * Revision 1.2  2002/12/11 15:42:02  starvik
19094 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
19095 - *
19096 - * Revision 1.1  2002/11/18 07:58:06  starvik
19097 - * Fast timers (from Linux 2.4)
19098 - *
19099 - * Revision 1.5  2002/10/15 06:21:39  starvik
19100 - * Added call to init_waitqueue_head
19101 - *
19102 - * Revision 1.4  2002/05/28 17:47:59  johana
19103 - * Added del_fast_timer()
19104 - *
19105 - * Revision 1.3  2002/05/28 16:16:07  johana
19106 - * Handle empty fast_timer_list
19107 - *
19108 - * Revision 1.2  2002/05/27 15:38:42  johana
19109 - * Made it compile without warnings on Linux 2.4.
19110 - * (includes, wait_queue, PROC_FS and snprintf)
19111 - *
19112 - * Revision 1.1  2002/05/27 15:32:25  johana
19113 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
19114 - *
19115 - * Revision 1.8  2001/11/27 13:50:40  pkj
19116 - * Disable interrupts while stopping the timer and while modifying the
19117 - * list of active timers in timer1_handler() as it may be interrupted
19118 - * by other interrupts (e.g., the serial interrupt) which may add fast
19119 - * timers.
19120 - *
19121 - * Revision 1.7  2001/11/22 11:50:32  pkj
19122 - * * Only store information about the last 16 timers.
19123 - * * proc_fasttimer_read() now uses an allocated buffer, since it
19124 - *   requires more space than just a page even for only writing the
19125 - *   last 16 timers. The buffer is only allocated on request, so
19126 - *   unless /proc/fasttimer is read, it is never allocated.
19127 - * * Renamed fast_timer_started to fast_timers_started to match
19128 - *   fast_timers_added and fast_timers_expired.
19129 - * * Some clean-up.
19130 - *
19131 - * Revision 1.6  2000/12/13 14:02:08  johana
19132 - * Removed volatile for fast_timer_list
19133 - *
19134 - * Revision 1.5  2000/12/13 13:55:35  johana
19135 - * Added DEBUG_LOG, added som cli() and cleanup
19136 - *
19137 - * Revision 1.4  2000/12/05 13:48:50  johana
19138 - * Added range check when writing proc file, modified timer int handling
19139 - *
19140 - * Revision 1.3  2000/11/23 10:10:20  johana
19141 - * More debug/logging possibilities.
19142 - * Moved GET_JIFFIES_USEC() to timex.h and time.c
19143 - *
19144 - * Revision 1.2  2000/11/01 13:41:04  johana
19145 - * Clean up and bugfixes.
19146 - * Created new do_gettimeofday_fast() that gets a timeval struct
19147 - * with time based on jiffies and *R_TIMER0_DATA, uses a table
19148 - * for fast conversion of timer value to microseconds.
19149 - * (Much faster the standard do_gettimeofday() and we don't really
19150 - * wan't to use the true time - we wan't the "uptime" so timers don't screw up
19151 - * when we change the time.
19152 - * TODO: Add efficient support for continuous timers as well.
19153 - *
19154 - * Revision 1.1  2000/10/26 15:49:16  johana
19155 - * Added fasttimer, highresolution timers.
19156 - *
19157 - * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
19158 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
19159   */
19160  
19161  #include <linux/errno.h>
19162 @@ -128,13 +28,13 @@
19163  #include <asm/fasttimer.h>
19164  #include <linux/proc_fs.h>
19165  
19166 -/*
19167 - * timer0 is running at 100MHz and generating jiffies timer ticks
19168 +/* 
19169 + * timer0 is running at 100MHz and generating jiffies timer ticks 
19170   * at 100 or 1000 HZ.
19171   * fasttimer gives an API that gives timers that expire "between" the jiffies
19172   * giving microsecond resolution (10 ns).
19173   * fasttimer uses reg_timer_rw_trig register to get interrupt when
19174 - * r_time reaches a certain value.
19175 + * r_time reaches a certain value. 
19176   */
19177  
19178  
19179 @@ -151,19 +51,19 @@
19180  #define SANITYCHECK(x)
19181  #endif
19182  
19183 -#define D1(x)
19184 -#define D2(x)
19185 -#define DP(x)
19186 +#define D1(x) 
19187 +#define D2(x) 
19188 +#define DP(x) 
19189  
19190  #define __INLINE__ inline
19191  
19192 -static int fast_timer_running = 0;
19193 -static int fast_timers_added = 0;
19194 -static int fast_timers_started = 0;
19195 -static int fast_timers_expired = 0;
19196 -static int fast_timers_deleted = 0;
19197 -static int fast_timer_is_init = 0;
19198 -static int fast_timer_ints = 0;
19199 +static unsigned int fast_timer_running = 0;
19200 +static unsigned int fast_timers_added = 0;
19201 +static unsigned int fast_timers_started = 0;
19202 +static unsigned int fast_timers_expired = 0;
19203 +static unsigned int fast_timers_deleted = 0;
19204 +static unsigned int fast_timer_is_init = 0;
19205 +static unsigned int fast_timer_ints = 0;
19206  
19207  struct fast_timer *fast_timer_list = NULL;
19208  
19209 @@ -171,8 +71,8 @@
19210  #define DEBUG_LOG_MAX 128
19211  static const char * debug_log_string[DEBUG_LOG_MAX];
19212  static unsigned long debug_log_value[DEBUG_LOG_MAX];
19213 -static int debug_log_cnt = 0;
19214 -static int debug_log_cnt_wrapped = 0;
19215 +static unsigned int debug_log_cnt = 0;
19216 +static unsigned int debug_log_cnt_wrapped = 0;
19217  
19218  #define DEBUG_LOG(string, value) \
19219  { \
19220 @@ -202,48 +102,33 @@
19221  int timer_div_settings[NUM_TIMER_STATS];
19222  int timer_delay_settings[NUM_TIMER_STATS];
19223  
19224 +struct work_struct fast_work;
19225  
19226  static void
19227 -timer_trig_handler(void);
19228 +timer_trig_handler(void* dummy);
19229  
19230  
19231  
19232  /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
19233 -void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
19234 +void __INLINE__ do_gettimeofday_fast(struct fasttime_t *tv)
19235  {
19236 -  unsigned long sec = jiffies;
19237 -  unsigned long usec = GET_JIFFIES_USEC();
19238 -
19239 -  usec += (sec % HZ) * (1000000 / HZ);
19240 -  sec = sec / HZ;
19241 -
19242 -  if (usec > 1000000)
19243 -  {
19244 -    usec -= 1000000;
19245 -    sec++;
19246 -  }
19247 -  tv->tv_sec = sec;
19248 -  tv->tv_usec = usec;
19249 +  tv->tv_jiff = jiffies;
19250 +  tv->tv_usec = GET_JIFFIES_USEC();
19251  }
19252  
19253 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
19254 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
19255  {
19256 -  if (t0->tv_sec < t1->tv_sec)
19257 -  {
19258 +  /* Compare jiffies. Takes care of wrapping */
19259 +  if (time_before(t0->tv_jiff, t1->tv_jiff))
19260      return -1;
19261 -  }
19262 -  else if (t0->tv_sec > t1->tv_sec)
19263 -  {
19264 +  else if (time_after(t0->tv_jiff, t1->tv_jiff))
19265      return 1;
19266 -  }
19267 +
19268 +  /* Compare us */
19269    if (t0->tv_usec < t1->tv_usec)
19270 -  {
19271      return -1;
19272 -  }
19273    else if (t0->tv_usec > t1->tv_usec)
19274 -  {
19275      return 1;
19276 -  }
19277    return 0;
19278  }
19279  
19280 @@ -254,20 +139,23 @@
19281    reg_timer_rw_intr_mask intr_mask;
19282    reg_timer_rw_trig trig;
19283    reg_timer_rw_trig_cfg trig_cfg = { 0 };
19284 -  reg_timer_r_time r_time;
19285 -
19286 -  r_time = REG_RD(timer, regi_timer, r_time);
19287 +  reg_timer_r_time r_time0;
19288 +  reg_timer_r_time r_time1;
19289 +  unsigned char trig_wrap;
19290 +  unsigned char time_wrap;
19291  
19292 +  r_time0 = REG_RD(timer, regi_timer, r_time);
19293 +  
19294    D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
19295              delay_us, freq_index, div));
19296    /* Clear trig irq */
19297    intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
19298    intr_mask.trig = 0;
19299    REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
19300 -
19301 -  /* Set timer values */
19302 +  
19303 +  /* Set timer values and check if trigger wraps. */
19304    /* r_time is 100MHz (10 ns resolution) */
19305 -  trig = r_time + delay_us*(1000/10);
19306 +  trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;
19307  
19308    timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
19309    timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
19310 @@ -275,15 +163,17 @@
19311    /* Ack interrupt */
19312    ack_intr.trig = 1;
19313    REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
19314 -
19315 +  
19316    /* Start timer */
19317    REG_WR(timer, regi_timer, rw_trig, trig);
19318    trig_cfg.tmr = regk_timer_time;
19319    REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
19320  
19321    /* Check if we have already passed the trig time */
19322 -  r_time = REG_RD(timer, regi_timer, r_time);
19323 -  if (r_time < trig) {
19324 +  r_time1 = REG_RD(timer, regi_timer, r_time);
19325 +  time_wrap = r_time1 < r_time0;
19326 +
19327 +  if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
19328      /* No, Enable trig irq */
19329      intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
19330      intr_mask.trig = 1;
19331 @@ -291,16 +181,17 @@
19332      fast_timers_started++;
19333      fast_timer_running = 1;
19334    }
19335 -  else
19336 +  else 
19337    {
19338      /* We have passed the time, disable trig point, ack intr */
19339      trig_cfg.tmr = regk_timer_off;
19340      REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
19341      REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
19342 -    /* call the int routine directly */
19343 -    timer_trig_handler();
19344 +    /* call the int routine */
19345 +    INIT_WORK(&fast_work, timer_trig_handler, (void*)NULL);
19346 +    schedule_work(&fast_work);
19347    }
19348 -
19349 +  
19350  }
19351  
19352  /* In version 1.4 this function takes 27 - 50 us */
19353 @@ -327,7 +218,7 @@
19354        {
19355          printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
19356          sanity_failed++;
19357 -        return;
19358 +        goto done;
19359        }
19360        else
19361        {
19362 @@ -343,11 +234,11 @@
19363    t->name = name;
19364  
19365    t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
19366 -  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
19367 +  t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
19368    if (t->tv_expires.tv_usec > 1000000)
19369    {
19370      t->tv_expires.tv_usec -= 1000000;
19371 -    t->tv_expires.tv_sec++;
19372 +    t->tv_expires.tv_jiff += HZ;
19373    }
19374  #ifdef FAST_TIMER_LOG
19375    timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
19376 @@ -388,6 +279,7 @@
19377  
19378    D2(printk("start_one_shot_timer: %d us done\n", delay_us));
19379  
19380 +done:
19381    local_irq_restore(flags);
19382  } /* start_one_shot_timer */
19383  
19384 @@ -431,26 +323,32 @@
19385  /* Timer interrupt handler for trig interrupts */
19386  
19387  static irqreturn_t
19388 -timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
19389 +timer_trig_interrupt(int irq, void *dev_id)
19390  {
19391    reg_timer_r_masked_intr masked_intr;
19392 -
19393    /* Check if the timer interrupt is for us (a trig int) */
19394    masked_intr = REG_RD(timer, regi_timer, r_masked_intr);
19395    if (!masked_intr.trig)
19396      return IRQ_NONE;
19397 -  timer_trig_handler();
19398 +  timer_trig_handler(NULL);
19399    return IRQ_HANDLED;
19400  }
19401  
19402 -static void timer_trig_handler(void)
19403 +static void timer_trig_handler(void* dummy) 
19404  {
19405    reg_timer_rw_ack_intr ack_intr = { 0 };
19406    reg_timer_rw_intr_mask intr_mask;
19407    reg_timer_rw_trig_cfg trig_cfg = { 0 };
19408    struct fast_timer *t;
19409 -  unsigned long flags;
19410 +  unsigned long flags;  
19411  
19412 +  /* We keep interrupts disabled not only when we modify the 
19413 +   * fast timer list, but any time we hold a reference to a
19414 +   * timer in the list, since del_fast_timer may be called
19415 +   * from (another) interrupt context.  Thus, the only time
19416 +   * when interrupts are enabled is when calling the timer
19417 +   * callback function.
19418 +   */
19419    local_irq_save(flags);
19420  
19421    /* Clear timer trig interrupt */
19422 @@ -470,16 +368,17 @@
19423    fast_timer_running = 0;
19424    fast_timer_ints++;
19425  
19426 -  local_irq_restore(flags);
19427 +  fast_timer_function_type *f;
19428 +  unsigned long d;
19429  
19430    t = fast_timer_list;
19431    while (t)
19432    {
19433 -    struct timeval tv;
19434 +    struct fasttime_t tv;
19435  
19436      /* Has it really expired? */
19437      do_gettimeofday_fast(&tv);
19438 -    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
19439 +    D1(printk("t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
19440  
19441      if (timeval_cmp(&t->tv_expires, &tv) <= 0)
19442      {
19443 @@ -490,7 +389,6 @@
19444        fast_timers_expired++;
19445  
19446        /* Remove this timer before call, since it may reuse the timer */
19447 -      local_irq_save(flags);
19448        if (t->prev)
19449        {
19450          t->prev->next = t->next;
19451 @@ -505,11 +403,21 @@
19452        }
19453        t->prev = NULL;
19454        t->next = NULL;
19455 -      local_irq_restore(flags);
19456  
19457 -      if (t->function != NULL)
19458 +      /* Save function callback data before enabling interrupts,
19459 +       * since the timer may be removed and we don't know how it
19460 +       * was allocated (e.g. ->function and ->data may become
19461 +       * overwritten after deletion if the timer was stack-allocated).
19462 +       */
19463 +      f = t->function;
19464 +      d = t->data;
19465 +
19466 +      if (f != NULL)
19467        {
19468 -        t->function(t->data);
19469 +        /* Run the callback function with interrupts enabled. */
19470 +        local_irq_restore(flags);
19471 +        f(d);
19472 +        local_irq_save(flags);
19473        }
19474        else
19475        {
19476 @@ -522,16 +430,19 @@
19477        D1(printk(".\n"));
19478      }
19479  
19480 -    local_irq_save(flags);
19481      if ((t = fast_timer_list) != NULL)
19482      {
19483        /* Start next timer.. */
19484 -      long us;
19485 -      struct timeval tv;
19486 +      long us = 0;
19487 +      struct fasttime_t tv;
19488  
19489        do_gettimeofday_fast(&tv);
19490 -      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
19491 -            t->tv_expires.tv_usec - tv.tv_usec);
19492 +
19493 +      /* time_after_eq takes care of wrapping */
19494 +      if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
19495 +       us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ +
19496 +             t->tv_expires.tv_usec - tv.tv_usec);
19497 +
19498        if (us > 0)
19499        {
19500          if (!fast_timer_running)
19501 @@ -541,7 +452,6 @@
19502  #endif
19503            start_timer_trig(us);
19504          }
19505 -        local_irq_restore(flags);
19506          break;
19507        }
19508        else
19509 @@ -552,9 +462,10 @@
19510          D1(printk("e! %d\n", us));
19511        }
19512      }
19513 -    local_irq_restore(flags);
19514    }
19515  
19516 +  local_irq_restore(flags);
19517 +
19518    if (!t)
19519    {
19520      D1(printk("ttrig stop!\n"));
19521 @@ -577,28 +488,17 @@
19522  void schedule_usleep(unsigned long us)
19523  {
19524    struct fast_timer t;
19525 -#ifdef DECLARE_WAITQUEUE
19526    wait_queue_head_t sleep_wait;
19527    init_waitqueue_head(&sleep_wait);
19528 -  {
19529 -  DECLARE_WAITQUEUE(wait, current);
19530 -#else
19531 -  struct wait_queue *sleep_wait = NULL;
19532 -  struct wait_queue wait = { current, NULL };
19533 -#endif
19534  
19535    D1(printk("schedule_usleep(%d)\n", us));
19536 -  add_wait_queue(&sleep_wait, &wait);
19537 -  set_current_state(TASK_INTERRUPTIBLE);
19538    start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
19539                         "usleep");
19540 -  schedule();
19541 -  set_current_state(TASK_RUNNING);
19542 -  remove_wait_queue(&sleep_wait, &wait);
19543 +  /* Uninterruptible sleep on the fast timer. (The condition is somewhat
19544 +     redundant since the timer is what wakes us up.) */
19545 +  wait_event(sleep_wait, !fast_timer_pending(&t));
19546 +
19547    D1(printk("done schedule_usleep(%d)\n", us));
19548 -#ifdef DECLARE_WAITQUEUE
19549 -  }
19550 -#endif
19551  }
19552  
19553  #ifdef CONFIG_PROC_FS
19554 @@ -638,7 +538,7 @@
19555    unsigned long flags;
19556    int i = 0;
19557    int num_to_show;
19558 -  struct timeval tv;
19559 +  struct fasttime_t tv;
19560    struct fast_timer *t, *nextt;
19561    static char *bigbuf = NULL;
19562    static unsigned long used;
19563 @@ -646,7 +546,8 @@
19564    if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
19565    {
19566      used = 0;
19567 -    bigbuf[0] = '\0';
19568 +    if (buf)
19569 +           buf[0] = '\0';
19570      return 0;
19571    }
19572  
19573 @@ -668,7 +569,7 @@
19574      used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
19575                      fast_timer_running ? "yes" : "no");
19576      used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
19577 -                    (unsigned long)tv.tv_sec,
19578 +                    (unsigned long)tv.tv_jiff,
19579                      (unsigned long)tv.tv_usec);
19580  #ifdef FAST_TIMER_SANITY_CHECKS
19581      used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
19582 @@ -717,9 +618,9 @@
19583                        "d: %6li us data: 0x%08lX"
19584                        "\n",
19585                        t->name,
19586 -                      (unsigned long)t->tv_set.tv_sec,
19587 +                      (unsigned long)t->tv_set.tv_jiff,
19588                        (unsigned long)t->tv_set.tv_usec,
19589 -                      (unsigned long)t->tv_expires.tv_sec,
19590 +                      (unsigned long)t->tv_expires.tv_jiff,
19591                        (unsigned long)t->tv_expires.tv_usec,
19592                        t->delay_us,
19593                        t->data
19594 @@ -739,9 +640,9 @@
19595                        "d: %6li us data: 0x%08lX"
19596                        "\n",
19597                        t->name,
19598 -                      (unsigned long)t->tv_set.tv_sec,
19599 +                      (unsigned long)t->tv_set.tv_jiff,
19600                        (unsigned long)t->tv_set.tv_usec,
19601 -                      (unsigned long)t->tv_expires.tv_sec,
19602 +                      (unsigned long)t->tv_expires.tv_jiff,
19603                        (unsigned long)t->tv_expires.tv_usec,
19604                        t->delay_us,
19605                        t->data
19606 @@ -759,9 +660,9 @@
19607                        "d: %6li us data: 0x%08lX"
19608                        "\n",
19609                        t->name,
19610 -                      (unsigned long)t->tv_set.tv_sec,
19611 +                      (unsigned long)t->tv_set.tv_jiff,
19612                        (unsigned long)t->tv_set.tv_usec,
19613 -                      (unsigned long)t->tv_expires.tv_sec,
19614 +                      (unsigned long)t->tv_expires.tv_jiff,
19615                        (unsigned long)t->tv_expires.tv_usec,
19616                        t->delay_us,
19617                        t->data
19618 @@ -772,7 +673,6 @@
19619  
19620      used += sprintf(bigbuf + used, "Active timers:\n");
19621      local_irq_save(flags);
19622 -    local_irq_save(flags);
19623      t = fast_timer_list;
19624      while (t != NULL && (used+100 < BIG_BUF_SIZE))
19625      {
19626 @@ -783,15 +683,15 @@
19627  /*                      " func: 0x%08lX" */
19628                        "\n",
19629                        t->name,
19630 -                      (unsigned long)t->tv_set.tv_sec,
19631 +                      (unsigned long)t->tv_set.tv_jiff,
19632                        (unsigned long)t->tv_set.tv_usec,
19633 -                      (unsigned long)t->tv_expires.tv_sec,
19634 +                      (unsigned long)t->tv_expires.tv_jiff,
19635                        (unsigned long)t->tv_expires.tv_usec,
19636                        t->delay_us,
19637                        t->data
19638  /*                      , t->function */
19639                        );
19640 -      local_irq_disable();
19641 +      local_irq_save(flags);
19642        if (t->next != nextt)
19643        {
19644          printk("timer removed!\n");
19645 @@ -822,7 +722,7 @@
19646  static struct fast_timer tr[10];
19647  static int exp_num[10];
19648  
19649 -static struct timeval tv_exp[100];
19650 +static struct fasttime_t tv_exp[100];
19651  
19652  static void test_timeout(unsigned long data)
19653  {
19654 @@ -860,7 +760,7 @@
19655    int prev_num;
19656    int j;
19657  
19658 -  struct timeval tv, tv0, tv1, tv2;
19659 +  struct fasttime_t tv, tv0, tv1, tv2;
19660  
19661    printk("fast_timer_test() start\n");
19662    do_gettimeofday_fast(&tv);
19663 @@ -873,7 +773,7 @@
19664    {
19665      do_gettimeofday_fast(&tv_exp[j]);
19666    }
19667 -  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
19668 +  printk("fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
19669  
19670    for (j = 0; j < 1000; j++)
19671    {
19672 @@ -883,11 +783,11 @@
19673    for (j = 0; j < 100; j++)
19674    {
19675      printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
19676 -           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
19677 -           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
19678 -           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
19679 -           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
19680 -           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
19681 +           tv_exp[j].tv_jiff,tv_exp[j].tv_usec,
19682 +           tv_exp[j+1].tv_jiff,tv_exp[j+1].tv_usec,
19683 +           tv_exp[j+2].tv_jiff,tv_exp[j+2].tv_usec,
19684 +           tv_exp[j+3].tv_jiff,tv_exp[j+3].tv_usec,
19685 +           tv_exp[j+4].tv_jiff,tv_exp[j+4].tv_usec);
19686      j += 4;
19687    }
19688    do_gettimeofday_fast(&tv0);
19689 @@ -919,9 +819,9 @@
19690      }
19691    }
19692    do_gettimeofday_fast(&tv2);
19693 -  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
19694 -  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
19695 -  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
19696 +  printk("Timers started    %is %06i\n", tv0.tv_jiff, tv0.tv_usec);
19697 +  printk("Timers started at %is %06i\n", tv1.tv_jiff, tv1.tv_usec);
19698 +  printk("Timers done       %is %06i\n", tv2.tv_jiff, tv2.tv_usec);
19699    DP(printk("buf0:\n");
19700       printk(buf0);
19701       printk("buf1:\n");
19702 @@ -943,9 +843,9 @@
19703      printk("%-10s set: %6is %06ius exp: %6is %06ius "
19704             "data: 0x%08X func: 0x%08X\n",
19705             t->name,
19706 -           t->tv_set.tv_sec,
19707 +           t->tv_set.tv_jiff,
19708             t->tv_set.tv_usec,
19709 -           t->tv_expires.tv_sec,
19710 +           t->tv_expires.tv_jiff,
19711             t->tv_expires.tv_usec,
19712             t->data,
19713             t->function
19714 @@ -953,10 +853,10 @@
19715  
19716      printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
19717             t->delay_us,
19718 -           tv_exp[j].tv_sec,
19719 +           tv_exp[j].tv_jiff,
19720             tv_exp[j].tv_usec,
19721             exp_num[j],
19722 -           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
19723 +           (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
19724    }
19725    proc_fasttimer_read(buf5, NULL, 0, 0, 0);
19726    printk("buf5 after all done:\n");
19727 @@ -966,7 +866,7 @@
19728  #endif
19729  
19730  
19731 -void fast_timer_init(void)
19732 +int fast_timer_init(void)
19733  {
19734    /* For some reason, request_irq() hangs when called froom time_init() */
19735    if (!fast_timer_is_init)
19736 @@ -981,10 +881,10 @@
19737      proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
19738  #endif
19739  #endif /* PROC_FS */
19740 -    if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED,
19741 -                   "fast timer int", NULL))
19742 +    if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, SA_SHIRQ | SA_INTERRUPT,
19743 +                   "fast timer int", &fast_timer_list))
19744      {
19745 -      printk("err: timer1 irq\n");
19746 +      printk("err: fasttimer irq\n");
19747      }
19748      fast_timer_is_init = 1;
19749  #ifdef FAST_TIMER_TEST
19750 @@ -992,4 +892,6 @@
19751      fast_timer_test();
19752  #endif
19753    }
19754 +  return 0;
19755  }
19756 +__initcall(fast_timer_init);
19757 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/head.S
19758 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/head.S 2007-01-10 20:10:37.000000000 +0100
19759 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/head.S 2007-01-09 10:29:19.000000000 +0100
19760 @@ -4,7 +4,6 @@
19761   * Copyright (C) 2003, Axis Communications AB
19762   */
19763  
19764 -
19765  #define ASSEMBLER_MACROS_ONLY
19766  
19767  /*
19768 @@ -12,14 +11,21 @@
19769   * -traditional must not be used when assembling this file.
19770   */
19771  #include <asm/arch/hwregs/reg_rdwr.h>
19772 +#include <asm/arch/memmap.h>   
19773 +#include <asm/arch/hwregs/intr_vect.h>
19774  #include <asm/arch/hwregs/asm/mmu_defs_asm.h>
19775  #include <asm/arch/hwregs/asm/reg_map_asm.h>
19776  #include <asm/arch/hwregs/asm/config_defs_asm.h>
19777  #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
19778 -
19779 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
19780 +#include <asm/arch/hwregs/asm/gio_defs_asm.h>
19781 +                       
19782  #define CRAMFS_MAGIC 0x28cd3d45
19783 +#define JHEAD_MAGIC 0x1FF528A6
19784 +#define JHEAD_SIZE 8
19785  #define RAM_INIT_MAGIC 0x56902387
19786 -#define COMMAND_LINE_MAGIC 0x87109563
19787 +#define COMMAND_LINE_MAGIC 0x87109563  
19788 +#define NAND_BOOT_MAGIC 0x9a9db001
19789  
19790         ;; NOTE: R8 and R9 carry information from the decompressor (if the
19791         ;; kernel was compressed). They must not be used in the code below
19792 @@ -30,11 +36,10 @@
19793         .global romfs_start
19794         .global romfs_length
19795         .global romfs_in_flash
19796 +       .global nand_boot
19797         .global swapper_pg_dir
19798 -       .global crisv32_nand_boot
19799 -       .global crisv32_nand_cramfs_offset
19800  
19801 -       ;; Dummy section to make it bootable with current VCS simulator
19802 +       ;; Dummy section to make it bootable with current VCS simulator 
19803  #ifdef CONFIG_ETRAXFS_SIM
19804         .section ".boot", "ax"
19805         ba tstart
19806 @@ -42,13 +47,13 @@
19807  #endif
19808  
19809         .text
19810 -tstart:
19811 +tstart:         
19812         ;; This is the entry point of the kernel. The CPU is currently in
19813         ;; supervisor mode.
19814 -       ;;
19815 +       ;; 
19816         ;; 0x00000000 if flash.
19817         ;; 0x40004000 if DRAM.
19818 -       ;;
19819 +       ;; 
19820         di
19821  
19822         ;; Start clocks for used blocks.
19823 @@ -72,20 +77,25 @@
19824         move.d   REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
19825         move.d   CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
19826         move.d   $r1, [$r0]
19827 -
19828 -#ifdef CONFIG_ETRAXFS_SIM
19829 +       
19830 +#ifdef CONFIG_ETRAXFS_SIM      
19831         ;; Set up minimal flash waitstates
19832         move.d 0, $r10
19833         move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
19834         move.d $r10, [$r11]
19835 -#endif
19836 +#endif 
19837  
19838 +#ifdef CONFIG_SMP      
19839 +secondary_cpu_entry: /* Entry point for secondary CPUs */
19840 +       di
19841 +#endif 
19842 +               
19843         ;; Setup and enable the MMU. Use same configuration for both the data
19844         ;; and the instruction MMU.
19845         ;;
19846         ;; Note; 3 cycles is needed for a bank-select to take effect. Further;
19847         ;; bank 1 is the instruction MMU, bank 2 is the data MMU.
19848 -#ifndef CONFIG_ETRAXFS_SIM
19849 +#ifndef CONFIG_ETRAXFS_SIM     
19850         move.d  REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8)       \
19851                 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4)     \
19852                 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
19853 @@ -96,7 +106,7 @@
19854                 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0)     \
19855                 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb)   \
19856                 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
19857 -#endif
19858 +#endif 
19859  
19860         ;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00.
19861         move.d  REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 4)  \
19862 @@ -146,8 +156,8 @@
19863                 | REG_STATE(mmu, rw_mm_cfg, seg_2, page)        \
19864                 | REG_STATE(mmu, rw_mm_cfg, seg_1, page)        \
19865                 | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
19866 -#endif
19867 -
19868 +#endif 
19869 +       
19870         ;; Update instruction MMU.
19871         move    1, $srs
19872         nop
19873 @@ -165,7 +175,7 @@
19874         move    $r0, $s2        ; kbase_hi.
19875         move    $r1, $s1        ; kbase_lo
19876         move    $r2, $s0        ; mm_cfg, virtual memory configuration.
19877 -
19878 +       
19879         ;; Enable data and instruction MMU.
19880         move    0, $srs
19881         moveq   0xf, $r0        ;  IMMU, DMMU, DCache, Icache on
19882 @@ -183,17 +193,11 @@
19883         nop
19884         nop
19885         nop
19886 -       move    $s10, $r0
19887 +       move    $s12, $r0
19888         cmpq    0, $r0
19889         beq     master_cpu
19890         nop
19891  slave_cpu:
19892 -       ; A slave waits for cpu_now_booting to be equal to CPU ID.
19893 -       move.d  cpu_now_booting, $r1
19894 -slave_wait:
19895 -       cmp.d   [$r1], $r0
19896 -       bne     slave_wait
19897 -       nop
19898         ; Time to boot-up. Get stack location provided by master CPU.
19899         move.d  smp_init_current_idle_thread, $r1
19900         move.d  [$r1], $sp
19901 @@ -203,9 +207,16 @@
19902         jsr     smp_callin
19903         nop
19904  master_cpu:
19905 -#endif
19906 +       /* Set up entry point for secondary CPUs. The boot ROM has set up
19907 +        * EBP at start of internal memory. The CPU will get there
19908 +        * later when we issue an IPI to them... */
19909 +       move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0
19910 +       move.d secondary_cpu_entry, $r1
19911 +       move.d $r1, [$r0]
19912 +#endif 
19913  #ifndef CONFIG_ETRAXFS_SIM
19914 -       ;; Check if starting from DRAM or flash.
19915 +       ; Check if starting from DRAM (network->RAM boot or unpacked 
19916 +       ; compressed kernel), or directly from flash.
19917         lapcq   ., $r0
19918         and.d   0x7fffffff, $r0 ; Mask off the non-cache bit.
19919         cmp.d   0x10000, $r0    ; Arbitrary, something above this code.
19920 @@ -238,6 +249,7 @@
19921         ;; Copy the text and data section to DRAM. This depends on that the
19922         ;; variables used below are correctly set up by the linker script.
19923         ;; The calculated value stored in R4 is used below.
19924 +       ;; Leave the cramfs file system (piggybacked after the kernel) in flash.
19925         moveq   0, $r0          ; Source.
19926         move.d  text_start, $r1 ; Destination.
19927         move.d  __vmlinux_end, $r2
19928 @@ -249,7 +261,7 @@
19929         blo     1b
19930         nop
19931  
19932 -       ;; Keep CRAMFS in flash.
19933 +       ;; Check for cramfs.
19934         moveq   0, $r0
19935         move.d  romfs_length, $r1
19936         move.d  $r0, [$r1]
19937 @@ -257,7 +269,8 @@
19938         cmp.d   CRAMFS_MAGIC, $r0
19939         bne 1f
19940         nop
19941 -
19942 +       
19943 +       ;; Set length and start of cramfs, set romfs_in_flash flag
19944         addoq   +4, $r4, $acr
19945         move.d  [$acr], $r0
19946         move.d  romfs_length, $r1
19947 @@ -273,35 +286,32 @@
19948         nop
19949  
19950  _inram:
19951 -       ;; Check if booting from NAND flash (in that case we just remember the offset
19952 -       ;; into the flash where cramfs should be).
19953 -       move.d  REG_ADDR(config, regi_config, r_bootsel), $r0
19954 -       move.d  [$r0], $r0
19955 -       and.d   REG_MASK(config, r_bootsel, boot_mode), $r0
19956 -       cmp.d   REG_STATE(config, r_bootsel, boot_mode, nand), $r0
19957 -       bne     move_cramfs
19958 -       moveq   1,$r0
19959 -       move.d  crisv32_nand_boot, $r1
19960 -       move.d  $r0, [$r1]
19961 -       move.d  crisv32_nand_cramfs_offset, $r1
19962 -       move.d  $r9, [$r1]
19963 +       ;; Check if booting from NAND flash; if so, set appropriate flags
19964 +       ;; and move on.
19965 +       cmp.d   NAND_BOOT_MAGIC, $r12
19966 +       bne     move_cramfs     ; not nand, jump
19967         moveq   1, $r0
19968 -       move.d  romfs_in_flash, $r1
19969 +       move.d  nand_boot, $r1  ; tell axisflashmap we're booting from NAND
19970 +       move.d  $r0, [$r1]
19971 +       moveq   0, $r0          ; tell axisflashmap romfs is not in 
19972 +       move.d  romfs_in_flash, $r1 ; (directly accessed) flash
19973         move.d  $r0, [$r1]
19974 -       jump    _start_it
19975 +       jump    _start_it       ; continue with boot
19976         nop
19977  
19978 -move_cramfs:
19979 -       ;; Move the cramfs after BSS.
19980 +move_cramfs:           
19981 +       ;; kernel is in DRAM.
19982 +       ;; Must figure out if there is a piggybacked rootfs image or not.
19983 +       ;; Set romfs_length to 0 => no rootfs image available by default.
19984         moveq   0, $r0
19985         move.d  romfs_length, $r1
19986         move.d  $r0, [$r1]
19987  
19988 -#ifndef CONFIG_ETRAXFS_SIM
19989 +#ifndef CONFIG_ETRAXFS_SIM             
19990         ;; The kernel could have been unpacked to DRAM by the loader, but
19991 -       ;; the cramfs image could still be inte the flash immediately
19992 -       ;; following the compressed kernel image. The loaded passes the address
19993 -       ;; of the bute succeeding the last compressed byte in the flash in
19994 +       ;; the cramfs image could still be in the flash immediately
19995 +       ;; following the compressed kernel image. The loader passes the address
19996 +       ;; of the byte succeeding the last compressed byte in the flash in
19997         ;; register R9 when starting the kernel.
19998         cmp.d   0x0ffffff8, $r9
19999         bhs     _no_romfs_in_flash ; R9 points outside the flash area.
20000 @@ -309,12 +319,14 @@
20001  #else
20002         ba _no_romfs_in_flash
20003         nop
20004 -#endif
20005 +#endif 
20006 +       ;; cramfs rootfs might to be in flash. Check for it.
20007         move.d  [$r9], $r0      ; cramfs_super.magic
20008         cmp.d   CRAMFS_MAGIC, $r0
20009         bne     _no_romfs_in_flash
20010         nop
20011  
20012 +       ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
20013         addoq   +4, $r9, $acr
20014         move.d  [$acr], $r0
20015         move.d  romfs_length, $r1
20016 @@ -330,29 +342,45 @@
20017         nop
20018  
20019  _no_romfs_in_flash:
20020 -       ;; Look for cramfs.
20021 -#ifndef CONFIG_ETRAXFS_SIM
20022 +       ;; No romfs in flash, so look for cramfs, or jffs2 with jhead, 
20023 +       ;; after kernel in RAM, as is the case with network->RAM boot.
20024 +       ;; For cramfs, partition starts with magic and length.
20025 +       ;; For jffs2, a jhead is prepended which contains with magic and length.
20026 +       ;; The jhead is not part of the jffs2 partition however.
20027 +#ifndef CONFIG_ETRAXFS_SIM             
20028         move.d  __vmlinux_end, $r0
20029  #else
20030 -       move.d  __end, $r0
20031 -#endif
20032 +       move.d  __end, $r0      
20033 +#endif 
20034         move.d  [$r0], $r1
20035 -       cmp.d   CRAMFS_MAGIC, $r1
20036 -       bne     2f
20037 +       cmp.d   CRAMFS_MAGIC, $r1 ; cramfs magic?
20038 +       beq     2f                ; yes, jump
20039 +       nop
20040 +       cmp.d   JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
20041 +       bne     4f              ; no, skip copy
20042 +       nop
20043 +       addq    4, $r0          ; location of jffs2 size
20044 +       move.d  [$r0+], $r2     ; fetch jffs2 size -> r2
20045 +                               ; r0 now points to start of jffs2
20046 +       ba      3f
20047         nop
20048 +2:
20049 +       addoq   +4, $r0, $acr   ; location of cramfs size
20050 +       move.d  [$acr], $r2     ; fetch cramfs size -> r2
20051 +                               ; r0 still points to start of cramfs
20052 +3:
20053 +       ;; Now, move the root fs to after kernel's BSS
20054  
20055 -       addoq   +4, $r0, $acr
20056 -       move.d  [$acr], $r2
20057 -       move.d  _end, $r1
20058 +       move.d  _end, $r1       ; start of cramfs -> r1
20059         move.d  romfs_start, $r3
20060 -       move.d  $r1, [$r3]
20061 +       move.d  $r1, [$r3]      ; store at romfs_start (for axisflashmap)
20062         move.d  romfs_length, $r3
20063 -       move.d  $r2, [$r3]
20064 +       move.d  $r2, [$r3]      ; store size at romfs_length
20065  
20066 -#ifndef CONFIG_ETRAXFS_SIM
20067 -       add.d   $r2, $r0
20068 +#ifndef CONFIG_ETRAXFS_SIM             
20069 +       add.d   $r2, $r0        ; copy from end and downwards
20070         add.d   $r2, $r1
20071 -
20072 +       
20073         lsrq    1, $r2          ; Size is in bytes, we copy words.
20074         addq    1, $r2
20075  1:
20076 @@ -364,17 +392,24 @@
20077         bne     1b
20078         nop
20079  #endif
20080 -
20081 -2:
20082 +       
20083 +4:
20084 +       ;; BSS move done.
20085 +       ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM
20086 +       ;; Also clear nand_boot flag; if we got here, we know we've not
20087 +       ;; booted from NAND flash.
20088         moveq   0, $r0
20089         move.d  romfs_in_flash, $r1
20090         move.d  $r0, [$r1]
20091 +       moveq   0, $r0
20092 +       move.d  nand_boot, $r1
20093 +       move.d  $r0, [$r1]
20094  
20095         jump    _start_it       ; Jump to cached code.
20096         nop
20097 -
20098 +       
20099  _start_it:
20100 -
20101 +       
20102         ;; Check if kernel command line is supplied
20103         cmp.d   COMMAND_LINE_MAGIC, $r10
20104         bne     no_command_line
20105 @@ -383,9 +418,9 @@
20106         move.d  256, $r13
20107         move.d  cris_command_line, $r10
20108         or.d    0x80000000, $r11 ; Make it virtual
20109 -1:
20110 -       move.b  [$r11+], $r12
20111 -       move.b  $r12, [$r10+]
20112 +1:                             
20113 +       move.b  [$r11+], $r1
20114 +       move.b  $r1, [$r10+]    
20115         subq    1, $r13
20116         bne     1b
20117         nop
20118 @@ -401,7 +436,7 @@
20119         move.d  etrax_irv, $r1  ; Set the exception base register and pointer.
20120         move.d  $r0, [$r1]
20121  
20122 -#ifndef CONFIG_ETRAXFS_SIM
20123 +#ifndef CONFIG_ETRAXFS_SIM     
20124         ;; Clear the BSS region from _bss_start to _end.
20125         move.d  __bss_start, $r0
20126         move.d  _end, $r1
20127 @@ -429,17 +464,31 @@
20128         .data
20129  etrax_irv:
20130         .dword 0
20131 +
20132 +; Variables for communication with the Axis flash map driver (axisflashmap),
20133 +; and for setting up memory in arch/cris/kernel/setup.c .
20134 +
20135 +; romfs_start is set to the start of the root file system, if it exists
20136 +; in directly accessible memory (i.e. NOR Flash when booting from Flash,
20137 +; or RAM when booting directly from a network-downloaded RAM image)
20138  romfs_start:
20139         .dword 0
20140 +
20141 +; romfs_length is set to the size of the root file system image, if it exists
20142 +; in directly accessible memory (see romfs_start). Otherwise it is set to 0.
20143  romfs_length:
20144         .dword 0
20145 +
20146 +; romfs_in_flash is set to 1 if the root file system resides in directly
20147 +; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot
20148 +; or NAND flash boot.
20149  romfs_in_flash:
20150         .dword 0
20151 -crisv32_nand_boot:
20152 -       .dword 0
20153 -crisv32_nand_cramfs_offset:
20154 -       .dword 0
20155  
20156 +; nand_boot is set to 1 when the kernel has been booted from NAND flash
20157 +nand_boot:
20158 +       .dword 0
20159 +       
20160  swapper_pg_dir = 0xc0002000
20161  
20162         .section ".init.data", "aw"
20163 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/io.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/io.c
20164 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/io.c   2007-01-10 20:10:37.000000000 +0100
20165 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/io.c   2006-11-21 00:04:55.000000000 +0100
20166 @@ -1,7 +1,7 @@
20167 -/*
20168 +/* 
20169   * Helper functions for I/O pins.
20170   *
20171 - * Copyright (c) 2004 Axis Communications AB.
20172 + * Copyright (c) 2004, 2006 Axis Communications AB.
20173   */
20174  
20175  #include <linux/types.h>
20176 @@ -15,6 +15,10 @@
20177  #include <asm/arch/pinmux.h>
20178  #include <asm/arch/hwregs/gio_defs.h>
20179  
20180 +#ifndef DEBUG
20181 +#define DEBUG(x)
20182 +#endif
20183 +
20184  struct crisv32_ioport crisv32_ioports[] =
20185  {
20186         {
20187 @@ -46,13 +50,15 @@
20188                 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout),
20189                 (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din),
20190                 18
20191 -       }
20192 +       } 
20193  };
20194  
20195  #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
20196  
20197 -struct crisv32_iopin crisv32_led1_green;
20198 -struct crisv32_iopin crisv32_led1_red;
20199 +struct crisv32_iopin crisv32_led_net0_green;
20200 +struct crisv32_iopin crisv32_led_net0_red;
20201 +struct crisv32_iopin crisv32_led_net1_green;
20202 +struct crisv32_iopin crisv32_led_net1_red;
20203  struct crisv32_iopin crisv32_led2_green;
20204  struct crisv32_iopin crisv32_led2_red;
20205  struct crisv32_iopin crisv32_led3_green;
20206 @@ -76,34 +82,54 @@
20207  static int __init crisv32_io_init(void)
20208  {
20209         int ret = 0;
20210 +
20211 +       u32 i;
20212 +
20213 +       /* Locks *should* be dynamically initialized. */
20214 +       for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
20215 +               spin_lock_init (&crisv32_ioports[i].lock);
20216 +       spin_lock_init (&dummy_port.lock);
20217 +
20218         /* Initialize LEDs */
20219 -       ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G);
20220 -       ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R);
20221 +#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
20222 +       ret += crisv32_io_get_name(&crisv32_led_net0_green, CONFIG_ETRAX_LED_G_NET0);
20223 +       crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
20224 +       if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
20225 +               ret += crisv32_io_get_name(&crisv32_led_net0_red, CONFIG_ETRAX_LED_R_NET0);
20226 +               crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
20227 +       } else
20228 +               crisv32_led_net0_red = dummy_led;
20229 +#endif
20230 +
20231 +#ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO
20232 +       ret += crisv32_io_get_name(&crisv32_led_net1_green, CONFIG_ETRAX_LED_G_NET1);
20233 +       crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out);
20234 +       if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) {
20235 +               crisv32_io_get_name(&crisv32_led_net1_red, CONFIG_ETRAX_LED_R_NET1);
20236 +               crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out);
20237 +       } else
20238 +               crisv32_led_net1_red = dummy_led;
20239 +#endif
20240 +
20241         ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G);
20242         ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R);
20243         ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G);
20244         ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R);
20245 -       crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out);
20246 -       crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out);
20247 +
20248         crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
20249         crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
20250         crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
20251         crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
20252  
20253 -       if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R))
20254 -               crisv32_led1_red = dummy_led;
20255 -       if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R))
20256 -               crisv32_led2_red = dummy_led;
20257 -
20258         return ret;
20259  }
20260  
20261  __initcall(crisv32_io_init);
20262  
20263 -int crisv32_io_get(struct crisv32_iopin* iopin,
20264 +int crisv32_io_get(struct crisv32_iopin* iopin, 
20265                     unsigned int port, unsigned int pin)
20266  {
20267 -       if (port > NBR_OF_PORTS)
20268 +       if (port > NBR_OF_PORTS) 
20269                 return -EINVAL;
20270         if (port > crisv32_ioports[port].pin_count)
20271                 return -EINVAL;
20272 @@ -111,14 +137,17 @@
20273         iopin->bit = 1 << pin;
20274         iopin->port = &crisv32_ioports[port];
20275  
20276 -       if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
20277 +       /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
20278 +        /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
20279 +       if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio)) 
20280                 return -EIO;
20281 -
20282 +       DEBUG(printk("crisv32_io_get: Allocated pin %d on port %d\n", pin, port ));
20283 +       
20284         return 0;
20285  }
20286  
20287  int crisv32_io_get_name(struct crisv32_iopin* iopin,
20288 -                         char* name)
20289 +                       const char* name)
20290  {
20291         int port;
20292         int pin;
20293 @@ -128,7 +157,7 @@
20294  
20295         if (toupper(*name) < 'A' || toupper(*name) > 'E')
20296                 return -EINVAL;
20297 -
20298 +       
20299         port = toupper(*name) - 'A';
20300         name++;
20301         pin = simple_strtoul(name, NULL, 10);
20302 @@ -139,9 +168,12 @@
20303         iopin->bit = 1 << pin;
20304         iopin->port = &crisv32_ioports[port];
20305  
20306 -       if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
20307 +       /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
20308 +        /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
20309 +       if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio)) 
20310                 return -EIO;
20311  
20312 +       DEBUG(printk("crisv32_io_get_name: Allocated pin %d on port %d\n", pin, port));
20313         return 0;
20314  }
20315  
20316 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/irq.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/irq.c
20317 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/irq.c  2007-01-10 20:10:37.000000000 +0100
20318 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/irq.c  2006-10-13 14:43:13.000000000 +0200
20319 @@ -44,10 +44,10 @@
20320    cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */
20321  };
20322  
20323 -struct cris_irq_allocation irq_allocations[NR_IRQS] =
20324 +struct cris_irq_allocation irq_allocations[NR_IRQS] = 
20325    {[0 ... NR_IRQS - 1] = {0, CPU_MASK_ALL}};
20326  
20327 -static unsigned long irq_regs[NR_CPUS] =
20328 +static unsigned long irq_regs[NR_CPUS] = 
20329  {
20330    regi_irq,
20331  #ifdef CONFIG_SMP
20332 @@ -79,9 +79,9 @@
20333  extern void kgdb_init(void);
20334  extern void breakpoint(void);
20335  
20336 -/*
20337 - * Build the IRQ handler stubs using macros from irq.h. First argument is the
20338 - * IRQ number, the second argument is the corresponding bit in
20339 +/* 
20340 + * Build the IRQ handler stubs using macros from irq.h. First argument is the 
20341 + * IRQ number, the second argument is the corresponding bit in 
20342   * intr_rw_vect_mask found in asm/arch/hwregs/intr_vect_defs.h.
20343   */
20344  BUILD_IRQ(0x31, (1 << 0))      /* memarb */
20345 @@ -139,7 +139,7 @@
20346  
20347          spin_lock_irqsave(&irq_lock, flags);
20348          intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20349 -
20350 +       
20351         /* Remember; 1 let thru, 0 block. */
20352         intr_mask &= ~(1 << (irq - FIRST_IRQ));
20353  
20354 @@ -152,10 +152,10 @@
20355  {
20356         int intr_mask;
20357          unsigned long flags;
20358 -
20359 +        
20360          spin_lock_irqsave(&irq_lock, flags);
20361          intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20362 -
20363 +       
20364         /* Remember; 1 let thru, 0 block. */
20365         intr_mask |= (1 << (irq - FIRST_IRQ));
20366  
20367 @@ -168,7 +168,7 @@
20368  {
20369         int cpu;
20370          unsigned long flags;
20371 -
20372 +        
20373          spin_lock_irqsave(&irq_lock, flags);
20374          cpu = irq_allocations[irq - FIRST_IRQ].cpu;
20375  
20376 @@ -178,12 +178,12 @@
20377                 spin_unlock_irqrestore(&irq_lock, flags);
20378                 return smp_processor_id();
20379          }
20380 -
20381 +        
20382  
20383         /* Let the interrupt stay if possible */
20384         if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
20385                 goto out;
20386 -
20387 +       
20388         /* IRQ must be moved to another CPU. */
20389         cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask);
20390         irq_allocations[irq - FIRST_IRQ].cpu = cpu;
20391 @@ -287,7 +287,7 @@
20392   * interrupt from the CPU and software has to sort out which
20393   * interrupts that happened. There are two special cases here:
20394   *
20395 - * 1. Timer interrupts may never be blocked because of the
20396 + * 1. Timer interrupts may never be blocked because of the 
20397   *    watchdog (refer to comment in include/asr/arch/irq.h)
20398   * 2. GDB serial port IRQs are unhandled here and will be handled
20399   *    as a single IRQ when it strikes again because the GDB
20400 @@ -304,33 +304,33 @@
20401         cpu = smp_processor_id();
20402  
20403         /* An extra irq_enter here to prevent softIRQs to run after
20404 -         * each do_IRQ. This will decrease the interrupt latency.
20405 +         * each do_IRQ. This will decrease the interrupt latency. 
20406          */
20407         irq_enter();
20408  
20409         /* Get which IRQs that happend. */
20410         masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
20411 -
20412 +       
20413         /* Calculate new IRQ mask with these IRQs disabled. */
20414         mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20415         mask &= ~masked;
20416  
20417         /* Timer IRQ is never masked */
20418         if (masked & TIMER_MASK)
20419 -               mask |= TIMER_MASK;
20420 +               mask |= TIMER_MASK; 
20421  
20422         /* Block all the IRQs */
20423         REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask);
20424 -
20425 +       
20426         /* Check for timer IRQ and handle it special. */
20427         if (masked & TIMER_MASK) {
20428                 masked &= ~TIMER_MASK;
20429 -               do_IRQ(TIMER_INTR_VECT, regs);
20430 +               do_IRQ(TIMER_INTR_VECT, regs);          
20431         }
20432  
20433  #ifdef IGNORE_MASK
20434         /* Remove IRQs that can't be handled as multiple. */
20435 -       masked &= ~IGNORE_MASK;
20436 +       masked &= ~IGNORE_MASK; 
20437  #endif
20438  
20439         /* Handle the rest of the IRQs. */
20440 @@ -377,7 +377,7 @@
20441         irq_desc[TIMER_INTR_VECT].status |= IRQ_PER_CPU;
20442         irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
20443         irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU;
20444 -
20445 +          
20446         set_exception_vector(0x00, nmi_interrupt);
20447         set_exception_vector(0x30, multiple_interrupt);
20448  
20449 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb.c
20450 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb.c 2007-01-10 20:10:37.000000000 +0100
20451 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb.c 2005-07-06 11:40:49.000000000 +0200
20452 @@ -25,7 +25,7 @@
20453   *  kgdb usage notes:
20454   *  -----------------
20455   *
20456 - * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be
20457 + * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be 
20458   * built with different gcc flags: "-g" is added to get debug infos, and
20459   * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
20460   * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
20461 @@ -118,7 +118,7 @@
20462   *  call to kgdb_init() is necessary in order to allow any breakpoints
20463   *  or error conditions to be properly intercepted and reported to gdb.
20464   *  Two, a breakpoint needs to be generated to begin communication.  This
20465 - *  is most easily accomplished by a call to breakpoint().
20466 + *  is most easily accomplished by a call to breakpoint(). 
20467   *
20468   *    The following gdb commands are supported:
20469   *
20470 @@ -382,8 +382,8 @@
20471  int getDebugChar(void);
20472  
20473  #ifdef CONFIG_ETRAXFS_SIM
20474 -int getDebugChar(void)
20475 -{
20476 +int getDebugChar(void) 
20477 +{ 
20478    return socketread();
20479  }
20480  #endif
20481 @@ -490,7 +490,7 @@
20482  
20483  /********************************** Breakpoint *******************************/
20484  /* Use an internal stack in the breakpoint and interrupt response routines.
20485 -   FIXME: How do we know the size of this stack is enough?
20486 +   FIXME: How do we know the size of this stack is enough? 
20487     Global so it can be reached from assembler code. */
20488  #define INTERNAL_STACK_SIZE 1024
20489  char internal_stack[INTERNAL_STACK_SIZE];
20490 @@ -511,7 +511,7 @@
20491  gdb_cris_strcpy(char *s1, const char *s2)
20492  {
20493         char *s = s1;
20494 -
20495 +       
20496         for (s = s1; (*s++ = *s2++) != '\0'; )
20497                 ;
20498         return s1;
20499 @@ -522,7 +522,7 @@
20500  gdb_cris_strlen(const char *s)
20501  {
20502         const char *sc;
20503 -
20504 +       
20505         for (sc = s; *sc != '\0'; sc++)
20506                 ;
20507         return (sc - s);
20508 @@ -534,7 +534,7 @@
20509  {
20510         const unsigned char uc = c;
20511         const unsigned char *su;
20512 -
20513 +       
20514         for (su = s; 0 < n; ++su, --n)
20515                 if (*su == uc)
20516                         return (void *)su;
20517 @@ -549,15 +549,15 @@
20518         char *s1;
20519         char *sd;
20520         int x = 0;
20521 -
20522 +       
20523         for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)
20524                 x = x * base + (sd - hexchars);
20525 -
20526 +        
20527          if (endptr) {
20528                  /* Unconverted suffix is stored in endptr unless endptr is NULL. */
20529                  *endptr = s1;
20530          }
20531 -
20532 +        
20533         return x;
20534  }
20535  
20536 @@ -629,7 +629,7 @@
20537         } else if (regno == PID) {
20538                 /* 32-bit register. */
20539                 *valptr =  *(unsigned int *)((char *)&reg.pid);
20540 -
20541 +              
20542         } else if (regno == SRS) {
20543                 /* 8-bit register. */
20544                 *valptr = (unsigned int)(*(unsigned char *)((char *)&reg.srs));
20545 @@ -726,7 +726,7 @@
20546                 *buf++ = highhex (ch);
20547                 *buf++ = lowhex (ch);
20548          }
20549 -
20550 +        
20551          /* Terminate properly. */
20552         *buf = '\0';
20553         return buf;
20554 @@ -804,7 +804,7 @@
20555                         continue;
20556  
20557                 buffer[count] = 0;
20558 -
20559 +               
20560                 if (ch == '#') {
20561                         xmitcsum = hex(getDebugChar()) << 4;
20562                         xmitcsum += hex(getDebugChar());
20563 @@ -836,7 +836,7 @@
20564         int checksum;
20565         int runlen;
20566         int encode;
20567 -
20568 +       
20569         do {
20570                 char *src = buffer;
20571                 putDebugChar('$');
20572 @@ -905,42 +905,42 @@
20573  {
20574         char *ptr = output_buffer;
20575         unsigned int reg_cont;
20576 -
20577 +        
20578         /* Send trap type (converted to signal) */
20579  
20580 -       *ptr++ = 'T';
20581 +       *ptr++ = 'T';   
20582         *ptr++ = highhex(sigval);
20583         *ptr++ = lowhex(sigval);
20584  
20585         if (((reg.exs & 0xff00) >> 8) == 0xc) {
20586 -
20587 +               
20588                 /* Some kind of hardware watchpoint triggered. Find which one
20589                    and determine its type (read/write/access).  */
20590                 int S, bp, trig_bits = 0, rw_bits = 0;
20591                 int trig_mask = 0;
20592                 unsigned int *bp_d_regs = &sreg.s3_3;
20593                 /* In a lot of cases, the stopped data address will simply be EDA.
20594 -                  In some cases, we adjust it to match the watched data range.
20595 +                  In some cases, we adjust it to match the watched data range. 
20596                    (We don't want to change the actual EDA though). */
20597                 unsigned int stopped_data_address;
20598                 /* The S field of EXS. */
20599                 S = (reg.exs & 0xffff0000) >> 16;
20600 -
20601 +               
20602                 if (S & 1) {
20603                         /* Instruction watchpoint. */
20604                         /* FIXME: Check against, and possibly adjust reported EDA. */
20605                 } else {
20606                         /* Data watchpoint.  Find the one that triggered. */
20607                         for (bp = 0; bp < 6; bp++) {
20608 -
20609 +                       
20610                                 /* Dx_RD, Dx_WR in the S field of EXS for this BP. */
20611                                 int bitpos_trig = 1 + bp * 2;
20612                                 /* Dx_BPRD, Dx_BPWR in BP_CTRL for this BP. */
20613                                 int bitpos_config = 2 + bp * 4;
20614 -
20615 +                       
20616                                 /* Get read/write trig bits for this BP. */
20617                                 trig_bits = (S & (3 << bitpos_trig)) >> bitpos_trig;
20618 -
20619 +                       
20620                                 /* Read/write config bits for this BP. */
20621                                 rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
20622                                 if (trig_bits) {
20623 @@ -949,11 +949,11 @@
20624                                         if ((rw_bits == 0x1 && trig_bits != 0x1) ||
20625                                             (rw_bits == 0x2 && trig_bits != 0x2))
20626                                                 panic("Invalid r/w trigging for this BP");
20627 -
20628 +                               
20629                                         /* Mark this BP as trigged for future reference. */
20630                                         trig_mask |= (1 << bp);
20631 -
20632 -                                       if (reg.eda >= bp_d_regs[bp * 2] &&
20633 +                               
20634 +                                       if (reg.eda >= bp_d_regs[bp * 2] && 
20635                                             reg.eda <= bp_d_regs[bp * 2 + 1]) {
20636                                                 /* EDA withing range for this BP; it must be the one
20637                                                    we're looking for. */
20638 @@ -972,7 +972,7 @@
20639  
20640                                         /* Read/write config bits for this BP (needed later). */
20641                                         rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
20642 -
20643 +                               
20644                                         if (trig_mask & (1 << bp)) {
20645                                                 /* EDA within 31 bytes of the configured start address? */
20646                                                 if (reg.eda + 31 >= bp_d_regs[bp * 2]) {
20647 @@ -987,12 +987,12 @@
20648                                         }
20649                                 }
20650                         }
20651 -
20652 +                       
20653                         /* No match yet? */
20654                         BUG_ON(bp >= 6);
20655                         /* Note that we report the type according to what the BP is configured
20656                            for (otherwise we'd never report an 'awatch'), not according to how
20657 -                          it trigged. We did check that the trigged bits match what the BP is
20658 +                          it trigged. We did check that the trigged bits match what the BP is 
20659                            configured for though. */
20660                         if (rw_bits == 0x1) {
20661                                 /* read */
20662 @@ -1110,12 +1110,12 @@
20663  
20664         if (sigval == SIGTRAP) {
20665                 /* Break 8, single step or hardware breakpoint exception. */
20666 -
20667 +               
20668                 /* Check IDX field of EXS. */
20669                 if (((reg.exs & 0xff00) >> 8) == 0x18) {
20670  
20671                         /* Break 8. */
20672 -
20673 +                       
20674                          /* Static (compiled) breakpoints must return to the next instruction
20675                            in order to avoid infinite loops (default value of ERP). Dynamic
20676                            (gdb-invoked) must subtract the size of the break instruction from
20677 @@ -1132,7 +1132,7 @@
20678                                         reg.pc -= 2;
20679                                 }
20680                         }
20681 -
20682 +                       
20683                 } else if (((reg.exs & 0xff00) >> 8) == 0x3) {
20684                         /* Single step. */
20685                         /* Don't fiddle with S1. */
20686 @@ -1190,10 +1190,10 @@
20687                 unsigned int *bp_d_regs = &sreg.s3_3;
20688  
20689                 /* The watchpoint allocation scheme is the simplest possible.
20690 -                  For example, if a region is watched for read and
20691 +                  For example, if a region is watched for read and 
20692                    a write watch is requested, a new watchpoint will
20693                    be used. Also, if a watch for a region that is already
20694 -                  covered by one or more existing watchpoints, a new
20695 +                  covered by one or more existing watchpoints, a new 
20696                    watchpoint will be used. */
20697  
20698                 /* First, find a free data watchpoint. */
20699 @@ -1205,13 +1205,13 @@
20700                                 break;
20701                         }
20702                 }
20703 -
20704 +                                              
20705                 if (bp > 5) {
20706                         /* We're out of watchpoints. */
20707                         gdb_cris_strcpy(output_buffer, error_message[E04]);
20708                         return;
20709                 }
20710 -
20711 +               
20712                 /* Configure the control register first. */
20713                 if (type == '3' || type == '4') {
20714                         /* Trigger on read. */
20715 @@ -1221,11 +1221,11 @@
20716                         /* Trigger on write. */
20717                         sreg.s0_3 |= (2 << (2 + bp * 4));
20718                 }
20719 -
20720 +                                              
20721                 /* Ugly pointer arithmetics to configure the watched range. */
20722                 bp_d_regs[bp * 2] = addr;
20723                 bp_d_regs[bp * 2 + 1] = (addr + len - 1);
20724 -       }
20725 +       } 
20726  
20727         /* Set the S1 flag to enable watchpoints. */
20728         reg.ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
20729 @@ -1258,7 +1258,7 @@
20730                         /* Not in use. */
20731                         gdb_cris_strcpy(output_buffer, error_message[E04]);
20732                         return;
20733 -               }
20734 +               }               
20735                 /* Deconfigure. */
20736                 sreg.s1_3 = 0;
20737                 sreg.s2_3 = 0;
20738 @@ -1268,8 +1268,8 @@
20739                 unsigned int *bp_d_regs = &sreg.s3_3;
20740                 /* Try to find a watchpoint that is configured for the
20741                    specified range, then check that read/write also matches. */
20742 -
20743 -               /* Ugly pointer arithmetic, since I cannot rely on a
20744 +                                       
20745 +               /* Ugly pointer arithmetic, since I cannot rely on a 
20746                    single switch (addr) as there may be several watchpoints with
20747                    the same start address for example. */
20748  
20749 @@ -1279,7 +1279,7 @@
20750                                 /* Matching range. */
20751                                 int bitpos = 2 + bp * 4;
20752                                 int rw_bits;
20753 -
20754 +                               
20755                                 /* Read/write bits for this BP. */
20756                                 rw_bits = (sreg.s0_3 & (0x3 << bitpos)) >> bitpos;
20757  
20758 @@ -1347,7 +1347,7 @@
20759                                         (char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
20760                                         16 * sizeof(unsigned int));
20761                                 break;
20762 -                       }
20763 +                       }       
20764                         case 'G':
20765                                 /* Write registers. GXX..XX
20766                                    Each byte of register data  is described by two hex digits.
20767 @@ -1357,11 +1357,11 @@
20768                                 hex2mem((char *)&reg, &input_buffer[1], sizeof(registers));
20769                                 /* Support registers. */
20770                                 hex2mem((char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
20771 -                                       &input_buffer[1] + sizeof(registers),
20772 +                                       &input_buffer[1] + sizeof(registers), 
20773                                         16 * sizeof(unsigned int));
20774                                 gdb_cris_strcpy(output_buffer, "OK");
20775                                 break;
20776 -
20777 +                               
20778                         case 'P':
20779                                 /* Write register. Pn...=r...
20780                                    Write register n..., hex value without 0x, with value r...,
20781 @@ -1393,7 +1393,7 @@
20782                                         }
20783                                 }
20784                                 break;
20785 -
20786 +                               
20787                         case 'm':
20788                                 /* Read from memory. mAA..AA,LLLL
20789                                    AA..AA is the address and LLLL is the length.
20790 @@ -1416,7 +1416,7 @@
20791                                          mem2hex(output_buffer, addr, len);
20792                                  }
20793                                 break;
20794 -
20795 +                               
20796                         case 'X':
20797                                 /* Write to memory. XAA..AA,LLLL:XX..XX
20798                                    AA..AA is the start address,  LLLL is the number of bytes, and
20799 @@ -1448,7 +1448,7 @@
20800                                         }
20801                                 }
20802                                 break;
20803 -
20804 +                               
20805                         case 'c':
20806                                 /* Continue execution. cAA..AA
20807                                    AA..AA is the address where execution is resumed. If AA..AA is
20808 @@ -1472,15 +1472,15 @@
20809                                 if ((sreg.s0_3 & 0x3fff) == 0) {
20810                                         reg.ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
20811                                 }
20812 -
20813 +                               
20814                                 return;
20815 -
20816 +                               
20817                         case 's':
20818                                 /* Step. sAA..AA
20819                                    AA..AA is the address where execution is resumed. If AA..AA is
20820                                    omitted, resume at the present address. Success: return to the
20821                                    executing thread. Failure: will never know. */
20822 -
20823 +                               
20824                                 if (input_buffer[1] != '\0') {
20825                                         /* FIXME: Doesn't handle address argument. */
20826                                         gdb_cris_strcpy(output_buffer, error_message[E04]);
20827 @@ -1497,7 +1497,7 @@
20828                                 return;
20829  
20830                         case 'Z':
20831 -
20832 +                               
20833                                 /* Insert breakpoint or watchpoint, Ztype,addr,length.
20834                                    Remote protocol says: A remote target shall return an empty string
20835                                    for an unrecognized breakpoint or watchpoint packet type. */
20836 @@ -1522,7 +1522,7 @@
20837                                         int addr = gdb_cris_strtol(&input_buffer[3], &lenptr, 16);
20838                                         int len = gdb_cris_strtol(lenptr + 1, &dataptr, 16);
20839                                         char type = input_buffer[1];
20840 -
20841 +                                       
20842                                         remove_watchpoint(type, addr, len);
20843                                         break;
20844                                 }
20845 @@ -1537,14 +1537,14 @@
20846                                 output_buffer[2] = lowhex(sigval);
20847                                 output_buffer[3] = 0;
20848                                 break;
20849 -
20850 +                               
20851                         case 'D':
20852                                 /* Detach from host. D
20853                                    Success: OK, and return to the executing thread.
20854                                    Failure: will never know */
20855                                 putpacket("OK");
20856                                 return;
20857 -
20858 +                               
20859                         case 'k':
20860                         case 'r':
20861                                 /* kill request or reset request.
20862 @@ -1552,7 +1552,7 @@
20863                                    Failure: will never know. */
20864                                 kill_restart();
20865                                 break;
20866 -
20867 +                               
20868                         case 'C':
20869                         case 'S':
20870                         case '!':
20871 @@ -1570,7 +1570,7 @@
20872                                    and ignored (below)? */
20873                                 gdb_cris_strcpy(output_buffer, error_message[E04]);
20874                                 break;
20875 -
20876 +                               
20877                         default:
20878                                 /* The stub should ignore other request and send an empty
20879                                    response ($#<checksum>). This way we can extend the protocol and GDB
20880 @@ -1587,7 +1587,7 @@
20881  {
20882         reg_intr_vect_rw_mask intr_mask;
20883         reg_ser_rw_intr_mask ser_intr_mask;
20884 -
20885 +       
20886         /* Configure the kgdb serial port. */
20887  #if defined(CONFIG_ETRAX_KGDB_PORT0)
20888         /* Note: no shortcut registered (not handled by multiple_interrupt).
20889 @@ -1597,9 +1597,9 @@
20890         intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20891         intr_mask.ser0 = 1;
20892         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20893 -
20894 +       
20895         ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask);
20896 -       ser_intr_mask.data_avail = regk_ser_yes;
20897 +       ser_intr_mask.dav = regk_ser_yes;
20898         REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask);
20899  #elif defined(CONFIG_ETRAX_KGDB_PORT1)
20900         /* Note: no shortcut registered (not handled by multiple_interrupt).
20901 @@ -1609,9 +1609,9 @@
20902         intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20903         intr_mask.ser1 = 1;
20904         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20905 -
20906 +       
20907         ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask);
20908 -       ser_intr_mask.data_avail = regk_ser_yes;
20909 +       ser_intr_mask.dav = regk_ser_yes;
20910         REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask);
20911  #elif defined(CONFIG_ETRAX_KGDB_PORT2)
20912         /* Note: no shortcut registered (not handled by multiple_interrupt).
20913 @@ -1621,9 +1621,9 @@
20914         intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20915         intr_mask.ser2 = 1;
20916         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20917 -
20918 +       
20919         ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask);
20920 -       ser_intr_mask.data_avail = regk_ser_yes;
20921 +       ser_intr_mask.dav = regk_ser_yes;
20922         REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask);
20923  #elif defined(CONFIG_ETRAX_KGDB_PORT3)
20924         /* Note: no shortcut registered (not handled by multiple_interrupt).
20925 @@ -1635,7 +1635,7 @@
20926         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20927  
20928         ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask);
20929 -       ser_intr_mask.data_avail = regk_ser_yes;
20930 +       ser_intr_mask.dav = regk_ser_yes;
20931         REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask);
20932  #endif
20933  
20934 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb_asm.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb_asm.S
20935 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb_asm.S     2007-01-10 20:10:37.000000000 +0100
20936 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb_asm.S     2006-10-13 14:43:13.000000000 +0200
20937 @@ -11,7 +11,7 @@
20938         .globl kgdb_handle_exception
20939  
20940  kgdb_handle_exception:
20941 -
20942 +       
20943  ;; Create a register image of the caller.
20944  ;;
20945  ;; First of all, save the ACR on the stack since we need it for address calculations.
20946 @@ -262,7 +262,7 @@
20947  ;; Nothing in S15, bank 3
20948    clear.d [$acr]
20949    addq    4,     $acr
20950 -
20951 +       
20952  ;; Check what got us here: get IDX field of EXS.
20953    move $exs,    $r10
20954    and.d 0xff00, $r10
20955 @@ -307,7 +307,7 @@
20956  handle_comm:
20957    move.d   internal_stack+1020, $sp ; Use the internal stack which grows upwards
20958    jsr      handle_exception         ; Interactive routine
20959 -  nop
20960 +  nop                               
20961  
20962  ;;
20963  ;; Return to the caller
20964 @@ -345,7 +345,7 @@
20965  ;; Nothing in S6 - S7, bank 0.
20966    addq    4,      $acr
20967    addq    4,      $acr
20968 -
20969 +       
20970    move.d  [$acr], $r0
20971    move    $r0,    $s8
20972    addq    4,      $acr
20973 @@ -507,7 +507,7 @@
20974     addq    8,      $acr
20975  
20976     ;; Skip BZ, VR.
20977 -   addq    2,      $acr
20978 +   addq    2,      $acr   
20979  
20980     move    [$acr], $pid   ; Restore PID
20981     addq    4,      $acr
20982 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/pinmux.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/pinmux.c
20983 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/pinmux.c       2007-01-10 20:10:37.000000000 +0100
20984 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/pinmux.c       2006-08-11 10:32:21.000000000 +0200
20985 @@ -1,7 +1,7 @@
20986 -/*
20987 +/* 
20988   * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
20989   * Unassigned pins and GPIO pins can be allocated to a fixed interface
20990 - * or the I/O processor instead.
20991 + * or the I/O processor instead. 
20992   *
20993   * Copyright (c) 2004 Axis Communications AB.
20994   */
20995 @@ -33,9 +33,10 @@
20996  
20997         if (!initialized) {
20998                 reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
20999 +               REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
21000                 initialized = 1;
21001 -               pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
21002 -               pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
21003 +               pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 = 
21004 +                       pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
21005                 REG_WR(pinmux, regi_pinmux, rw_pa, pa);
21006                 crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
21007                 crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
21008 @@ -46,124 +47,137 @@
21009         return 0;
21010  }
21011  
21012 -int
21013 -crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21014 +/*
21015 + * must be called with the pinmux_lock held.
21016 + */
21017 +static int __crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
21018 +                                 enum pin_mode mode)
21019  {
21020         int i;
21021 -       unsigned long flags;
21022  
21023 -       crisv32_pinmux_init();
21024 -
21025 -       if (port > PORTS)
21026 +       if (port >= PORTS ||
21027 +           first_pin < 0 || last_pin >= PORT_PINS || last_pin < first_pin)
21028                 return -EINVAL;
21029 -
21030 -       spin_lock_irqsave(&pinmux_lock, flags);
21031 -
21032 -       for (i = first_pin; i <= last_pin; i++)
21033 +       
21034 +       for (i = first_pin; i <= last_pin; i++) 
21035         {
21036 -               if ((pins[port][i] != pinmux_none) && (pins[port][i] != pinmux_gpio) &&
21037 -                   (pins[port][i] != mode))
21038 +               if ((pins[port][i] != pinmux_none)
21039 +                   && (pins[port][i] != pinmux_gpio)
21040 +                   && (pins[port][i] != mode)) 
21041                 {
21042 -                       spin_unlock_irqrestore(&pinmux_lock, flags);
21043  #ifdef DEBUG
21044                         panic("Pinmux alloc failed!\n");
21045  #endif
21046                         return -EPERM;
21047                 }
21048         }
21049 -
21050 +  
21051         for (i = first_pin; i <= last_pin; i++)
21052                 pins[port][i] = mode;
21053  
21054         crisv32_pinmux_set(port);
21055 -
21056 -       spin_unlock_irqrestore(&pinmux_lock, flags);
21057 -
21058         return 0;
21059  }
21060  
21061  int
21062 +crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21063 +{
21064 +       int r;
21065 +       unsigned long flags;
21066 +       
21067 +       crisv32_pinmux_init();
21068 +       
21069 +       spin_lock_irqsave(&pinmux_lock, flags);
21070 +       r = __crisv32_pinmux_alloc(port, first_pin, last_pin, mode);
21071 +       spin_unlock_irqrestore(&pinmux_lock, flags);
21072 +       return r;
21073 +}
21074 +
21075 +int 
21076  crisv32_pinmux_alloc_fixed(enum fixed_function function)
21077  {
21078         int ret = -EINVAL;
21079         char saved[sizeof pins];
21080         unsigned long flags;
21081 -
21082 +        reg_pinmux_rw_hwprot hwprot;
21083 +        
21084 +       crisv32_pinmux_init();
21085 +       
21086         spin_lock_irqsave(&pinmux_lock, flags);
21087  
21088         /* Save internal data for recovery */
21089         memcpy(saved, pins, sizeof pins);
21090 -
21091 -       reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21092 -
21093 +  
21094 +       hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21095 +  
21096         switch(function)
21097         {
21098         case pinmux_ser1:
21099 -               ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
21100 +               ret = __crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
21101                 hwprot.ser1 = regk_pinmux_yes;
21102                 break;
21103         case pinmux_ser2:
21104 -               ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
21105 +               ret = __crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
21106                 hwprot.ser2 = regk_pinmux_yes;
21107                 break;
21108         case pinmux_ser3:
21109 -               ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
21110 +               ret = __crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
21111                 hwprot.ser3 = regk_pinmux_yes;
21112                 break;
21113         case pinmux_sser0:
21114 -               ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
21115 -               ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21116 +               ret = __crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
21117 +               ret |= __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21118                 hwprot.sser0 = regk_pinmux_yes;
21119                 break;
21120         case pinmux_sser1:
21121 -               ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21122 +               ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21123                 hwprot.sser1 = regk_pinmux_yes;
21124                 break;
21125         case pinmux_ata0:
21126 -               ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
21127 -               ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
21128 +               ret = __crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
21129 +               ret |= __crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
21130                 hwprot.ata0 = regk_pinmux_yes;
21131                 break;
21132         case pinmux_ata1:
21133 -               ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21134 -               ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
21135 +               ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21136 +               ret |= __crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
21137                 hwprot.ata1 = regk_pinmux_yes;
21138                 break;
21139         case pinmux_ata2:
21140 -               ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
21141 -               ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
21142 +               ret = __crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
21143 +               ret |= __crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
21144                 hwprot.ata2 = regk_pinmux_yes;
21145                 break;
21146         case pinmux_ata3:
21147 -               ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
21148 -               ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
21149 +               ret = __crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
21150 +               ret |= __crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
21151                 hwprot.ata2 = regk_pinmux_yes;
21152                 break;
21153         case pinmux_ata:
21154 -               ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
21155 -               ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
21156 +               ret = __crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
21157 +               ret |= __crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
21158                 hwprot.ata = regk_pinmux_yes;
21159                 break;
21160         case pinmux_eth1:
21161 -               ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
21162 +               ret = __crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
21163                 hwprot.eth1 = regk_pinmux_yes;
21164                 hwprot.eth1_mgm = regk_pinmux_yes;
21165                 break;
21166         case pinmux_timer:
21167 -               ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21168 +               ret = __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21169                 hwprot.timer = regk_pinmux_yes;
21170                 spin_unlock_irqrestore(&pinmux_lock, flags);
21171                 return ret;
21172         }
21173 -
21174 +  
21175         if (!ret)
21176                 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21177         else
21178                 memcpy(pins, saved, sizeof pins);
21179 -
21180 -  spin_unlock_irqrestore(&pinmux_lock, flags);
21181 -
21182 -  return ret;
21183 +       
21184 +       spin_unlock_irqrestore(&pinmux_lock, flags);
21185 +       
21186 +       return ret;
21187  }
21188  
21189  void
21190 @@ -189,33 +203,126 @@
21191  #endif
21192  }
21193  
21194 -int
21195 -crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21196 +/*
21197 + * must be called with the pinmux_lock held.
21198 + */
21199 +static int __crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21200  {
21201         int i;
21202 +  
21203 +       if (port > PORTS)
21204 +               return -EINVAL;
21205 +  
21206 +       for (i = first_pin; i <= last_pin; i++)
21207 +               pins[port][i] = pinmux_none;
21208 +
21209 +       crisv32_pinmux_set(port);
21210 +
21211 +       return 0;
21212 +}
21213 +
21214 +int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21215 +{
21216 +       int r;
21217         unsigned long flags;
21218  
21219         crisv32_pinmux_init();
21220 +       
21221 +       spin_lock_irqsave(&pinmux_lock, flags);
21222 +       r = __crisv32_pinmux_dealloc(port, first_pin, last_pin);
21223 +       spin_unlock_irqrestore(&pinmux_lock, flags);
21224 +       return r;
21225 +}
21226  
21227 -       if (port > PORTS)
21228 -               return -EINVAL;
21229 +int 
21230 +crisv32_pinmux_dealloc_fixed(enum fixed_function function)
21231 +{
21232 +       int ret = -EINVAL;
21233 +       char saved[sizeof pins];
21234 +       unsigned long flags;
21235  
21236         spin_lock_irqsave(&pinmux_lock, flags);
21237  
21238 -       for (i = first_pin; i <= last_pin; i++)
21239 -               pins[port][i] = pinmux_none;
21240 +       /* Save internal data for recovery */
21241 +       memcpy(saved, pins, sizeof pins);
21242 +  
21243 +       reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21244 +  
21245 +       switch(function)
21246 +       {
21247 +       case pinmux_ser1:
21248 +               ret = __crisv32_pinmux_dealloc(PORT_C, 4, 7);
21249 +               hwprot.ser1 = regk_pinmux_no;
21250 +               break;
21251 +       case pinmux_ser2:
21252 +               ret = __crisv32_pinmux_dealloc(PORT_C, 8, 11);
21253 +               hwprot.ser2 = regk_pinmux_no;
21254 +               break;
21255 +       case pinmux_ser3:
21256 +               ret = __crisv32_pinmux_dealloc(PORT_C, 12, 15);
21257 +               hwprot.ser3 = regk_pinmux_no;
21258 +               break;
21259 +       case pinmux_sser0:
21260 +               ret = __crisv32_pinmux_dealloc(PORT_C, 0, 3);
21261 +               ret |= __crisv32_pinmux_dealloc(PORT_C, 16, 16);
21262 +               hwprot.sser0 = regk_pinmux_no;
21263 +               break;
21264 +       case pinmux_sser1:
21265 +               ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
21266 +               hwprot.sser1 = regk_pinmux_no;
21267 +               break;
21268 +       case pinmux_ata0:
21269 +               ret = __crisv32_pinmux_dealloc(PORT_D, 5, 7);
21270 +               ret |= __crisv32_pinmux_dealloc(PORT_D, 15, 17);
21271 +               hwprot.ata0 = regk_pinmux_no;
21272 +               break;
21273 +       case pinmux_ata1:
21274 +               ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
21275 +               ret |= __crisv32_pinmux_dealloc(PORT_E, 17, 17);
21276 +               hwprot.ata1 = regk_pinmux_no;
21277 +               break;
21278 +       case pinmux_ata2:
21279 +               ret = __crisv32_pinmux_dealloc(PORT_C, 11, 15);
21280 +               ret |= __crisv32_pinmux_dealloc(PORT_E, 3, 3);
21281 +               hwprot.ata2 = regk_pinmux_no;
21282 +               break;
21283 +       case pinmux_ata3:
21284 +               ret = __crisv32_pinmux_dealloc(PORT_C, 8, 10);
21285 +               ret |= __crisv32_pinmux_dealloc(PORT_C, 0, 2);
21286 +               hwprot.ata2 = regk_pinmux_no;
21287 +               break;
21288 +       case pinmux_ata:
21289 +               ret = __crisv32_pinmux_dealloc(PORT_B, 0, 15);
21290 +               ret |= __crisv32_pinmux_dealloc(PORT_D, 8, 15);
21291 +               hwprot.ata = regk_pinmux_no;
21292 +               break;
21293 +       case pinmux_eth1:
21294 +               ret = __crisv32_pinmux_dealloc(PORT_E, 0, 17);
21295 +               hwprot.eth1 = regk_pinmux_no;
21296 +               hwprot.eth1_mgm = regk_pinmux_no;
21297 +               break;
21298 +       case pinmux_timer:
21299 +               ret = __crisv32_pinmux_dealloc(PORT_C, 16, 16);
21300 +               hwprot.timer = regk_pinmux_no;
21301 +               spin_unlock_irqrestore(&pinmux_lock, flags);
21302 +               return ret;
21303 +       }
21304 +  
21305 +       if (!ret)
21306 +               REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21307 +       else
21308 +               memcpy(pins, saved, sizeof pins);
21309  
21310 -       crisv32_pinmux_set(port);
21311         spin_unlock_irqrestore(&pinmux_lock, flags);
21312 -
21313 -       return 0;
21314 +       
21315 +       return ret;
21316  }
21317  
21318  void
21319  crisv32_pinmux_dump(void)
21320  {
21321         int i, j;
21322 -
21323 +  
21324         crisv32_pinmux_init();
21325  
21326         for (i = 0; i < PORTS; i++)
21327 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/process.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/process.c
21328 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/process.c      2007-01-10 20:10:37.000000000 +0100
21329 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/process.c      2006-10-13 14:43:13.000000000 +0200
21330 @@ -74,9 +74,9 @@
21331  #else
21332  {
21333         reg_timer_rw_wd_ctrl wd_ctrl = {0};
21334 -
21335 +       
21336         stop_watchdog();
21337 -
21338 +       
21339         wd_ctrl.key = 16;       /* Arbitrary key. */
21340         wd_ctrl.cnt = 1;        /* Minimum time. */
21341         wd_ctrl.cmd = regk_timer_start;
21342 @@ -141,7 +141,7 @@
21343  {
21344         struct pt_regs *childregs;
21345         struct switch_stack *swstack;
21346 -
21347 +       
21348         /*
21349          * Put the pt_regs structure at the end of the new kernel stack page and
21350          * fix it up. Note: the task_struct doubles as the kernel stack for the
21351 @@ -152,7 +152,7 @@
21352          p->set_child_tid = p->clear_child_tid = NULL;
21353          childregs->r10 = 0;    /* Child returns 0 after a fork/clone. */
21354  
21355 -       /* Set a new TLS ?
21356 +       /* Set a new TLS ?  
21357          * The TLS is in $mof beacuse it is the 5th argument to sys_clone.
21358          */
21359         if (p->mm && (clone_flags & CLONE_SETTLS)) {
21360 @@ -165,20 +165,20 @@
21361         /* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
21362         swstack->r9 = 0;
21363  
21364 -       /*
21365 +       /* 
21366          * We want to return into ret_from_sys_call after the _resume.
21367          * ret_from_fork will call ret_from_sys_call.
21368          */
21369         swstack->return_ip = (unsigned long) ret_from_fork;
21370 -
21371 +       
21372         /* Fix the user-mode and kernel-mode stackpointer. */
21373 -       p->thread.usp = usp;
21374 +       p->thread.usp = usp;    
21375         p->thread.ksp = (unsigned long) swstack;
21376  
21377         return 0;
21378  }
21379  
21380 -/*
21381 +/* 
21382   * Be aware of the "magic" 7th argument in the four system-calls below.
21383   * They need the latest stackframe, which is put as the 7th argument by
21384   * entry.S. The previous arguments are dummies or actually used, but need
21385 @@ -200,7 +200,7 @@
21386  
21387  /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
21388  asmlinkage int
21389 -sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid,
21390 +sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid, 
21391         unsigned long tls, long srp, struct pt_regs *regs)
21392  {
21393         if (!newusp)
21394 @@ -209,11 +209,11 @@
21395         return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
21396  }
21397  
21398 -/*
21399 +/* 
21400   * vfork is a system call in i386 because of register-pressure - maybe
21401   * we can remove it and handle it in libc but we put it here until then.
21402   */
21403 -asmlinkage int
21404 +asmlinkage int 
21405  sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
21406         struct pt_regs *regs)
21407  {
21408 @@ -222,7 +222,7 @@
21409  
21410  /* sys_execve() executes a new program. */
21411  asmlinkage int
21412 -sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
21413 +sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp, 
21414         struct pt_regs *regs)
21415  {
21416         int error;
21417 @@ -254,13 +254,13 @@
21418         unsigned long usp = rdusp();
21419          printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
21420                 regs->erp, regs->srp, regs->ccs, usp, regs->mof);
21421 -
21422 +       
21423         printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
21424                 regs->r0, regs->r1, regs->r2, regs->r3);
21425 -
21426 +       
21427         printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
21428                 regs->r4, regs->r5, regs->r6, regs->r7);
21429 -
21430 +       
21431         printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
21432                 regs->r8, regs->r9, regs->r10, regs->r11);
21433  
21434 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/ptrace.c
21435 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/ptrace.c       2007-01-10 20:10:37.000000000 +0100
21436 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/ptrace.c       2006-03-22 10:56:56.000000000 +0100
21437 @@ -20,7 +20,7 @@
21438  #include <asm/processor.h>
21439  #include <asm/arch/hwregs/supp_reg.h>
21440  
21441 -/*
21442 +/* 
21443   * Determines which bits in CCS the user has access to.
21444   * 1 = access, 0 = no access.
21445   */
21446 @@ -84,7 +84,7 @@
21447   *
21448   * Make sure the single step bit is not set.
21449   */
21450 -void
21451 +void 
21452  ptrace_disable(struct task_struct *child)
21453  {
21454         unsigned long tmp;
21455 @@ -105,7 +105,7 @@
21456         unsigned long __user *datap = (unsigned long __user *)data;
21457  
21458         switch (request) {
21459 -               /* Read word at location address. */
21460 +               /* Read word at location address. */ 
21461                 case PTRACE_PEEKTEXT:
21462                 case PTRACE_PEEKDATA: {
21463                         unsigned long tmp;
21464 @@ -122,11 +122,11 @@
21465                                 tmp = *(unsigned long*)addr;
21466                         } else {
21467                                 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21468 -
21469 +                       
21470                                 if (copied != sizeof(tmp))
21471                                         break;
21472                         }
21473 -
21474 +                       
21475                         ret = put_user(tmp,datap);
21476                         break;
21477                 }
21478 @@ -143,18 +143,18 @@
21479                         ret = put_user(tmp, datap);
21480                         break;
21481                 }
21482 -
21483 +               
21484                 /* Write the word at location address. */
21485                 case PTRACE_POKETEXT:
21486                 case PTRACE_POKEDATA:
21487                         ret = 0;
21488 -
21489 +                       
21490                         if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
21491                                 break;
21492 -
21493 +                       
21494                         ret = -EIO;
21495                         break;
21496 -
21497
21498                 /* Write the word at location address in the USER area. */
21499                 case PTRACE_POKEUSR:
21500                         ret = -EIO;
21501 @@ -178,10 +178,10 @@
21502                 case PTRACE_SYSCALL:
21503                 case PTRACE_CONT:
21504                         ret = -EIO;
21505 -
21506 +                       
21507                         if (!valid_signal(data))
21508                                 break;
21509 -
21510 +                       
21511                         /* Continue means no single-step. */
21512                         put_reg(child, PT_SPC, 0);
21513  
21514 @@ -198,27 +198,27 @@
21515                         else {
21516                                 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21517                         }
21518 -
21519 +                       
21520                         child->exit_code = data;
21521 -
21522 +                       
21523                         /* TODO: make sure any pending breakpoint is killed */
21524                         wake_up_process(child);
21525                         ret = 0;
21526 -
21527 +                       
21528                         break;
21529 -
21530 +               
21531                 /* Make the child exit by sending it a sigkill. */
21532                 case PTRACE_KILL:
21533                         ret = 0;
21534 -
21535 +                       
21536                         if (child->exit_state == EXIT_ZOMBIE)
21537                                 break;
21538 -
21539 +                       
21540                         child->exit_code = SIGKILL;
21541 -
21542 +                       
21543                         /* Deconfigure single-step and h/w bp. */
21544                         ptrace_disable(child);
21545 -
21546 +                       
21547                         /* TODO: make sure any pending breakpoint is killed */
21548                         wake_up_process(child);
21549                         break;
21550 @@ -227,7 +227,7 @@
21551                 case PTRACE_SINGLESTEP: {
21552                         unsigned long tmp;
21553                         ret = -EIO;
21554 -
21555 +                       
21556                         /* Set up SPC if not set already (in which case we have
21557                            no other choice but to trust it). */
21558                         if (!get_reg(child, PT_SPC)) {
21559 @@ -240,7 +240,7 @@
21560  
21561                         if (!valid_signal(data))
21562                                 break;
21563 -
21564 +                       
21565                         clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21566  
21567                         /* TODO: set some clever breakpoint mechanism... */
21568 @@ -259,15 +259,15 @@
21569                 case PTRACE_GETREGS: {
21570                         int i;
21571                         unsigned long tmp;
21572 -
21573 +                       
21574                         for (i = 0; i <= PT_MAX; i++) {
21575                                 tmp = get_reg(child, i);
21576 -
21577 +                               
21578                                 if (put_user(tmp, datap)) {
21579                                         ret = -EFAULT;
21580                                         goto out_tsk;
21581                                 }
21582 -
21583 +                               
21584                                 datap++;
21585                         }
21586  
21587 @@ -279,22 +279,22 @@
21588                 case PTRACE_SETREGS: {
21589                         int i;
21590                         unsigned long tmp;
21591 -
21592 +                       
21593                         for (i = 0; i <= PT_MAX; i++) {
21594                                 if (get_user(tmp, datap)) {
21595                                         ret = -EFAULT;
21596                                         goto out_tsk;
21597                                 }
21598 -
21599 +                               
21600                                 if (i == PT_CCS) {
21601                                         tmp &= CCS_MASK;
21602                                         tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
21603                                 }
21604 -
21605 +                               
21606                                 put_reg(child, i, tmp);
21607                                 datap++;
21608                         }
21609 -
21610 +                       
21611                         ret = 0;
21612                         break;
21613                 }
21614 @@ -304,6 +304,7 @@
21615                         break;
21616         }
21617  
21618 +out_tsk:
21619         return ret;
21620  }
21621  
21622 @@ -311,15 +312,15 @@
21623  {
21624         if (!test_thread_flag(TIF_SYSCALL_TRACE))
21625                 return;
21626 -
21627 +       
21628         if (!(current->ptrace & PT_PTRACED))
21629                 return;
21630 -
21631 +       
21632         /* the 0x80 provides a way for the tracing parent to distinguish
21633            between a syscall stop and SIGTRAP delivery */
21634         ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
21635                                  ? 0x80 : 0));
21636 -
21637 +       
21638         /*
21639          * This isn't the same as continuing with a signal, but it will do for
21640          * normal use.
21641 @@ -338,7 +339,7 @@
21642    int copied;
21643    int opsize = 0;
21644  
21645 -  /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
21646 +  /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */  
21647    copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
21648    if (copied != sizeof(opcode))
21649      return 0;
21650 @@ -361,7 +362,7 @@
21651                   opsize = 6;
21652           break;
21653    default:
21654 -         panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
21655 +         panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n", 
21656                 opcode, pc);
21657    }
21658  
21659 @@ -378,7 +379,7 @@
21660                 /* Delay slot bit set. Report as stopped on proper
21661                    instruction. */
21662                 if (spc) {
21663 -                       /* Rely on SPC if set. FIXME: We might want to check
21664 +                       /* Rely on SPC if set. FIXME: We might want to check 
21665                            that EXS indicates we stopped due to a single-step
21666                            exception. */
21667                         pc = spc;
21668 @@ -422,7 +423,7 @@
21669         register int old_srs;
21670  
21671  #ifdef CONFIG_ETRAX_KGDB
21672 -       /* Ignore write, but pretend it was ok if value is 0
21673 +       /* Ignore write, but pretend it was ok if value is 0 
21674            (we don't want POKEUSR/SETREGS failing unnessecarily). */
21675         return (data == 0) ? ret : -1;
21676  #endif
21677 @@ -431,7 +432,7 @@
21678         if (!bp_owner)
21679                 bp_owner = pid;
21680         else if (bp_owner != pid) {
21681 -               /* Ignore write, but pretend it was ok if value is 0
21682 +               /* Ignore write, but pretend it was ok if value is 0 
21683                    (we don't want POKEUSR/SETREGS failing unnessecarily). */
21684                 return (data == 0) ? ret : -1;
21685         }
21686 @@ -440,7 +441,7 @@
21687         SPEC_REG_RD(SPEC_REG_SRS, old_srs);
21688         /* Switch to BP bank. */
21689         SUPP_BANK_SEL(BANK_BP);
21690 -
21691 +       
21692         switch (regno - PT_BP) {
21693         case 0:
21694                 SUPP_REG_WR(0, data); break;
21695 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/setup.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/setup.c
21696 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/setup.c        2007-01-10 20:10:37.000000000 +0100
21697 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/setup.c        2006-10-13 14:43:13.000000000 +0200
21698 @@ -40,12 +40,12 @@
21699  
21700         {"ETRAX 100LX", 10, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21701                              | HAS_MMU | HAS_MMU_BUG},
21702 -
21703 +       
21704         {"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21705                                 | HAS_MMU},
21706 -
21707 +       
21708         {"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
21709 -
21710 +       
21711         {"Unknown", 0, 0, 0}
21712  };
21713  
21714 @@ -67,7 +67,7 @@
21715  #endif
21716  
21717         revision = rdvr();
21718 -
21719 +       
21720         for (i = 0; i < entries; i++) {
21721                 if (cpinfo[i].rev == revision) {
21722                         info = &cpinfo[i];
21723 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/signal.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/signal.c
21724 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/signal.c       2007-01-10 20:10:37.000000000 +0100
21725 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/signal.c       2006-03-22 10:56:56.000000000 +0100
21726 @@ -50,7 +50,7 @@
21727         unsigned char retcode[8];       /* Trampoline code. */
21728  };
21729  
21730 -int do_signal(int restart, sigset_t *oldset, struct pt_regs *regs);
21731 +void do_signal(int restart, struct pt_regs *regs);
21732  void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
21733                       struct pt_regs *regs);
21734  /*
21735 @@ -61,74 +61,16 @@
21736  sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
21737                long srp, struct pt_regs *regs)
21738  {
21739 -       sigset_t saveset;
21740 -
21741         mask &= _BLOCKABLE;
21742 -
21743         spin_lock_irq(&current->sighand->siglock);
21744 -
21745 -       saveset = current->blocked;
21746 -
21747 +       current->saved_sigmask = current->blocked;
21748         siginitset(&current->blocked, mask);
21749 -
21750         recalc_sigpending();
21751         spin_unlock_irq(&current->sighand->siglock);
21752 -
21753 -       regs->r10 = -EINTR;
21754 -
21755 -       while (1) {
21756 -               current->state = TASK_INTERRUPTIBLE;
21757 -               schedule();
21758 -
21759 -               if (do_signal(0, &saveset, regs)) {
21760 -                       /*
21761 -                        * This point is reached twice: once to call
21762 -                        * the signal handler, then again to return
21763 -                        * from the sigsuspend system call. When
21764 -                        * calling the signal handler, R10 hold the
21765 -                        * signal number as set by do_signal(). The
21766 -                        * sigsuspend  call will always return with
21767 -                        * the restored value above; -EINTR.
21768 -                        */
21769 -                       return regs->r10;
21770 -               }
21771 -       }
21772 -}
21773 -
21774 -/* Define some dummy arguments to be able to reach the regs argument. */
21775 -int
21776 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
21777 -                 long mof, long srp, struct pt_regs *regs)
21778 -{
21779 -       sigset_t saveset;
21780 -       sigset_t newset;
21781 -
21782 -       if (sigsetsize != sizeof(sigset_t))
21783 -               return -EINVAL;
21784 -
21785 -       if (copy_from_user(&newset, unewset, sizeof(newset)))
21786 -               return -EFAULT;
21787 -
21788 -       sigdelsetmask(&newset, ~_BLOCKABLE);
21789 -       spin_lock_irq(&current->sighand->siglock);
21790 -
21791 -       saveset = current->blocked;
21792 -       current->blocked = newset;
21793 -
21794 -       recalc_sigpending();
21795 -       spin_unlock_irq(&current->sighand->siglock);
21796 -
21797 -       regs->r10 = -EINTR;
21798 -
21799 -       while (1) {
21800 -               current->state = TASK_INTERRUPTIBLE;
21801 -               schedule();
21802 -
21803 -               if (do_signal(0, &saveset, regs)) {
21804 -                       /* See comment in function above. */
21805 -                       return regs->r10;
21806 -               }
21807 -       }
21808 +        current->state = TASK_INTERRUPTIBLE;
21809 +       schedule();
21810 +        set_thread_flag(TIF_RESTORE_SIGMASK);
21811 +        return -ERESTARTNOHAND;
21812  }
21813  
21814  int
21815 @@ -263,7 +205,7 @@
21816         unsigned long oldccs = regs->ccs;
21817  
21818         frame = (struct rt_signal_frame *) rdusp();
21819 -
21820 +       
21821         /*
21822          * Since the signal is stacked on a dword boundary, the frame
21823          * should be dword aligned here as well. It it's not, then the
21824 @@ -285,7 +227,7 @@
21825  
21826         recalc_sigpending();
21827         spin_unlock_irq(&current->sighand->siglock);
21828 -
21829 +        
21830         if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
21831                 goto badframe;
21832  
21833 @@ -311,7 +253,7 @@
21834  
21835         err = 0;
21836         usp = rdusp();
21837 -
21838 +       
21839         /*
21840          * Copy the registers. They are located first in sc, so it's
21841          * possible to use sc directly.
21842 @@ -351,7 +293,7 @@
21843   * which performs the syscall sigreturn(), or a provided user-mode
21844   * trampoline.
21845    */
21846 -static void
21847 +static int
21848  setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
21849             struct pt_regs * regs)
21850  {
21851 @@ -388,7 +330,7 @@
21852                 /* Trampoline - the desired return ip is in the signal return page. */
21853                 return_ip = cris_signal_return_page;
21854  
21855 -               /*
21856 +               /* 
21857                  * This is movu.w __NR_sigreturn, r9; break 13;
21858                  *
21859                  * WE DO NOT USE IT ANY MORE! It's only left here for historical
21860 @@ -402,7 +344,7 @@
21861  
21862         if (err)
21863                 goto give_sigsegv;
21864 -
21865 +       
21866         /*
21867          * Set up registers for signal handler.
21868          *
21869 @@ -417,16 +359,17 @@
21870         /* Actually move the USP to reflect the stacked frame. */
21871         wrusp((unsigned long)frame);
21872  
21873 -       return;
21874 +       return 0;
21875  
21876  give_sigsegv:
21877         if (sig == SIGSEGV)
21878                 ka->sa.sa_handler = SIG_DFL;
21879 -
21880 +       
21881         force_sig(SIGSEGV, current);
21882 +        return -EFAULT;
21883  }
21884  
21885 -static void
21886 +static int
21887  setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
21888                sigset_t *set, struct pt_regs * regs)
21889  {
21890 @@ -441,11 +384,11 @@
21891                 goto give_sigsegv;
21892  
21893         /* TODO: what is the current->exec_domain stuff and invmap ? */
21894 -
21895 +       
21896         err |= __put_user(&frame->info, &frame->pinfo);
21897         err |= __put_user(&frame->uc, &frame->puc);
21898         err |= copy_siginfo_to_user(&frame->info, info);
21899 -
21900 +       
21901         if (err)
21902                 goto give_sigsegv;
21903  
21904 @@ -467,7 +410,7 @@
21905                 /* Trampoline - the desired return ip is in the signal return page. */
21906                 return_ip = cris_signal_return_page + 6;
21907  
21908 -               /*
21909 +               /* 
21910                  * This is movu.w __NR_rt_sigreturn, r9; break 13;
21911                  *
21912                  * WE DO NOT USE IT ANY MORE! It's only left here for historical
21913 @@ -478,7 +421,7 @@
21914  
21915                 err |= __put_user(__NR_rt_sigreturn,
21916                                   (short __user*)(frame->retcode+2));
21917 -
21918 +               
21919                 err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
21920         }
21921  
21922 @@ -503,21 +446,24 @@
21923         /* Actually move the usp to reflect the stacked frame. */
21924         wrusp((unsigned long)frame);
21925  
21926 -       return;
21927 +       return 0;
21928  
21929  give_sigsegv:
21930         if (sig == SIGSEGV)
21931                 ka->sa.sa_handler = SIG_DFL;
21932 -
21933 +       
21934         force_sig(SIGSEGV, current);
21935 +        return -EFAULT;
21936  }
21937  
21938  /* Invoke a singal handler to, well, handle the signal. */
21939 -static inline void
21940 +static inline int
21941  handle_signal(int canrestart, unsigned long sig,
21942               siginfo_t *info, struct k_sigaction *ka,
21943                sigset_t *oldset, struct pt_regs * regs)
21944  {
21945 +       int ret;
21946 +
21947         /* Check if this got called from a system call. */
21948         if (canrestart) {
21949                 /* If so, check system call restarting. */
21950 @@ -561,19 +507,23 @@
21951  
21952         /* Set up the stack frame. */
21953         if (ka->sa.sa_flags & SA_SIGINFO)
21954 -               setup_rt_frame(sig, ka, info, oldset, regs);
21955 +               ret = setup_rt_frame(sig, ka, info, oldset, regs);
21956         else
21957 -               setup_frame(sig, ka, oldset, regs);
21958 +               ret = setup_frame(sig, ka, oldset, regs);
21959  
21960         if (ka->sa.sa_flags & SA_ONESHOT)
21961                 ka->sa.sa_handler = SIG_DFL;
21962  
21963 -       spin_lock_irq(&current->sighand->siglock);
21964 -       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
21965 -       if (!(ka->sa.sa_flags & SA_NODEFER))
21966 -               sigaddset(&current->blocked,sig);
21967 -       recalc_sigpending();
21968 -       spin_unlock_irq(&current->sighand->siglock);
21969 +       if (ret == 0) {
21970 +               spin_lock_irq(&current->sighand->siglock);
21971 +               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
21972 +               if (!(ka->sa.sa_flags & SA_NODEFER))
21973 +                       sigaddset(&current->blocked,sig);
21974 +               recalc_sigpending();
21975 +               spin_unlock_irq(&current->sighand->siglock);
21976 +       }
21977 +
21978 +       return ret;
21979  }
21980  
21981  /*
21982 @@ -587,12 +537,13 @@
21983   * we can use user_mode(regs) to see if we came directly from kernel or user
21984   * mode below.
21985   */
21986 -int
21987 -do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
21988 +void
21989 +do_signal(int canrestart, struct pt_regs *regs)
21990  {
21991         int signr;
21992         siginfo_t info;
21993          struct k_sigaction ka;
21994 +       sigset_t *oldset;
21995  
21996         /*
21997          * The common case should go fast, which is why this point is
21998 @@ -600,17 +551,27 @@
21999          * without doing anything.
22000          */
22001         if (!user_mode(regs))
22002 -               return 1;
22003 +               return;
22004  
22005 -       if (!oldset)
22006 +        if (test_thread_flag(TIF_RESTORE_SIGMASK))
22007 +               oldset = &current->saved_sigmask;
22008 +       else
22009                 oldset = &current->blocked;
22010  
22011         signr = get_signal_to_deliver(&info, &ka, regs, NULL);
22012 -
22013 +       
22014         if (signr > 0) {
22015 -               /* Deliver the signal. */
22016 -               handle_signal(canrestart, signr, &info, &ka, oldset, regs);
22017 -               return 1;
22018 +               /* Whee!  Actually deliver the signal.  */
22019 +               if (handle_signal(canrestart, signr, &info, &ka, oldset, regs)) {
22020 +                       /* a signal was successfully delivered; the saved
22021 +                        * sigmask will have been stored in the signal frame,
22022 +                        * and will be restored by sigreturn, so we can simply
22023 +                        * clear the TIF_RESTORE_SIGMASK flag */
22024 +                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
22025 +                               clear_thread_flag(TIF_RESTORE_SIGMASK);
22026 +               }
22027 +
22028 +               return;
22029         }
22030  
22031         /* Got here from a system call? */
22032 @@ -621,14 +582,19 @@
22033                     regs->r10 == -ERESTARTNOINTR) {
22034                         RESTART_CRIS_SYS(regs);
22035                 }
22036 -
22037 +               
22038                 if (regs->r10 == -ERESTART_RESTARTBLOCK){
22039                         regs->r10 = __NR_restart_syscall;
22040                         regs->erp -= 2;
22041                 }
22042         }
22043 -
22044 -       return 0;
22045 +       
22046 +       /* if there's no signal to deliver, we just put the saved sigmask
22047 +        * back */
22048 +       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
22049 +               clear_thread_flag(TIF_RESTORE_SIGMASK);
22050 +               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
22051 +       }
22052  }
22053  
22054  asmlinkage void
22055 @@ -651,7 +617,7 @@
22056         sys_kill(ti->task->pid, sig);
22057  }
22058  
22059 -void
22060 +void 
22061  keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
22062                  struct pt_regs *regs)
22063  {
22064 @@ -666,7 +632,7 @@
22065                 regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
22066                 /* Assume the SPC is valid and interesting. */
22067                 regs->spc = oldspc;
22068 -
22069 +               
22070         } else if (oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT))) {
22071                 /* If a h/w bp was set in the signal handler we need
22072                    to keep the S flag. */
22073 @@ -679,7 +645,7 @@
22074                    have forgotten all about it. */
22075                 regs->spc = 0;
22076                 regs->ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
22077 -       }
22078 +       }               
22079  }
22080  
22081  /* Set up the trampolines on the signal return page. */
22082 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/smp.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/smp.c
22083 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/smp.c  2007-01-10 20:10:37.000000000 +0100
22084 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/smp.c  2007-01-09 10:29:19.000000000 +0100
22085 @@ -20,6 +20,7 @@
22086  #define IPI_SCHEDULE 1
22087  #define IPI_CALL 2
22088  #define IPI_FLUSH_TLB 4
22089 +#define IPI_BOOT 8
22090  
22091  #define FLUSH_ALL (void*)0xffffffff
22092  
22093 @@ -30,6 +31,8 @@
22094  cpumask_t cpu_online_map = CPU_MASK_NONE;
22095  EXPORT_SYMBOL(cpu_online_map);
22096  cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
22097 +cpumask_t cpu_possible_map;
22098 +EXPORT_SYMBOL(cpu_possible_map);
22099  EXPORT_SYMBOL(phys_cpu_present_map);
22100  
22101  /* Variables used during SMP boot */
22102 @@ -55,7 +58,7 @@
22103  extern int setup_irq(int, struct irqaction *);
22104  
22105  /* Mode registers */
22106 -static unsigned long irq_regs[NR_CPUS] =
22107 +static unsigned long irq_regs[NR_CPUS] = 
22108  {
22109    regi_irq,
22110    regi_irq2
22111 @@ -97,6 +100,7 @@
22112  
22113         cpu_set(0, cpu_online_map);
22114         cpu_set(0, phys_cpu_present_map);
22115 +        cpu_set(0, cpu_possible_map);
22116  }
22117  
22118  void __init smp_cpus_done(unsigned int max_cpus)
22119 @@ -109,6 +113,7 @@
22120  {
22121         unsigned timeout;
22122         struct task_struct *idle;
22123 +       cpumask_t cpu_mask = CPU_MASK_NONE;
22124  
22125         idle = fork_idle(cpuid);
22126         if (IS_ERR(idle))
22127 @@ -120,6 +125,12 @@
22128         smp_init_current_idle_thread = task_thread_info(idle);
22129         cpu_now_booting = cpuid;
22130  
22131 +        /* Kick it */
22132 +       cpu_set(cpuid, cpu_online_map);
22133 +       cpu_set(cpuid, cpu_mask);
22134 +       send_ipi(IPI_BOOT, 0, cpu_mask);
22135 +       cpu_clear(cpuid, cpu_online_map);
22136 +
22137         /* Wait for CPU to come online */
22138         for (timeout = 0; timeout < 10000; timeout++) {
22139                 if(cpu_online(cpuid)) {
22140 @@ -142,7 +153,7 @@
22141   * specific stuff such as the local timer and the MMU. */
22142  void __init smp_callin(void)
22143  {
22144 -       extern void cpu_idle(void);
22145 +       extern void cpu_idle(void);     
22146  
22147         int cpu = cpu_now_booting;
22148         reg_intr_vect_rw_mask vect_mask = {0};
22149 @@ -190,8 +201,8 @@
22150  
22151  /* cache_decay_ticks is used by the scheduler to decide if a process
22152   * is "hot" on one CPU. A higher value means a higher penalty to move
22153 - * a process to another CPU. Our cache is rather small so we report
22154 - * 1 tick.
22155 + * a process to another CPU. Our cache is rather small so we report 
22156 + * 1 tick. 
22157   */
22158  unsigned long cache_decay_ticks = 1;
22159  
22160 @@ -205,14 +216,14 @@
22161  {
22162         cpumask_t cpu_mask = CPU_MASK_NONE;
22163         cpu_set(cpu, cpu_mask);
22164 -       send_ipi(IPI_SCHEDULE, 0, cpu_mask);
22165 +       send_ipi(IPI_SCHEDULE, 0, cpu_mask);    
22166  }
22167  
22168  /* TLB flushing
22169   *
22170   * Flush needs to be done on the local CPU and on any other CPU that
22171   * may have the same mapping. The mm->cpu_vm_mask is used to keep track
22172 - * of which CPUs that a specific process has been executed on.
22173 + * of which CPUs that a specific process has been executed on. 
22174   */
22175  void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned long addr)
22176  {
22177 @@ -244,7 +255,7 @@
22178         cpu_set(smp_processor_id(), mm->cpu_vm_mask);
22179  }
22180  
22181 -void flush_tlb_page(struct vm_area_struct *vma,
22182 +void flush_tlb_page(struct vm_area_struct *vma, 
22183                            unsigned long addr)
22184  {
22185         __flush_tlb_page(vma, addr);
22186 @@ -252,8 +263,8 @@
22187  }
22188  
22189  /* Inter processor interrupts
22190 - *
22191 - * The IPIs are used for:
22192 + * 
22193 + * The IPIs are used for: 
22194   *   * Force a schedule on a CPU
22195   *   * FLush TLB on other CPUs
22196   *   * Call a function on other CPUs
22197 @@ -341,7 +352,7 @@
22198                      else if (flush_vma == FLUSH_ALL)
22199                         __flush_tlb_mm(flush_mm);
22200                      else
22201 -                       __flush_tlb_page(flush_vma, flush_addr);
22202 +                       __flush_tlb_page(flush_vma, flush_addr);  
22203         }
22204  
22205         ipi.vector = 0;
22206 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/time.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/time.c
22207 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/time.c 2007-01-10 20:10:37.000000000 +0100
22208 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/time.c 2007-01-09 10:29:19.000000000 +0100
22209 @@ -1,4 +1,4 @@
22210 -/* $Id: time.c,v 1.19 2005/04/29 05:40:09 starvik Exp $
22211 +/* $Id: time.c,v 1.25 2007/01/09 09:29:19 starvik Exp $
22212   *
22213   *  linux/arch/cris/arch-v32/kernel/time.c
22214   *
22215 @@ -14,12 +14,14 @@
22216  #include <linux/sched.h>
22217  #include <linux/init.h>
22218  #include <linux/threads.h>
22219 +#include <linux/cpufreq.h>
22220  #include <asm/types.h>
22221  #include <asm/signal.h>
22222  #include <asm/io.h>
22223  #include <asm/delay.h>
22224  #include <asm/rtc.h>
22225  #include <asm/irq.h>
22226 +#include <asm/irq_regs.h>
22227  
22228  #include <asm/arch/hwregs/reg_map.h>
22229  #include <asm/arch/hwregs/reg_rdwr.h>
22230 @@ -31,7 +33,7 @@
22231  #define ETRAX_WD_HZ       763 /* watchdog counts at 763 Hz */
22232  #define ETRAX_WD_CNT      ((2*ETRAX_WD_HZ)/HZ + 1) /* Number of 763 counts before watchdog bites */
22233  
22234 -unsigned long timer_regs[NR_CPUS] =
22235 +unsigned long timer_regs[NR_CPUS] = 
22236  {
22237    regi_timer,
22238  #ifdef CONFIG_SMP
22239 @@ -44,6 +46,15 @@
22240  extern int setup_irq(int, struct irqaction *);
22241  extern int have_rtc;
22242  
22243 +#ifdef CONFIG_CPU_FREQ
22244 +static int
22245 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
22246 +
22247 +static struct notifier_block cris_time_freq_notifier_block = {
22248 +        .notifier_call  = cris_time_freq_notifier
22249 +};
22250 +#endif
22251 +
22252  unsigned long get_ns_in_jiffie(void)
22253  {
22254         reg_timer_r_tmr0_data data;
22255 @@ -63,7 +74,7 @@
22256         static unsigned long jiffies_p = 0;
22257  
22258         /*
22259 -        * cache volatile jiffies temporarily; we have IRQs turned off.
22260 +        * cache volatile jiffies temporarily; we have IRQs turned off. 
22261          */
22262         unsigned long jiffies_t;
22263  
22264 @@ -82,7 +93,7 @@
22265          */
22266         if( jiffies_t == jiffies_p ) {
22267                 if( count > count_p ) {
22268 -                       /* Timer wrapped, use new count and prescale
22269 +                       /* Timer wrapped, use new count and prescale 
22270                          * increase the time corresponding to one jiffie
22271                          */
22272                         usec_count = 1000000/HZ;
22273 @@ -101,7 +112,7 @@
22274   * The watchdog timer is an 8-bit timer with a configurable start value.
22275   * Once started the whatchdog counts downwards with a frequency of 763 Hz
22276   * (100/131072 MHz). When the watchdog counts down to 1, it generates an
22277 - * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
22278 + * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the 
22279   * chip.
22280   */
22281  /* This gives us 1.3 ms to do something useful when the NMI comes */
22282 @@ -124,7 +135,7 @@
22283  {
22284  #if defined(CONFIG_ETRAX_WATCHDOG)
22285         reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
22286 -
22287 +       
22288         /* only keep watchdog happy as long as we have memory left! */
22289         if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
22290                 /* reset the watchdog with the inverse of the old key */
22291 @@ -139,7 +150,7 @@
22292  
22293  /* stop the watchdog - we still need the correct key */
22294  
22295 -void
22296 +void 
22297  stop_watchdog(void)
22298  {
22299  #if defined(CONFIG_ETRAX_WATCHDOG)
22300 @@ -149,7 +160,7 @@
22301         wd_ctrl.cmd = regk_timer_stop;
22302         wd_ctrl.key = watchdog_key;
22303         REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
22304 -#endif
22305 +#endif 
22306  }
22307  
22308  extern void show_registers(struct pt_regs *regs);
22309 @@ -160,7 +171,8 @@
22310  #if defined(CONFIG_ETRAX_WATCHDOG)
22311         extern int cause_of_death;
22312  
22313 -       raw_printk("Watchdog bite\n");
22314 +       oops_in_progress = 1;
22315 +       printk("Watchdog bite\n");
22316  
22317         /* Check if forced restart or unexpected watchdog */
22318         if (cause_of_death == 0xbedead) {
22319 @@ -169,8 +181,9 @@
22320  
22321         /* Unexpected watchdog, stop the watchdog and dump registers*/
22322         stop_watchdog();
22323 -       raw_printk("Oops: bitten by watchdog\n");
22324 -        show_registers(regs);
22325 +       printk("Oops: bitten by watchdog\n");
22326 +       show_registers(regs);
22327 +       oops_in_progress = 0;
22328  #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22329         reset_watchdog();
22330  #endif
22331 @@ -191,8 +204,9 @@
22332  extern void cris_do_profile(struct pt_regs *regs);
22333  
22334  static inline irqreturn_t
22335 -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
22336 +timer_interrupt(int irq, void *dev_id)
22337  {
22338 +       struct pt_regs* regs = get_irq_regs();
22339         int cpu = smp_processor_id();
22340         reg_timer_r_masked_intr masked_intr;
22341         reg_timer_rw_ack_intr ack_intr = { 0 };
22342 @@ -226,7 +240,7 @@
22343          * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
22344          * called as close as possible to 500 ms before the new second starts.
22345          *
22346 -        * The division here is not time critical since it will run once in
22347 +        * The division here is not time critical since it will run once in 
22348          * 11 minutes
22349          */
22350         if ((time_status & STA_UNSYNC) == 0 &&
22351 @@ -246,7 +260,7 @@
22352   */
22353  
22354  static struct irqaction irq_timer  = {
22355 -       .mask = timer_interrupt,
22356 +       .handler = timer_interrupt,
22357         .flags = IRQF_SHARED | IRQF_DISABLED,
22358         .mask = CPU_MASK_NONE,
22359         .name = "timer"
22360 @@ -262,7 +276,7 @@
22361  
22362         /* Setup the etrax timers
22363          * Base frequency is 100MHz, divider 1000000 -> 100 HZ
22364 -        * We use timer0, so timer1 is free.
22365 +        * We use timer0, so timer1 is free. 
22366          * The trig timer is used by the fasttimer API if enabled.
22367          */
22368  
22369 @@ -284,11 +298,11 @@
22370  {
22371         reg_intr_vect_rw_mask intr_mask;
22372  
22373 -       /* probe for the RTC and read it if it exists
22374 -        * Before the RTC can be probed the loops_per_usec variable needs
22375 -        * to be initialized to make usleep work. A better value for
22376 -        * loops_per_usec is calculated by the kernel later once the
22377 -        * clock has started.
22378 +       /* probe for the RTC and read it if it exists 
22379 +        * Before the RTC can be probed the loops_per_usec variable needs 
22380 +        * to be initialized to make usleep work. A better value for 
22381 +        * loops_per_usec is calculated by the kernel later once the 
22382 +        * clock has started.  
22383          */
22384         loops_per_usec = 50;
22385  
22386 @@ -297,7 +311,7 @@
22387                 xtime.tv_sec = 0;
22388                 xtime.tv_nsec = 0;
22389                 have_rtc = 0;
22390 -       } else {
22391 +       } else {                
22392                 /* get the current time */
22393                 have_rtc = 1;
22394                 update_xtime_from_cmos();
22395 @@ -316,9 +330,9 @@
22396         intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
22397         intr_mask.timer = 1;
22398         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
22399 -
22400 +  
22401         /* now actually register the timer irq handler that calls timer_interrupt() */
22402 -
22403 +       
22404         setup_irq(TIMER_INTR_VECT, &irq_timer);
22405  
22406         /* enable watchdog if we should use one */
22407 @@ -330,10 +344,7 @@
22408         /* If we use the hardware watchdog, we want to trap it as an NMI
22409            and dump registers before it resets us.  For this to happen, we
22410            must set the "m" NMI enable flag (which once set, is unset only
22411 -          when an NMI is taken).
22412 -
22413 -          The same goes for the external NMI, but that doesn't have any
22414 -          driver or infrastructure support yet.  */
22415 +          when an NMI is taken). */
22416          {
22417            unsigned long flags;
22418            local_save_flags(flags);
22419 @@ -341,4 +352,27 @@
22420            local_irq_restore(flags);
22421          }
22422  #endif
22423 +
22424 +#ifdef CONFIG_CPU_FREQ
22425 +        cpufreq_register_notifier(&cris_time_freq_notifier_block,
22426 +                                  CPUFREQ_TRANSITION_NOTIFIER);
22427 +#endif
22428 +}
22429 +
22430 +#ifdef CONFIG_CPU_FREQ
22431 +static int
22432 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
22433 +{
22434 +       struct cpufreq_freqs *freqs = data;
22435 +       if (val == CPUFREQ_POSTCHANGE) {
22436 +               reg_timer_r_tmr0_data data;
22437 +               reg_timer_rw_tmr0_div div = (freqs->new * 500) / HZ;
22438 +               do
22439 +               {
22440 +                       data = REG_RD(timer, timer_regs[freqs->cpu], r_tmr0_data);
22441 +               } while (data > 20);
22442 +               REG_WR(timer, timer_regs[freqs->cpu], rw_tmr0_div, div);
22443 +       }
22444 +       return 0;
22445  }
22446 +#endif
22447 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/traps.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/traps.c
22448 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/traps.c        2007-01-10 20:10:37.000000000 +0100
22449 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/traps.c        2006-12-11 14:04:24.000000000 +0100
22450 @@ -1,50 +1,43 @@
22451  /*
22452 - * Copyright (C) 2003, Axis Communications AB.
22453 + * Copyright (C) 2003-2006, Axis Communications AB.
22454   */
22455  
22456  #include <linux/ptrace.h>
22457  #include <asm/uaccess.h>
22458 -
22459  #include <asm/arch/hwregs/supp_reg.h>
22460 -
22461 -extern void reset_watchdog(void);
22462 -extern void stop_watchdog(void);
22463 -
22464 -extern int raw_printk(const char *fmt, ...);
22465 +#include <asm/arch/hwregs/intr_vect_defs.h>
22466  
22467  void
22468  show_registers(struct pt_regs *regs)
22469  {
22470         /*
22471          * It's possible to use either the USP register or current->thread.usp.
22472 -        * USP might not correspond to the current proccess for all cases this
22473 +        * USP might not correspond to the current process for all cases this
22474          * function is called, and current->thread.usp isn't up to date for the
22475 -        * current proccess. Experience shows that using USP is the way to go.
22476 +        * current process. Experience shows that using USP is the way to go.
22477          */
22478 -       unsigned long usp;
22479 +       unsigned long usp = rdusp();
22480         unsigned long d_mmu_cause;
22481         unsigned long i_mmu_cause;
22482  
22483 -       usp = rdusp();
22484 +       printk("CPU: %d\n", smp_processor_id());
22485  
22486 -       raw_printk("CPU: %d\n", smp_processor_id());
22487 +       printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
22488 +              regs->erp, regs->srp, regs->ccs, usp, regs->mof);
22489  
22490 -       raw_printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
22491 -               regs->erp, regs->srp, regs->ccs, usp, regs->mof);
22492 +       printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
22493 +              regs->r0, regs->r1, regs->r2, regs->r3);
22494  
22495 -       raw_printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
22496 -               regs->r0, regs->r1, regs->r2, regs->r3);
22497 +       printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
22498 +              regs->r4, regs->r5, regs->r6, regs->r7);
22499  
22500 -       raw_printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
22501 -               regs->r4, regs->r5, regs->r6, regs->r7);
22502 +       printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
22503 +              regs->r8, regs->r9, regs->r10, regs->r11);
22504  
22505 -       raw_printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
22506 -               regs->r8, regs->r9, regs->r10, regs->r11);
22507 +       printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
22508 +              regs->r12, regs->r13, regs->orig_r10, regs->acr);
22509  
22510 -       raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
22511 -               regs->r12, regs->r13, regs->orig_r10, regs->acr);
22512 -
22513 -       raw_printk("sp: %08lx\n", regs);
22514 +       printk(" sp: %08lx\n", (unsigned long)regs);
22515  
22516         SUPP_BANK_SEL(BANK_IM);
22517         SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause);
22518 @@ -52,18 +45,20 @@
22519         SUPP_BANK_SEL(BANK_DM);
22520         SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause);
22521  
22522 -       raw_printk("       Data MMU Cause: %08lx\n", d_mmu_cause);
22523 -       raw_printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
22524 +       printk("       Data MMU Cause: %08lx\n", d_mmu_cause);
22525 +       printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
22526  
22527 -       raw_printk("Process %s (pid: %d, stackpage: %08lx)\n",
22528 -               current->comm, current->pid, (unsigned long) current);
22529 +       printk("Process %s (pid: %d, stackpage=%08lx)\n",
22530 +              current->comm, current->pid, (unsigned long)current);
22531  
22532 -       /* Show additional info if in kernel-mode. */
22533 +       /*
22534 +        * When in-kernel, we also print out the stack and code at the
22535 +        * time of the fault..
22536 +        */
22537         if (!user_mode(regs)) {
22538                 int i;
22539 -               unsigned char c;
22540  
22541 -               show_stack(NULL, (unsigned long *) usp);
22542 +               show_stack(NULL, (unsigned long *)usp);
22543  
22544                 /*
22545                  * If the previous stack-dump wasn't a kernel one, dump the
22546 @@ -72,7 +67,7 @@
22547                 if (usp != 0)
22548                         show_stack(NULL, NULL);
22549  
22550 -               raw_printk("\nCode: ");
22551 +               printk("\nCode: ");
22552  
22553                 if (regs->erp < PAGE_OFFSET)
22554                         goto bad_value;
22555 @@ -84,76 +79,65 @@
22556                  * instruction decoding should be in sync at the interesting
22557                  * point, but small enough to fit on a row. The regs->erp
22558                  * location is pointed out in a ksymoops-friendly way by
22559 -                * wrapping the byte for that address in parenthesis.
22560 +                * wrapping the byte for that address in parenthesises.
22561                  */
22562                 for (i = -12; i < 12; i++) {
22563 -                       if (__get_user(c, &((unsigned char *) regs->erp)[i])) {
22564 +                       unsigned char c;
22565 +
22566 +                       if (__get_user(c, &((unsigned char *)regs->erp)[i])) {
22567  bad_value:
22568 -                               raw_printk(" Bad IP value.");
22569 +                               printk(" Bad IP value.");
22570                                 break;
22571                         }
22572  
22573                         if (i == 0)
22574 -                               raw_printk("(%02x) ", c);
22575 +                               printk("(%02x) ", c);
22576                         else
22577 -                               raw_printk("%02x ", c);
22578 +                               printk("%02x ", c);
22579                 }
22580 -
22581 -               raw_printk("\n");
22582 +               printk("\n");
22583         }
22584  }
22585  
22586 -/*
22587 - * This gets called from entry.S when the watchdog has bitten. Show something
22588 - * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
22589 - * halt instead of reboot.
22590 - */
22591  void
22592 -watchdog_bite_hook(struct pt_regs *regs)
22593 +arch_enable_nmi(void)
22594  {
22595 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22596 -       local_irq_disable();
22597 -       stop_watchdog();
22598 -       show_registers(regs);
22599 -
22600 -       while (1)
22601 -               ; /* Do nothing. */
22602 -#else
22603 -       show_registers(regs);
22604 -#endif
22605 +       unsigned long flags;
22606 +
22607 +       local_save_flags(flags);
22608 +       flags |= (1 << 30); /* NMI M flag is at bit 30 */
22609 +       local_irq_restore(flags);
22610  }
22611  
22612 -/* This is normally the Oops function. */
22613 -void
22614 -die_if_kernel(const char *str, struct pt_regs *regs, long err)
22615 +extern void (*nmi_handler)(struct pt_regs*);
22616 +void handle_nmi(struct pt_regs* regs)
22617  {
22618 -       if (user_mode(regs))
22619 -               return;
22620 +  reg_intr_vect_r_nmi r;
22621  
22622 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22623 -       /*
22624 -        * This printout might take too long and could trigger
22625 -        * the watchdog normally. If NICE_DOGGY is set, simply
22626 -        * stop the watchdog during the printout.
22627 -        */
22628 -       stop_watchdog();
22629 -#endif
22630 -
22631 -       raw_printk("%s: %04lx\n", str, err & 0xffff);
22632 +  if (nmi_handler)
22633 +    nmi_handler(regs);
22634  
22635 -       show_registers(regs);
22636 -
22637 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22638 -       reset_watchdog();
22639 -#endif
22640 -
22641 -       do_exit(SIGSEGV);
22642 +  /* Wait until nmi is no longer active. */
22643 +  do {
22644 +         r = REG_RD(intr_vect, regi_irq, r_nmi);
22645 +  } while (r.ext == regk_intr_vect_on);
22646  }
22647  
22648 -void arch_enable_nmi(void)
22649 +#ifdef CONFIG_DEBUG_BUGVERBOSE
22650 +void
22651 +handle_BUG(struct pt_regs *regs)
22652  {
22653 -       unsigned long flags;
22654 -       local_save_flags(flags);
22655 -       flags |= (1<<30); /* NMI M flag is at bit 30 */
22656 -       local_irq_restore(flags);
22657 +       struct bug_frame f;
22658 +       unsigned char c;
22659 +       unsigned long erp = regs->erp;
22660 +
22661 +       if (__copy_from_user(&f, (const void __user *)(erp - 8), sizeof f))
22662 +               return;
22663 +       if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
22664 +               return;
22665 +       if (__get_user(c, f.filename))
22666 +               f.filename = "<bad filename>";
22667 +
22668 +       printk("kernel BUG at %s:%d!\n", f.filename, f.line);
22669  }
22670 +#endif
22671 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.c
22672 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.c     2007-01-10 20:10:37.000000000 +0100
22673 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.c     1970-01-01 01:00:00.000000000 +0100
22674 @@ -1,96 +0,0 @@
22675 -// $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $
22676 -//
22677 -// Call simulator hook. This is the part running in the
22678 -// simulated program.
22679 -//
22680 -
22681 -#include "vcs_hook.h"
22682 -#include <stdarg.h>
22683 -#include <asm/arch-v32/hwregs/reg_map.h>
22684 -#include <asm/arch-v32/hwregs/intr_vect_defs.h>
22685 -
22686 -#define HOOK_TRIG_ADDR     0xb7000000   /* hook cvlog model reg address */
22687 -#define HOOK_MEM_BASE_ADDR 0xa0000000   /* csp4 (shared mem) base addr */
22688 -
22689 -#define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset]
22690 -#define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset]
22691 -#define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0)
22692 -#define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset]
22693 -
22694 -
22695 -// ------------------------------------------------------------------ hook_call
22696 -int hook_call( unsigned id, unsigned pcnt, ...) {
22697 -  va_list ap;
22698 -  unsigned i;
22699 -  unsigned ret;
22700 -#ifdef USING_SOS
22701 -  PREEMPT_OFF_SAVE();
22702 -#endif
22703 -
22704 -  // pass parameters
22705 -  HOOK_DATA(0) = id;
22706 -
22707 -  /* Have to make hook_print_str a special case since we call with a
22708 -     parameter of byte type. Should perhaps be a separate
22709 -     hook_call. */
22710 -
22711 -  if (id == hook_print_str) {
22712 -    int i;
22713 -    char *str;
22714 -
22715 -    HOOK_DATA(1) = pcnt;
22716 -
22717 -    va_start(ap, pcnt);
22718 -    str = (char*)va_arg(ap,unsigned);
22719 -
22720 -    for (i=0; i!=pcnt; i++) {
22721 -      HOOK_DATA_BYTE(8+i) = str[i];
22722 -    }
22723 -    HOOK_DATA_BYTE(8+i) = 0;   /* null byte */
22724 -  }
22725 -  else {
22726 -    va_start(ap, pcnt);
22727 -    for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned);
22728 -    va_end(ap);
22729 -  }
22730 -
22731 -  // read from mem to make sure data has propagated to memory before trigging
22732 -  *((volatile unsigned*) HOOK_MEM_BASE_ADDR);
22733 -
22734 -  // trigger hook
22735 -  HOOK_TRIG(id);
22736 -
22737 -  // wait for call to finish
22738 -  while( VHOOK_DATA(0) > 0 ) {}
22739 -
22740 -  // extract return value
22741 -
22742 -  ret = VHOOK_DATA(1);
22743 -
22744 -#ifdef USING_SOS
22745 -  PREEMPT_RESTORE();
22746 -#endif
22747 -  return ret;
22748 -}
22749 -
22750 -unsigned
22751 -hook_buf(unsigned i)
22752 -{
22753 -  return (HOOK_DATA(i));
22754 -}
22755 -
22756 -void print_str( const char *str ) {
22757 -  int i;
22758 -  for (i=1; str[i]; i++);         /* find null at end of string */
22759 -  hook_call(hook_print_str, i, str);
22760 -}
22761 -
22762 -// --------------------------------------------------------------- CPU_KICK_DOG
22763 -void CPU_KICK_DOG(void) {
22764 -  (void) hook_call( hook_kick_dog, 0 );
22765 -}
22766 -
22767 -// ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT
22768 -void CPU_WATCHDOG_TIMEOUT( unsigned t ) {
22769 -  (void) hook_call( hook_dog_timeout, 1, t );
22770 -}
22771 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.h linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.h
22772 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.h     2007-01-10 20:10:37.000000000 +0100
22773 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.h     1970-01-01 01:00:00.000000000 +0100
22774 @@ -1,42 +0,0 @@
22775 -// $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $
22776 -//
22777 -// Call simulator hook functions
22778 -
22779 -#ifndef HOOK_H
22780 -#define HOOK_H
22781 -
22782 -int hook_call( unsigned id, unsigned pcnt, ...);
22783 -
22784 -enum hook_ids {
22785 -  hook_debug_on = 1,
22786 -  hook_debug_off,
22787 -  hook_stop_sim_ok,
22788 -  hook_stop_sim_fail,
22789 -  hook_alloc_shared,
22790 -  hook_ptr_shared,
22791 -  hook_free_shared,
22792 -  hook_file2shared,
22793 -  hook_cmp_shared,
22794 -  hook_print_params,
22795 -  hook_sim_time,
22796 -  hook_stop_sim,
22797 -  hook_kick_dog,
22798 -  hook_dog_timeout,
22799 -  hook_rand,
22800 -  hook_srand,
22801 -  hook_rand_range,
22802 -  hook_print_str,
22803 -  hook_print_hex,
22804 -  hook_cmp_offset_shared,
22805 -  hook_fill_random_shared,
22806 -  hook_alloc_random_data,
22807 -  hook_calloc_random_data,
22808 -  hook_print_int,
22809 -  hook_print_uint,
22810 -  hook_fputc,
22811 -  hook_init_fd,
22812 -  hook_sbrk
22813 -
22814 -};
22815 -
22816 -#endif
22817 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/lib/Makefile
22818 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/Makefile  2007-01-10 20:10:37.000000000 +0100
22819 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/Makefile  2006-10-11 19:29:20.000000000 +0200
22820 @@ -2,5 +2,5 @@
22821  # Makefile for Etrax-specific library files..
22822  #
22823  
22824 -lib-y  = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o
22825 +lib-y  = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o delay.o
22826  
22827 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksum.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksum.S
22828 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksum.S        2007-01-10 20:10:37.000000000 +0100
22829 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksum.S        2005-08-15 15:53:12.000000000 +0200
22830 @@ -7,15 +7,15 @@
22831  
22832         .globl  csum_partial
22833  csum_partial:
22834 -
22835 +       
22836         ;; r10 - src
22837         ;; r11 - length
22838         ;; r12 - checksum
22839  
22840         ;; check for breakeven length between movem and normal word looping versions
22841 -       ;; we also do _NOT_ want to compute a checksum over more than the
22842 +       ;; we also do _NOT_ want to compute a checksum over more than the 
22843         ;; actual length when length < 40
22844 -
22845 +       
22846         cmpu.w  80,$r11
22847         blo     _word_loop
22848         nop
22849 @@ -24,17 +24,17 @@
22850         ;; this overhead is why we have a check above for breakeven length
22851         ;; only r0 - r8 have to be saved, the other ones are clobber-able
22852         ;; according to the ABI
22853 -
22854 +       
22855         subq    9*4,$sp
22856         subq    10*4,$r11       ; update length for the first loop
22857         movem   $r8,[$sp]
22858 -
22859 +       
22860         ;; do a movem checksum
22861  
22862  _mloop:        movem   [$r10+],$r9     ; read 10 longwords
22863  
22864         ;; perform dword checksumming on the 10 longwords
22865 -
22866 +       
22867         add.d   $r0,$r12
22868         addc    $r1,$r12
22869         addc    $r2,$r12
22870 @@ -48,9 +48,8 @@
22871  
22872         ;; fold the carry into the checksum, to avoid having to loop the carry
22873         ;; back into the top
22874 -
22875 +       
22876         addc    0,$r12
22877 -       addc    0,$r12          ; do it again, since we might have generated a carry
22878  
22879         subq    10*4,$r11
22880         bge     _mloop
22881 @@ -68,34 +67,30 @@
22882  
22883         ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
22884         ;; r9 and r13 can be used as temporaries.
22885 -
22886 +       
22887         moveq   -1,$r9          ; put 0xffff in r9, faster than move.d 0xffff,r9
22888         lsrq    16,$r9
22889 -
22890 +       
22891         move.d  $r12,$r13
22892         lsrq    16,$r13         ; r13 = checksum >> 16
22893         and.d   $r9,$r12                ; checksum = checksum & 0xffff
22894         add.d   $r13,$r12               ; checksum += r13
22895 -       move.d  $r12,$r13               ; do the same again, maybe we got a carry last add
22896 -       lsrq    16,$r13
22897 -       and.d   $r9,$r12
22898 -       add.d   $r13,$r12
22899  
22900  _no_fold:
22901         cmpq    2,$r11
22902         blt     _no_words
22903         nop
22904 -
22905 +       
22906         ;; checksum the rest of the words
22907 -
22908 +       
22909         subq    2,$r11
22910 -
22911 +       
22912  _wloop:        subq    2,$r11
22913         bge     _wloop
22914         addu.w  [$r10+],$r12
22915 -
22916 +       
22917         addq    2,$r11
22918 -
22919 +               
22920  _no_words:
22921         ;; see if we have one odd byte more
22922         cmpq    1,$r11
22923 @@ -104,7 +99,7 @@
22924         ret
22925         move.d  $r12,$r10
22926  
22927 -_do_byte:
22928 +_do_byte:      
22929         ;; copy and checksum the last byte
22930         addu.b  [$r10],$r12
22931         ret
22932 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksumcopy.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksumcopy.S
22933 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksumcopy.S    2007-01-10 20:10:37.000000000 +0100
22934 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksumcopy.S    2005-08-15 15:53:12.000000000 +0200
22935 @@ -3,23 +3,23 @@
22936   * Copyright (c) 1998, 2001, 2003 Axis Communications AB
22937   *
22938   * Authors:    Bjorn Wesen
22939 - *
22940 + * 
22941   * csum_partial_copy_nocheck(const char *src, char *dst,
22942   *                          int len, unsigned int sum)
22943   */
22944  
22945         .globl  csum_partial_copy_nocheck
22946 -csum_partial_copy_nocheck:
22947 -
22948 +csum_partial_copy_nocheck:     
22949 +       
22950         ;; r10 - src
22951         ;; r11 - dst
22952         ;; r12 - length
22953         ;; r13 - checksum
22954  
22955         ;; check for breakeven length between movem and normal word looping versions
22956 -       ;; we also do _NOT_ want to compute a checksum over more than the
22957 +       ;; we also do _NOT_ want to compute a checksum over more than the 
22958         ;; actual length when length < 40
22959 -
22960 +       
22961         cmpu.w  80,$r12
22962         blo     _word_loop
22963         nop
22964 @@ -28,19 +28,19 @@
22965         ;; this overhead is why we have a check above for breakeven length
22966         ;; only r0 - r8 have to be saved, the other ones are clobber-able
22967         ;; according to the ABI
22968 -
22969 +       
22970         subq    9*4,$sp
22971         subq    10*4,$r12       ; update length for the first loop
22972         movem   $r8,[$sp]
22973 -
22974 +       
22975         ;; do a movem copy and checksum
22976 -
22977 +       
22978  1:     ;; A failing userspace access (the read) will have this as PC.
22979  _mloop:        movem   [$r10+],$r9     ; read 10 longwords
22980         movem   $r9,[$r11+]     ; write 10 longwords
22981  
22982         ;; perform dword checksumming on the 10 longwords
22983 -
22984 +       
22985         add.d   $r0,$r13
22986         addc    $r1,$r13
22987         addc    $r2,$r13
22988 @@ -54,9 +54,8 @@
22989  
22990         ;; fold the carry into the checksum, to avoid having to loop the carry
22991         ;; back into the top
22992 -
22993 +       
22994         addc    0,$r13
22995 -       addc    0,$r13          ; do it again, since we might have generated a carry
22996  
22997         subq    10*4,$r12
22998         bge     _mloop
22999 @@ -74,34 +73,30 @@
23000  
23001         ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
23002         ;; r9 can be used as temporary.
23003 -
23004 +       
23005         move.d  $r13,$r9
23006         lsrq    16,$r9          ; r0 = checksum >> 16
23007         and.d   0xffff,$r13     ; checksum = checksum & 0xffff
23008         add.d   $r9,$r13        ; checksum += r0
23009 -       move.d  $r13,$r9        ; do the same again, maybe we got a carry last add
23010 -       lsrq    16,$r9
23011 -       and.d   0xffff,$r13
23012 -       add.d   $r9,$r13
23013 -
23014 +       
23015  _no_fold:
23016         cmpq    2,$r12
23017         blt     _no_words
23018         nop
23019 -
23020 +       
23021         ;; copy and checksum the rest of the words
23022 -
23023 +       
23024         subq    2,$r12
23025 -
23026 +       
23027  2:     ;; A failing userspace access for the read below will have this as PC.
23028  _wloop:        move.w  [$r10+],$r9
23029         addu.w  $r9,$r13
23030         subq    2,$r12
23031         bge     _wloop
23032         move.w  $r9,[$r11+]
23033 -
23034 +       
23035         addq    2,$r12
23036 -
23037 +               
23038  _no_words:
23039         ;; see if we have one odd byte more
23040         cmpq    1,$r12
23041 @@ -110,7 +105,7 @@
23042         ret
23043         move.d  $r13,$r10
23044  
23045 -_do_byte:
23046 +_do_byte:      
23047         ;; copy and checksum the last byte
23048  3:     ;; A failing userspace access for the read below will have this as PC.
23049         move.b  [$r10],$r9
23050 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/delay.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/delay.c
23051 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/delay.c   1970-01-01 01:00:00.000000000 +0100
23052 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/delay.c   2006-10-16 01:08:41.000000000 +0200
23053 @@ -0,0 +1,28 @@
23054 +/*
23055 + * Precise Delay Loops for ETRAX FS
23056 + *
23057 + * Copyright (C) 2006 Axis Communications AB.
23058 + *
23059 + */
23060 +
23061 +#include <asm/arch/hwregs/reg_map.h>
23062 +#include <asm/arch/hwregs/reg_rdwr.h>
23063 +#include <asm/arch/hwregs/timer_defs.h>
23064 +#include <linux/types.h>
23065 +#include <linux/delay.h>
23066 +#include <linux/module.h>
23067 +
23068 +/*
23069 + * On ETRAX FS, we can check the free-running read-only 100MHz timer
23070 + * getting 32-bit 10ns precision, theoretically good for 42.94967295
23071 + * seconds.  Unsigned arithmetic and careful expression handles
23072 + * wrapping.
23073 + */
23074 +
23075 +void cris_delay10ns(u32 n10ns)
23076 +{
23077 +       u32 t0 = REG_RD(timer, regi_timer, r_time);
23078 +       while (REG_RD(timer, regi_timer, r_time) - t0 < n10ns)
23079 +               ;
23080 +}
23081 +EXPORT_SYMBOL(cris_delay10ns);
23082 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/dram_init.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/dram_init.S
23083 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/dram_init.S       2007-01-10 20:10:37.000000000 +0100
23084 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/dram_init.S       2006-11-28 11:06:19.000000000 +0100
23085 @@ -1,14 +1,14 @@
23086 -/* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $
23087 - *
23088 +/* $Id: dram_init.S,v 1.9 2006/11/28 10:06:19 ricardw Exp $
23089 + * 
23090   * DRAM/SDRAM initialization - alter with care
23091   * This file is intended to be included from other assembler files
23092   *
23093 - * Note: This file may not modify r8 or r9 because they are used to
23094 - * carry information from the decompresser to the kernel
23095 + * Note: This file may not modify r8 .. r12  because they are used to 
23096 + * carry information from the decompressor to the kernel
23097   *
23098   * Copyright (C) 2000-2003 Axis Communications AB
23099   *
23100 - * Authors:  Mikael Starvik (starvik@axis.com)
23101 + * Authors:  Mikael Starvik (starvik@axis.com) 
23102   */
23103  
23104  /* Just to be certain the config file is included, we include it here
23105 @@ -18,13 +18,13 @@
23106  
23107  #include <asm/arch/hwregs/asm/reg_map_asm.h>
23108  #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
23109 -
23110 -       ;; WARNING! The registers r8 and r9 are used as parameters carrying
23111 -       ;; information from the decompressor (if the kernel was compressed).
23112 +       
23113 +       ;; WARNING! The registers r8 .. r12 are used as parameters carrying
23114 +       ;; information from the decompressor (if the kernel was compressed). 
23115         ;; They should not be used in the code below.
23116  
23117         ; Refer to BIF MDS for a description of SDRAM initialization
23118 -
23119 +       
23120         ; Bank configuration
23121         move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0), $r0
23122         move.d   CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
23123 @@ -33,7 +33,7 @@
23124         move.d   CONFIG_ETRAX_SDRAM_GRP1_CONFIG, $r1
23125         move.d   $r1, [$r0]
23126  
23127 -       ; Calculate value of mrs_data
23128 +       ; Calculate value of mrs_data 
23129         ; CAS latency = 2 && bus_width = 32 => 0x40
23130         ; CAS latency = 3 && bus_width = 32 => 0x60
23131         ; CAS latency = 2 && bus_width = 16 => 0x20
23132 @@ -43,7 +43,7 @@
23133         move.d   CONFIG_ETRAX_SDRAM_COMMAND, $r2
23134         bne      _set_timing
23135         nop
23136 -
23137 +       
23138         move.d   0x40, $r4       ; Assume 32 bits and CAS latency = 2
23139         move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
23140         and.d    0x07, $r1       ; Get CAS latency
23141 @@ -51,7 +51,7 @@
23142         beq      _bw_check
23143         nop
23144         move.d   0x60, $r4
23145 -
23146 +       
23147  _bw_check:
23148         ; Assume that group 0 width is equal to group 1. This assumption
23149         ; is wrong for a group 1 only hardware (such as the grand old
23150 @@ -67,23 +67,27 @@
23151         move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
23152         and.d    ~(3 << reg_bif_core_rw_sdram_timing___ref___lsb), $r1
23153         move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
23154 -       move.d   $r1, [$r0]
23155 +       move.d   $r1, [$r0]     
23156 +
23157 +       ; Wait 200us
23158 +       move.d   10000, $r2
23159 +1:     bne      1b
23160 +       subq     1, $r2
23161  
23162         ; Issue NOP command
23163         move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd), $r5
23164         moveq regk_bif_core_nop, $r1
23165         move.d $r1, [$r5]
23166 -
23167 +       
23168         ; Wait 200us
23169         move.d   10000, $r2
23170  1:     bne      1b
23171         subq     1, $r2
23172 -
23173 +       
23174         ; Issue initialization command sequence
23175 -       move.d   _sdram_commands_start, $r2
23176 -       and.d    0x000fffff, $r2 ; Make sure commands are read from flash
23177 -       move.d   _sdram_commands_end,  $r3
23178 -       and.d    0x000fffff, $r3
23179 +       lapc.d   _sdram_commands_start, $r2     ; position-independent
23180 +       lapc.d   _sdram_commands_end,  $r3      ; position-independent
23181 +
23182  1:     clear.d  $r6
23183         move.b   [$r2+], $r6    ; Load command
23184         or.d     $r4, $r6       ; Add calculated mrs
23185 @@ -100,7 +104,7 @@
23186         move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
23187         move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
23188         move.d   $r1, [$r0]
23189 -
23190 +       
23191         ; Initialization finished
23192         ba       _sdram_commands_end
23193         nop
23194 @@ -116,4 +120,4 @@
23195         .byte   regk_bif_core_ref ; refresh
23196         .byte   regk_bif_core_ref ; refresh
23197         .byte   regk_bif_core_mrs ; mrs
23198 -_sdram_commands_end:
23199 +_sdram_commands_end:           
23200 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/hw_settings.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/hw_settings.S
23201 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/hw_settings.S     2007-01-10 20:10:37.000000000 +0100
23202 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/hw_settings.S     2006-10-13 14:43:15.000000000 +0200
23203 @@ -1,25 +1,25 @@
23204  /*
23205 - * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $
23206 - *
23207 + * $Id: hw_settings.S,v 1.5 2006/10/13 12:43:15 starvik Exp $
23208 + * 
23209   * This table is used by some tools to extract hardware parameters.
23210   * The table should be included in the kernel and the decompressor.
23211   * Don't forget to update the tools if you change this table.
23212   *
23213   * Copyright (C) 2001 Axis Communications AB
23214   *
23215 - * Authors:  Mikael Starvik (starvik@axis.com)
23216 + * Authors:  Mikael Starvik (starvik@axis.com) 
23217   */
23218  
23219  #include <asm/arch/hwregs/asm/reg_map_asm.h>
23220  #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
23221  #include <asm/arch/hwregs/asm/gio_defs_asm.h>
23222 -
23223 +               
23224         .ascii "HW_PARAM_MAGIC" ; Magic number
23225         .dword 0xc0004000       ; Kernel start address
23226  
23227         ; Debug port
23228  #ifdef CONFIG_ETRAX_DEBUG_PORT0
23229 -       .dword 0
23230 +       .dword 0                
23231  #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
23232         .dword 1
23233  #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
23234 @@ -28,9 +28,9 @@
23235         .dword 3
23236  #else
23237         .dword 4 ; No debug
23238 -#endif
23239 +#endif                 
23240  
23241 -       ; Register values
23242 +       ; Register values 
23243         .dword REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg)
23244         .dword CONFIG_ETRAX_MEM_GRP1_CONFIG
23245         .dword REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg)
23246 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/memset.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/memset.c
23247 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/memset.c  2007-01-10 20:10:37.000000000 +0100
23248 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/memset.c  2003-07-02 05:00:14.000000000 +0200
23249 @@ -66,7 +66,7 @@
23250  
23251    {
23252      register char *dst __asm__ ("r13") = pdst;
23253 -
23254
23255    /* This is NONPORTABLE, but since this whole routine is     */
23256    /* grossly nonportable that doesn't matter.                 */
23257  
23258 @@ -156,7 +156,7 @@
23259    }
23260  
23261      /* Either we directly starts copying, using dword copying
23262 -       in a loop, or we copy as much as possible with 'movem'
23263 +       in a loop, or we copy as much as possible with 'movem' 
23264         and then the last block (<44 bytes) is copied here.
23265         This will work since 'movem' will have updated src,dst,n. */
23266  
23267 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/nand_init.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/nand_init.S
23268 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/nand_init.S       2007-01-10 20:10:37.000000000 +0100
23269 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/nand_init.S       2007-01-31 16:52:19.000000000 +0100
23270 @@ -9,14 +9,16 @@
23271  ##
23272  ##     Some notes about the bug/feature for future reference:
23273  ##        The bootrom copies the first 127 KB from NAND flash to internal
23274 -##        memory. The problem is that it does a bytewise copy. NAND flashes
23275 -##        does autoincrement on the address so for a 16-bite device each
23276 -##        read/write increases the address by two. So the copy loop in the
23277 +##        memory. The problem is that it does a bytewise copy, copying
23278 +##        a single byte from the lowest byte of the bus for each address.
23279 +##        NAND flashes autoincrement on the address so for a 16 bit device
23280 +##        each read/write increases the address by two. So the copy loop in the
23281  ##        bootrom will discard every second byte. This is solved by inserting
23282 -##        zeroes in every second byte in the first erase block.
23283 +##        zeroes in every second byte in the first erase block, in order
23284 +##        to get contiguous code.
23285  ##
23286  ##        The bootrom also incorrectly assumes that it can read the flash
23287 -##        linear with only one read command but the flash will actually
23288 +##        linearly with only one read command but the flash will actually
23289  ##        switch between normal area and spare area if you do that so we
23290  ##        can't trust more than the first 256 bytes.
23291  ##
23292 @@ -29,14 +31,16 @@
23293  #include <asm/arch/hwregs/asm/config_defs_asm.h>
23294  
23295  ;; There are 8-bit NAND flashes and 16-bit NAND flashes.
23296 -;; We need to treat them slightly different.
23297 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23298 -#define PAGE_SIZE 256
23299 +;; We need to treat them slightly differently.
23300 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23301 +#define PAGE_SIZE_ADDRESSES 256
23302  #else
23303 -#error 2
23304 -#define PAGE_SIZE 512
23305 +#define PAGE_SIZE_ADDRESSES 512
23306  #endif
23307 +
23308 +;; Block size for erase
23309  #define ERASE_BLOCK 16384
23310 +#define PAGE_SIZE_BYTES 512
23311  
23312  ;; GPIO pins connected to NAND flash
23313  #define CE 4
23314 @@ -49,6 +53,7 @@
23315  #define NAND_WR_ADDR 0x94000000
23316  
23317  #define READ_CMD 0x00
23318 +#define RESET_CMD 0xFF
23319  
23320  ;; Readability macros
23321  #define CSP_MASK \
23322 @@ -58,6 +63,10 @@
23323         REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
23324         REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
23325  
23326 +;; Normally we initialize GPIO and bus interfaces.
23327 +;; This is strictly not necessary; boot ROM does this for us.
23328 +#define INTERFACE_SETUP (1)
23329 +
23330  ;;----------------------------------------------------------------------------
23331  ;; Macros to set/clear GPIO bits
23332  
23333 @@ -71,16 +80,41 @@
23334         move.d $r9, [$r2]
23335  .endm
23336  
23337 +.macro GPIO_SYNC
23338 +;;     Originally, we read back data written to nand flash in order
23339 +;;     to flush the pipeline. It turned out however, that the real
23340 +;;     culprit was a lack of wait states.
23341 +;;     This macro remains in the code however in case this conclusion
23342 +;;     is wrong too.
23343 +;;
23344 +;;     move.d [$r2], $r9 ; read back to flush pipeline
23345 +.endm
23346 +
23347  ;;----------------------------------------------------------------------------
23348 +;; Read value from bus to temporary register to sync with previous write
23349 +;; This generates no signal to the NAND flash, since only chip select lines are
23350 +;; pulled out to the chip, and read is not gated with chip select for the write
23351 +;; area.
23352  
23353 -nand_boot:
23354 -       ;; Check if nand boot was selected
23355 -       move.d REG_ADDR(config, regi_config, r_bootsel), $r0
23356 -       move.d [$r0], $r0
23357 -       and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
23358 -       cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
23359 -       bne normal_boot ; No NAND boot
23360 -       nop
23361 +.macro BUS_SYNC r
23362 +       move.b [$r1], \r
23363 +.endm
23364 +
23365 +;;----------------------------------------------------------------------------
23366 +;; Delay macro
23367 +;; x = delay = 10*x + 20 ns, e.g. DELAY 25 => 270ns delay, max 63 (650 ns)
23368 +;;(@200Mc)
23369 +;; r is temp reg used
23370 +;; Macro currently not used, save for a rainy day.
23371 +
23372 +.macro DELAY x, r
23373 +       clear.d \r
23374 +       addq    (\x),\r         ; addq zero-extends its argument
23375 +7:     bne     7b
23376 +       subq    1, \r
23377 +.endm
23378 +
23379 +;;----------------------------------------------------------------------------
23380  
23381  copy_nand_to_ram:
23382         ;; copy_nand_to_ram
23383 @@ -88,7 +122,6 @@
23384         ;;   r10 - destination
23385         ;;   r11 - source offset
23386         ;;   r12 - size
23387 -       ;;   r13 - Address to jump to after completion
23388         ;; Note : r10-r12 are clobbered on return
23389         ;; Registers used:
23390         ;;   r0 - NAND_RD_ADDR
23391 @@ -96,83 +129,99 @@
23392         ;;   r2 - reg_gio_rw_pa_dout
23393         ;;   r3 - reg_gio_r_pa_din
23394         ;;   r4 - tmp
23395 -       ;;   r5 - byte counter within a page
23396 -       ;;   r6 - reg_pinmux_rw_pa
23397 -       ;;   r7 - reg_gio_rw_pa_oe
23398 -       ;;   r8 - reg_bif_core_rw_grp3_cfg
23399 +       ;;   r5 - byte counter within a page / tmp2
23400 +       ;;   r6 - r_bootsel masked w/ 0x18
23401 +       ;;   r7 - n/u
23402 +       ;;   r8 - n/u
23403         ;;   r9 - reg_gio_rw_pa_dout shadow
23404 -       move.d 0x90000000, $r0
23405 -       move.d 0x94000000, $r1
23406 +       move.d NAND_RD_ADDR, $r0
23407 +       move.d NAND_WR_ADDR, $r1
23408         move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
23409         move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
23410 -       move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
23411 -       move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
23412 -       move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
23413  
23414 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23415 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23416         lsrq    1, $r11
23417  #endif
23418 +
23419 +#if INTERFACE_SETUP
23420 +       ;; Set up pinmux
23421 +       move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r5
23422 +       move.d [$r5], $r4
23423 +       or.b 0xf0, $r4          ; bits 4,5,6,7
23424 +       move.d $r4, [$r5]
23425 +
23426         ;; Set up GPIO
23427 -       move.d [$r2], $r9
23428 -       move.d [$r7], $r4
23429 +       move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r5
23430 +       move.d [$r5], $r4
23431         or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
23432 -       move.d $r4, [$r7]
23433 +       move.d $r4, [$r5]
23434  
23435 +#endif
23436         ;; Set up bif
23437 -       move.d [$r8], $r4
23438 -       and.d CSP_MASK, $r4
23439 +       move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r5
23440 +       move.d CONFIG_ETRAX_MEM_GRP3_CONFIG, $r4 ; wait states
23441 +       and.d ~CSP_MASK, $r4
23442         or.d CSP_VAL, $r4
23443 -       move.d $r4, [$r8]
23444 +       move.d $r4, [$r5]
23445 +
23446 +       move.d [$r2], $r9       ; fetch PA DOUT to shadow register
23447 +
23448 +       ;; figure out how many address cycles the flash needs
23449 +       move.d REG_ADDR(config, regi_config, r_bootsel), $r5
23450 +       move.d [$r5], $r6
23451 +       andq 0x18, $r6          ; mask out bs3,4 (00=>3, 08=>4, 18=>5 cycles)
23452  
23453  1:     ;; Copy one page
23454         CLR CE
23455         SET CLE
23456 +       GPIO_SYNC
23457         moveq   READ_CMD, $r4
23458         move.b  $r4, [$r1]
23459 -       moveq   20, $r4
23460 -2:     bne     2b
23461 -       subq    1, $r4
23462 +       BUS_SYNC $r4
23463         CLR CLE
23464         SET ALE
23465 -       clear.w [$r1]           ; Column address = 0
23466 -       move.d  $r11, $r4
23467 +       GPIO_SYNC
23468 +       clear.b [$r1]           ; Column address = 0
23469 +       move.d  $r11, $r4       ; Address
23470 +       lsrq    9, $r4          ; Row address is A9 and up
23471 +       move.b  $r4, [$r1]      ; Row address byte #0
23472         lsrq    8, $r4
23473 -       move.b  $r4, [$r1]      ; Row address
23474 +       cmpq    0x08, $r6       ; 8 => Z, 0 => C, 18h => NZ,NC
23475 +       bcs     4f              ; C (3 cycles) => jump
23476 +       move.b  $r4, [$r1]      ; Row address byte #1 (DELAY SLOT) (no flagset)
23477 +       beq     3f              ; Z (4 cycles) => jump
23478 +       lsrq    8, $r4          ; (DELAY SLOT)
23479 +       move.b  $r4, [$r1]      ; Row address byte #2 (5 cyc only)
23480         lsrq    8, $r4
23481 -       move.b  $r4, [$r1]      ; Row adddress
23482 -       moveq   20, $r4
23483 -2:     bne     2b
23484 -       subq    1, $r4
23485 +3:
23486 +       move.b  $r4, [$r1]      ; Row address byte #3 (5 cyc) or #2 (4 cyc)
23487 +4:
23488 +       BUS_SYNC $r4
23489         CLR ALE
23490 +       GPIO_SYNC
23491 +
23492  2:     move.d  [$r3], $r4
23493         and.d   1 << BY, $r4
23494         beq 2b
23495 -       movu.w  PAGE_SIZE, $r5
23496 +       nop
23497 +       movu.w  PAGE_SIZE_ADDRESSES, $r5
23498  2:     ; Copy one byte/word
23499 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23500 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23501         move.w  [$r0], $r4
23502  #else
23503         move.b  [$r0], $r4
23504  #endif
23505         subq    1, $r5
23506         bne     2b
23507 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23508 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23509         move.w  $r4, [$r10+]
23510 -       subu.w  PAGE_SIZE*2, $r12
23511  #else
23512         move.b  $r4, [$r10+]
23513 -       subu.w  PAGE_SIZE, $r12
23514  #endif
23515 -       bpl     1b
23516 -       addu.w  PAGE_SIZE, $r11
23517 +       subu.w  PAGE_SIZE_BYTES, $r12
23518 +       bhi     1b
23519 +       addu.w  PAGE_SIZE_ADDRESSES, $r11
23520  
23521 -       ;; End of copy
23522 -       jump    $r13
23523 -       nop
23524 +       SET CE
23525  
23526 -       ;; This will warn if the code above is too large. If you consider
23527 -       ;; to remove this you don't understand the bug/feature.
23528 -       .org 256
23529 -       .org ERASE_BLOCK
23530 -
23531 -normal_boot:
23532 +       ;; End of copy
23533 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/spinlock.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/spinlock.S
23534 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/spinlock.S        2007-01-10 20:10:37.000000000 +0100
23535 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/spinlock.S        2006-05-24 11:38:43.000000000 +0200
23536 @@ -1,22 +1,22 @@
23537  ;; Core of the spinlock implementation
23538  ;;
23539 -;; Copyright (C) 2004 Axis Communications AB.
23540 +;; Copyright (C) 2004 Axis Communications AB. 
23541  ;;
23542 -;; Author: Mikael Starvik
23543 -
23544 +;; Author: Mikael Starvik 
23545  
23546 +        
23547         .global cris_spin_lock
23548         .global cris_spin_trylock
23549  
23550         .text
23551 -
23552 +       
23553  cris_spin_lock:
23554         clearf  p
23555 -1:     test.d  [$r10]
23556 +1:     test.b  [$r10]
23557         beq     1b
23558         clearf  p
23559         ax
23560 -       clear.d [$r10]
23561 +       clear.b [$r10]
23562         bcs     1b
23563         clearf  p
23564         ret
23565 @@ -24,10 +24,10 @@
23566  
23567  cris_spin_trylock:
23568         clearf  p
23569 -1:     move.d  [$r10], $r11
23570 +1:     move.b  [$r10], $r11
23571         ax
23572 -       clear.d [$r10]
23573 +       clear.b [$r10]
23574          bcs    1b
23575          clearf p
23576         ret
23577 -       move.d  $r11,$r10
23578 +       movu.b  $r11,$r10
23579 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/string.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/string.c
23580 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/string.c  2007-01-10 20:10:37.000000000 +0100
23581 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/string.c  2003-07-02 05:00:14.000000000 +0200
23582 @@ -48,8 +48,8 @@
23583    register char *dst __asm__ ("r13") = pdst;
23584    register const char *src __asm__ ("r11") = psrc;
23585    register int n __asm__ ("r12") = pn;
23586 -
23587 -
23588 +  
23589
23590    /* When src is aligned but not dst, this makes a few extra needless
23591       cycles.  I believe it would take as many to check that the
23592       re-alignment was unnecessary.  */
23593 @@ -117,13 +117,13 @@
23594         ;; Restore registers from stack                                 \n\
23595          movem [$sp+],$r10"
23596  
23597 -     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
23598 +     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) 
23599       /* Inputs */ : "0" (dst), "1" (src), "2" (n));
23600 -
23601 +    
23602    }
23603  
23604    /* Either we directly starts copying, using dword copying
23605 -     in a loop, or we copy as much as possible with 'movem'
23606 +     in a loop, or we copy as much as possible with 'movem' 
23607       and then the last block (<44 bytes) is copied here.
23608       This will work since 'movem' will have updated src,dst,n. */
23609  
23610 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/init.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/init.c
23611 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/init.c     2007-01-10 20:10:37.000000000 +0100
23612 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/init.c     2006-10-13 14:43:14.000000000 +0200
23613 @@ -34,12 +34,12 @@
23614         unsigned long mmu_kbase_hi;
23615         unsigned long mmu_kbase_lo;
23616         unsigned short mmu_page_id;
23617 -
23618 -       /*
23619 +       
23620 +       /* 
23621          * Make sure the current pgd table points to something sane, even if it
23622          * is most probably not used until the next switch_mm.
23623          */
23624 -       per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
23625 +       per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd; 
23626  
23627  #ifdef CONFIG_SMP
23628         {
23629 @@ -65,7 +65,7 @@
23630                        REG_STATE(mmu, rw_mm_cfg, seg_d, page)   |
23631                        REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
23632                        REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
23633 -#ifndef CONFIG_ETRAXFS_SIM
23634 +#ifndef CONFIG_ETRAXFS_SIM     
23635                         REG_STATE(mmu, rw_mm_cfg, seg_a, page)   |
23636  #else
23637                        REG_STATE(mmu, rw_mm_cfg, seg_a, linear) |
23638 @@ -115,7 +115,7 @@
23639         SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
23640         SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
23641         SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
23642 -
23643 +       
23644         /* Update the data MMU. */
23645         SUPP_BANK_SEL(BANK_DM);
23646         SUPP_REG_WR(RW_MM_CFG, mmu_config);
23647 @@ -125,7 +125,7 @@
23648  
23649         SPEC_REG_WR(SPEC_REG_PID, 0);
23650  
23651 -       /*
23652 +       /* 
23653          * The MMU has been enabled ever since head.S but just to make it
23654          * totally obvious enable it here as well.
23655          */
23656 @@ -133,7 +133,7 @@
23657         SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
23658  }
23659  
23660 -void __init
23661 +void __init 
23662  paging_init(void)
23663  {
23664         int i;
23665 @@ -160,13 +160,13 @@
23666         for (i = 1; i < MAX_NR_ZONES; i++)
23667                 zones_size[i] = 0;
23668  
23669 -       /*
23670 +       /* 
23671          * Use free_area_init_node instead of free_area_init, because it is
23672 -        * designed for systems where the DRAM starts at an address
23673 +        * designed for systems where the DRAM starts at an address 
23674          * substantially higher than 0, like us (we start at PAGE_OFFSET). This
23675          * saves space in the mem_map page array.
23676          */
23677         free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
23678 -
23679 +       
23680         mem_map = contig_page_data.node_mem_map;
23681  }
23682 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/intmem.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/intmem.c
23683 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/intmem.c   2007-01-10 20:10:37.000000000 +0100
23684 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/intmem.c   2006-01-02 12:27:04.000000000 +0100
23685 @@ -27,7 +27,7 @@
23686  {
23687         static int initiated = 0;
23688         if (!initiated) {
23689 -               struct intmem_allocation* alloc =
23690 +               struct intmem_allocation* alloc = 
23691                   (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);
23692                 INIT_LIST_HEAD(&intmem_allocations);
23693                 intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE);
23694 @@ -44,7 +44,7 @@
23695         struct intmem_allocation* allocation;
23696         struct intmem_allocation* tmp;
23697         void* ret = NULL;
23698 -
23699 +  
23700         preempt_disable();
23701         crisv32_intmem_init();
23702  
23703 @@ -55,7 +55,7 @@
23704                 if (allocation->status == STATUS_FREE &&
23705                     allocation->size >= size + alignment) {
23706                         if (allocation->size > size + alignment) {
23707 -                               struct intmem_allocation* alloc =
23708 +                               struct intmem_allocation* alloc = 
23709                                         (struct intmem_allocation*)
23710                                         kmalloc(sizeof *alloc, GFP_ATOMIC);
23711                                 alloc->status = STATUS_FREE;
23712 @@ -73,13 +73,13 @@
23713                                         allocation->offset += alignment;
23714                                         list_add_tail(&tmp->entry, &allocation->entry);
23715                                 }
23716 -                       }
23717 +                       }               
23718                         allocation->status = STATUS_ALLOCATED;
23719                         allocation->size = size;
23720                         ret = (void*)((int)intmem_virtual + allocation->offset);
23721                 }
23722         }
23723 -       preempt_enable();
23724 +       preempt_enable();        
23725         return ret;
23726  }
23727  
23728 @@ -96,22 +96,22 @@
23729  
23730         list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
23731                 if (allocation->offset == (int)(addr - intmem_virtual)) {
23732 -                       struct intmem_allocation* prev =
23733 -                         list_entry(allocation->entry.prev,
23734 +                       struct intmem_allocation* prev = 
23735 +                         list_entry(allocation->entry.prev, 
23736                                      struct intmem_allocation, entry);
23737 -                       struct intmem_allocation* next =
23738 -                         list_entry(allocation->entry.next,
23739 +                       struct intmem_allocation* next = 
23740 +                         list_entry(allocation->entry.next, 
23741                                      struct intmem_allocation, entry);
23742  
23743                         allocation->status = STATUS_FREE;
23744                         /* Join with prev and/or next if also free */
23745 -                       if (prev->status == STATUS_FREE) {
23746 +                       if ((prev != &intmem_allocations) && (prev->status == STATUS_FREE)) {
23747                                 prev->size += allocation->size;
23748                                 list_del(&allocation->entry);
23749                                 kfree(allocation);
23750                                 allocation = prev;
23751                         }
23752 -                       if (next->status == STATUS_FREE) {
23753 +                       if ((next != &intmem_allocations) && (next->status == STATUS_FREE)) {
23754                                 allocation->size += next->size;
23755                                 list_del(&next->entry);
23756                                 kfree(next);
23757 @@ -125,13 +125,13 @@
23758  
23759  void* crisv32_intmem_phys_to_virt(unsigned long addr)
23760  {
23761 -       return (void*)(addr - MEM_INTMEM_START+
23762 +       return (void*)(addr - MEM_INTMEM_START+ 
23763                        (unsigned long)intmem_virtual);
23764  }
23765  
23766  unsigned long crisv32_intmem_virt_to_phys(void* addr)
23767  {
23768 -       return (unsigned long)((unsigned long )addr -
23769 +       return (unsigned long)((unsigned long )addr - 
23770           (unsigned long)intmem_virtual + MEM_INTMEM_START);
23771  }
23772  
23773 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/mmu.S linux-2.6.19.2.dev/arch/cris/arch-v32/mm/mmu.S
23774 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/mmu.S      2007-01-10 20:10:37.000000000 +0100
23775 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/mmu.S      2006-08-04 10:10:20.000000000 +0200
23776 @@ -1,3 +1,5 @@
23777 +; WARNING : The refill handler has been modified, see below !!!
23778 +
23779  /*
23780   *  Copyright (C) 2003 Axis Communications AB
23781   *
23782 @@ -9,7 +11,7 @@
23783  
23784  #include <asm/page.h>
23785  #include <asm/pgtable.h>
23786 -
23787 +       
23788  ; Save all register. Must save in same order as struct pt_regs.
23789  .macro SAVE_ALL
23790         subq    12, $sp
23791 @@ -29,11 +31,11 @@
23792         subq    14*4, $sp
23793         movem   $r13, [$sp]
23794         subq    4, $sp
23795 -       move.d  $r10, [$sp]
23796 +       move.d  $r10, [$sp]     
23797  .endm
23798  
23799  ; Bus fault handler. Extracts relevant information and calls mm subsystem
23800 -; to handle the fault.
23801 +; to handle the fault. 
23802  .macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
23803         .globl  \handler
23804  \handler:
23805 @@ -45,7 +47,7 @@
23806         orq     \ex << 1, $r13  ; execute?
23807         move    $s3, $r10       ; rw_mm_cause
23808         and.d   ~8191, $r10     ; Get faulting page start address
23809 -
23810 +       
23811         jsr     do_page_fault
23812         nop
23813         ba      ret_from_intr
23814 @@ -59,15 +61,28 @@
23815  ; The code below handles case 1 and calls the mm subsystem for case 2 and 3.
23816  ; Do not touch this code without very good reasons and extensive testing.
23817  ; Note that the code is optimized to minimize stalls (makes the code harder
23818 -; to read).
23819 +; to read).            
23820 +;
23821 +; WARNING !!!
23822 +; Modified by Mikael Asker 060725: added a workaround for strange TLB 
23823 +; behavior. If the same PTE is present in more than one set, the TLB 
23824 +; doesn't recognize it and we get stuck in a loop of refill exceptions.  
23825 +; The workaround detects such loops and exits them by flushing
23826 +; the TLB contents. The problem and workaround were verified 
23827 +; in VCS by Mikael Starvik.
23828  ;
23829  ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
23830 -; PMD holds 16 MB of virtual memory.
23831 +; PMD holds 16 MB of virtual memory. 
23832  ;   Bits  0-12 : Offset within a page
23833  ;   Bits 13-23 : PTE offset within a PMD
23834  ;   Bits 24-31 : PMD offset within the PGD
23835 -
23836 +       
23837  .macro MMU_REFILL_HANDLER handler, mmu
23838 +       .data
23839 +1:     .dword  0               ; refill_count
23840 +                                ;   == 0 <=> last_refill_cause is invalid\r
23841 +2:     .dword  0               ; last_refill_cause\r
23842 +       .text
23843         .globl \handler
23844  \handler:
23845         subq    4, $sp
23846 @@ -76,40 +91,88 @@
23847         subq    4, $sp
23848         move    \mmu, $srs      ; Select MMU support register bank
23849         move.d  $acr, [$sp]
23850 -       subq    4, $sp
23851 -       move.d  $r0, [$sp]
23852 -#ifdef CONFIG_SMP
23853 +       subq    12, $sp\r
23854 +       move.d  1b, $acr        ; Point to refill_count\r
23855 +       movem   $r2, [$sp]\r
23856 +\r
23857 +       test.d  [$acr]          ; refill_count == 0 ?
23858 +       beq     5f              ;   yes, last_refill_cause is invalid\r
23859 +        move.d $acr, $r1\r
23860 +\r
23861 +       ; last_refill_cause is valid, investigate cause\r
23862 +        addq    4, $r1          ; Point to last_refill_cause\r
23863 +       move    $s3, $r0        ; Get rw_mm_cause\r
23864 +       move.d  [$r1], $r2      ; Get last_refill_cause\r
23865 +       cmp.d   $r0, $r2        ; rw_mm_cause == last_refill_cause ?\r
23866 +       beq     6f              ;   yes, increment count\r
23867 +       moveq   1, $r2\r
23868 +\r
23869 +        ; rw_mm_cause != last_refill_cause\r
23870 +       move.d  $r2, [$acr]     ; refill_count = 1\r
23871 +       move.d  $r0, [$r1]      ; last_refill_cause = rw_mm_cause\r
23872 +\r
23873 +3:     ; Probably not in a loop, continue normal processing
23874 +#ifdef CONFIG_SMP      
23875         move    $s7, $acr       ; PGD
23876  #else
23877         move.d  per_cpu__current_pgd, $acr ; PGD
23878  #endif
23879         ; Look up PMD in PGD
23880 -       move    $s3, $r0        ; rw_mm_cause
23881         lsrq    24, $r0 ; Get PMD index into PGD (bit 24-31)
23882         move.d  [$acr], $acr    ; PGD for the current process
23883         addi    $r0.d, $acr, $acr
23884         move    $s3, $r0        ; rw_mm_cause
23885         move.d  [$acr], $acr    ; Get PMD
23886 -       beq     1f
23887 +       beq     8f
23888         ; Look up PTE in PMD
23889         lsrq    PAGE_SHIFT, $r0
23890         and.w   PAGE_MASK, $acr ; Remove PMD flags
23891         and.d   0x7ff, $r0      ; Get PTE index into PMD (bit 13-23)
23892         addi    $r0.d, $acr, $acr
23893         move.d  [$acr], $acr    ; Get PTE
23894 -       beq     2f
23895 -       move.d  [$sp+], $r0     ; Pop r0 in delayslot
23896 +       beq     9f
23897 +       movem   [$sp], $r2      ; Restore r0-r2 in delay slot
23898 +       addq    12, $sp
23899         ; Store in TLB
23900         move    $acr, $s5
23901 -       ; Return
23902 +4:     ; Return
23903         move.d  [$sp+], $acr
23904         move    [$sp], $srs
23905         addq    4, $sp
23906         rete
23907         rfe
23908 -1:     ; PMD missing, let the mm subsystem fix it up.
23909 -       move.d  [$sp+], $r0     ; Pop r0
23910 -2:      ; PTE missing, let the mm subsystem fix it up.
23911 +\r
23912 +5:      ; last_refill_cause is invalid\r
23913 +       moveq   1, $r2\r
23914 +        addq    4, $r1          ; Point to last_refill_cause\r
23915 +       move.d  $r2, [$acr]     ; refill_count = 1\r
23916 +       move    $s3, $r0        ; Get rw_mm_cause\r
23917 +        ba      3b             ; Continue normal processing\r
23918 +       move.d  $r0,[$r1]       ; last_refill_cause = rw_mm_cause\r
23919 +\r
23920 +6:      ; rw_mm_cause == last_refill_cause\r
23921 +        move.d  [$acr], $r2     ; Get refill_count\r
23922 +       cmpq    4, $r2          ; refill_count > 4 ?\r
23923 +       bhi     7f              ;   yes\r
23924 +       addq    1, $r2          ; refill_count++
23925 +       ba      3b              ; Continue normal processing
23926 +       move.d  $r2, [$acr]
23927 +\r
23928 +7:     ; refill_count > 4, error
23929 +       subq    4, $sp\r
23930 +       move    $srp, [$sp]
23931 +       jsr     __flush_tlb_all
23932 +        move.d $acr, $r0       ; Save pointer to refill_count
23933 +       move    [$sp+], $srp
23934 +       clear.d [$r0]           ; refill_count = 0
23935 +       movem   [$sp], $r2
23936 +       ba      4b              ; Return
23937 +       addq    12, $sp
23938 +\r
23939 +8:     ; PMD missing, let the mm subsystem fix it up.
23940 +       movem   [$sp], $r2      ; Restore r0-r2
23941 +9:      ; PTE missing, let the mm subsystem fix it up.
23942 +       addq    12, $sp
23943         move.d  [$sp+], $acr
23944         move    [$sp], $srs
23945         addq    4, $sp
23946 @@ -128,7 +191,7 @@
23947         ba      ret_from_intr
23948         nop
23949  .endm
23950 -
23951 +                       
23952         ; This is the MMU bus fault handlers.
23953  
23954  MMU_REFILL_HANDLER i_mmu_refill, 1
23955 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/tlb.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/tlb.c
23956 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/tlb.c      2007-01-10 20:10:37.000000000 +0100
23957 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/tlb.c      2006-08-07 12:06:44.000000000 +0200
23958 @@ -2,7 +2,7 @@
23959   * Low level TLB handling.
23960   *
23961   * Copyright (C) 2000-2003, Axis Communications AB.
23962 - *
23963 + *  
23964   * Authors:   Bjorn Wesen <bjornw@axis.com>
23965   *            Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
23966   */
23967 @@ -79,7 +79,7 @@
23968  void
23969  __flush_tlb_mm(struct mm_struct *mm)
23970  {
23971 -       int i;
23972 +       int i; 
23973         int mmu;
23974         unsigned long flags;
23975         unsigned long page_id;
23976 @@ -90,7 +90,7 @@
23977  
23978         if (page_id == NO_CONTEXT)
23979                 return;
23980 -
23981 +       
23982         /* Mark the TLB entries that match the page_id as invalid. */
23983         local_save_flags(flags);
23984         local_irq_disable();
23985 @@ -99,15 +99,15 @@
23986                 SUPP_BANK_SEL(mmu);
23987                 for (i = 0; i < NUM_TLB_ENTRIES; i++) {
23988                         UPDATE_TLB_SEL_IDX(i);
23989 -
23990 +       
23991                         /* Get the page_id */
23992                         SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
23993  
23994                         /* Check if the page_id match. */
23995                         if ((tlb_hi & 0xff) == page_id) {
23996                                 mmu_tlb_hi = (REG_FIELD(mmu, rw_mm_tlb_hi, pid,
23997 -                                                       INVALID_PAGEID)
23998 -                                           | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
23999 +                                                       INVALID_PAGEID) 
24000 +                                           | REG_FIELD(mmu, rw_mm_tlb_hi, vpn, 
24001                                                         i & 0xf));
24002  
24003                                 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24004 @@ -135,7 +135,7 @@
24005                 return;
24006  
24007         addr &= PAGE_MASK;
24008 -
24009 +       
24010         /*
24011          * Invalidate those TLB entries that match both the mm context and the
24012          * requested virtual address.
24013 @@ -150,11 +150,11 @@
24014                         SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
24015  
24016                         /* Check if page_id and address matches */
24017 -                       if (((tlb_hi & 0xff) == page_id) &&
24018 +                       if (((tlb_hi & 0xff) == page_id) && 
24019                             ((tlb_hi & PAGE_MASK) == addr)) {
24020                                 mmu_tlb_hi = REG_FIELD(mmu, rw_mm_tlb_hi, pid,
24021                                                        INVALID_PAGEID) | addr;
24022 -
24023 +                       
24024                                 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24025                         }
24026                 }
24027 @@ -178,33 +178,35 @@
24028  static DEFINE_SPINLOCK(mmu_context_lock);
24029  
24030  /* Called in schedule() just before actually doing the switch_to. */
24031 -void
24032 +void 
24033  switch_mm(struct mm_struct *prev, struct mm_struct *next,
24034           struct task_struct *tsk)
24035 -{
24036 -       int cpu = smp_processor_id();
24037 -
24038 -       /* Make sure there is a MMU context. */
24039 -       spin_lock(&mmu_context_lock);
24040 -       get_mmu_context(next);
24041 -       cpu_set(cpu, next->cpu_vm_mask);
24042 -       spin_unlock(&mmu_context_lock);
24043 -
24044 -       /*
24045 -        * Remember the pgd for the fault handlers. Keep a seperate copy of it
24046 -        * because current and active_mm might be invalid at points where
24047 -        * there's still a need to derefer the pgd.
24048 -        */
24049 -       per_cpu(current_pgd, cpu) = next->pgd;
24050 -
24051 -       /* Switch context in the MMU. */
24052 -        if (tsk && task_thread_info(tsk))
24053 -        {
24054 -          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24055 -        }
24056 -        else
24057 -        {
24058 -          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
24059 -        }
24060 +{      
24061 +       if (prev != next) {
24062 +               int cpu = smp_processor_id();
24063 +               
24064 +               /* Make sure there is a MMU context. */
24065 +               spin_lock(&mmu_context_lock);
24066 +               get_mmu_context(next);
24067 +               cpu_set(cpu, next->cpu_vm_mask);
24068 +               spin_unlock(&mmu_context_lock);
24069 +               
24070 +               /*
24071 +                * Remember the pgd for the fault handlers. Keep a seperate copy of it
24072 +                * because current and active_mm might be invalid at points where
24073 +                * there's still a need to derefer the pgd.
24074 +                */
24075 +               per_cpu(current_pgd, cpu) = next->pgd;
24076 +               
24077 +               /* Switch context in the MMU. */
24078 +               if (tsk && task_thread_info(tsk))
24079 +               {
24080 +                       SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24081 +               }
24082 +               else
24083 +               {
24084 +                       SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
24085 +               }
24086 +       }
24087  }
24088  
24089 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/vmlinux.lds.S linux-2.6.19.2.dev/arch/cris/arch-v32/vmlinux.lds.S
24090 --- linux-2.6.19.2.old/arch/cris/arch-v32/vmlinux.lds.S 2007-01-10 20:10:37.000000000 +0100
24091 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/vmlinux.lds.S 2006-10-13 14:43:11.000000000 +0200
24092 @@ -5,11 +5,11 @@
24093   * script. It is for example quite vital that all generated sections
24094   * that are used are actually named here, otherwise the linker will
24095   * put them at the end, where the init stuff is which is FREED after
24096 - * the kernel has booted.
24097 - */
24098 + * the kernel has booted. 
24099 + */    
24100  
24101  #include <asm-generic/vmlinux.lds.h>
24102 -
24103 +               
24104  jiffies = jiffies_64;
24105  SECTIONS
24106  {
24107 @@ -20,7 +20,7 @@
24108         /* The boot section is only necessary until the VCS top level testbench */
24109         /* includes both flash and DRAM. */
24110         .boot : { *(.boot) }
24111 -
24112 +       
24113         . = DRAM_VIRTUAL_BASE + 0x4000;         /* See head.S and pages reserved at the start. */
24114  
24115         _text = .;              /* Text and read-only data. */
24116 @@ -35,7 +35,7 @@
24117                 *(.text.__*)
24118         }
24119  
24120 -       _etext = . ;            /* End of text section. */
24121 +       _etext = . ;            /* End of text section. */ 
24122         __etext = .;
24123  
24124         . = ALIGN(4);           /* Exception table. */
24125 @@ -59,7 +59,7 @@
24126  
24127         . = ALIGN(8192);        /* Init code and data. */
24128         __init_begin = .;
24129 -       .init.text : {
24130 +       .init.text : { 
24131                    _sinittext = .;
24132                    *(.init.text)
24133                    _einittext = .;
24134 @@ -81,7 +81,7 @@
24135                 *(.initcall5.init);
24136                 *(.initcall6.init);
24137                 *(.initcall7.init);
24138 -               __initcall_end = .;
24139 +               __initcall_end = .;     
24140         }
24141  
24142         .con_initcall.init : {
24143 @@ -94,20 +94,20 @@
24144         __per_cpu_start = .;
24145         .data.percpu  : { *(.data.percpu) }
24146         __per_cpu_end = .;
24147 -
24148 +       
24149         .init.ramfs : {
24150                 __initramfs_start = .;
24151                 *(.init.ramfs)
24152                 __initramfs_end = .;
24153 -               /*
24154 +               /* 
24155                  * We fill to the next page, so we can discard all init
24156                  * pages without needing to consider what payload might be
24157                  * appended to the kernel image.
24158                  */
24159 -               FILL (0);
24160 +               FILL (0); 
24161                 . = ALIGN (8192);
24162         }
24163 -
24164 +       
24165         __vmlinux_end = .;      /* Last address of the physical file. */
24166         __init_end = .;
24167  
24168 diff -urN linux-2.6.19.2.old/arch/cris/kernel/crisksyms.c linux-2.6.19.2.dev/arch/cris/kernel/crisksyms.c
24169 --- linux-2.6.19.2.old/arch/cris/kernel/crisksyms.c     2007-01-10 20:10:37.000000000 +0100
24170 +++ linux-2.6.19.2.dev/arch/cris/kernel/crisksyms.c     2006-11-03 13:49:17.000000000 +0100
24171 @@ -9,7 +9,7 @@
24172  #include <linux/kernel.h>
24173  #include <linux/string.h>
24174  #include <linux/tty.h>
24175 -
24176
24177  #include <asm/semaphore.h>
24178  #include <asm/processor.h>
24179  #include <asm/uaccess.h>
24180 @@ -28,6 +28,7 @@
24181  extern void __ashldi3(void);
24182  extern void __ashrdi3(void);
24183  extern void __lshrdi3(void);
24184 +extern void __negdi2(void);
24185  extern void iounmap(volatile void * __iomem);
24186  
24187  /* Platform dependent support */
24188 @@ -35,18 +36,7 @@
24189  EXPORT_SYMBOL(get_cmos_time);
24190  EXPORT_SYMBOL(loops_per_usec);
24191  
24192 -/* String functions */
24193 -EXPORT_SYMBOL(memcmp);
24194 -EXPORT_SYMBOL(memmove);
24195 -EXPORT_SYMBOL(strstr);
24196 -EXPORT_SYMBOL(strcpy);
24197 -EXPORT_SYMBOL(strchr);
24198 -EXPORT_SYMBOL(strcmp);
24199 -EXPORT_SYMBOL(strlen);
24200 -EXPORT_SYMBOL(strcat);
24201 -EXPORT_SYMBOL(strncat);
24202 -EXPORT_SYMBOL(strncmp);
24203 -EXPORT_SYMBOL(strncpy);
24204 +EXPORT_SYMBOL(ktime_get_ts);
24205  
24206  /* Math functions */
24207  EXPORT_SYMBOL(__Udiv);
24208 @@ -56,6 +46,7 @@
24209  EXPORT_SYMBOL(__ashldi3);
24210  EXPORT_SYMBOL(__ashrdi3);
24211  EXPORT_SYMBOL(__lshrdi3);
24212 +EXPORT_SYMBOL(__negdi2);
24213  
24214  /* Memory functions */
24215  EXPORT_SYMBOL(__ioremap);
24216 @@ -85,4 +76,4 @@
24217  EXPORT_SYMBOL(del_fast_timer);
24218  EXPORT_SYMBOL(schedule_usleep);
24219  #endif
24220 -
24221 +EXPORT_SYMBOL(csum_partial);
24222 diff -urN linux-2.6.19.2.old/arch/cris/kernel/irq.c linux-2.6.19.2.dev/arch/cris/kernel/irq.c
24223 --- linux-2.6.19.2.old/arch/cris/kernel/irq.c   2007-01-10 20:10:37.000000000 +0100
24224 +++ linux-2.6.19.2.dev/arch/cris/kernel/irq.c   2007-01-09 10:29:20.000000000 +0100
24225 @@ -92,14 +92,16 @@
24226  asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
24227  {
24228         unsigned long sp;
24229 +       struct pt_regs *old_regs = set_irq_regs(regs);
24230         irq_enter();
24231         sp = rdsp();
24232         if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
24233                 printk("do_IRQ: stack overflow: %lX\n", sp);
24234                 show_stack(NULL, (unsigned long *)sp);
24235         }
24236 -       __do_IRQ(irq, regs);
24237 +       __do_IRQ(irq);
24238          irq_exit();
24239 +       set_irq_regs(old_regs);
24240  }
24241  
24242  void weird_irq(void)
24243 diff -urN linux-2.6.19.2.old/arch/cris/kernel/process.c linux-2.6.19.2.dev/arch/cris/kernel/process.c
24244 --- linux-2.6.19.2.old/arch/cris/kernel/process.c       2007-01-10 20:10:37.000000000 +0100
24245 +++ linux-2.6.19.2.dev/arch/cris/kernel/process.c       2006-06-25 17:00:10.000000000 +0200
24246 @@ -1,4 +1,4 @@
24247 -/* $Id: process.c,v 1.21 2005/03/04 08:16:17 starvik Exp $
24248 +/* $Id: process.c,v 1.26 2006/06/25 15:00:10 starvik Exp $
24249   * 
24250   *  linux/arch/cris/kernel/process.c
24251   *
24252 @@ -8,6 +8,21 @@
24253   *  Authors:   Bjorn Wesen (bjornw@axis.com)
24254   *
24255   *  $Log: process.c,v $
24256 + *  Revision 1.26  2006/06/25 15:00:10  starvik
24257 + *  Merge of Linux 2.6.17
24258 + *
24259 + *  Revision 1.25  2006/03/22 09:56:56  starvik
24260 + *  Merge of Linux 2.6.16
24261 + *
24262 + *  Revision 1.24  2006/01/04 06:09:48  starvik
24263 + *  Merge of Linux 2.6.15
24264 + *
24265 + *  Revision 1.23  2005/08/29 07:32:19  starvik
24266 + *  Merge of 2.6.13
24267 + *
24268 + *  Revision 1.22  2005/08/18 08:33:18  starvik
24269 + *  Corrected signature of machine_restart
24270 + *
24271   *  Revision 1.21  2005/03/04 08:16:17  starvik
24272   *  Merge of Linux 2.6.11.
24273   *
24274 @@ -195,12 +210,18 @@
24275   */
24276  void (*pm_idle)(void);
24277  
24278 +extern void default_idle(void);
24279 +
24280 +void (*pm_power_off)(void);
24281 +EXPORT_SYMBOL(pm_power_off);
24282 +
24283  /*
24284   * The idle thread. There's no useful work to be
24285   * done, so just try to conserve power and have a
24286   * low exit latency (ie sit in a loop waiting for
24287   * somebody to say that they'd like to reschedule)
24288   */
24289 +
24290  void cpu_idle (void)
24291  {
24292         /* endless idle loop with no priority at all */
24293 diff -urN linux-2.6.19.2.old/arch/cris/kernel/profile.c linux-2.6.19.2.dev/arch/cris/kernel/profile.c
24294 --- linux-2.6.19.2.old/arch/cris/kernel/profile.c       2007-01-10 20:10:37.000000000 +0100
24295 +++ linux-2.6.19.2.dev/arch/cris/kernel/profile.c       2004-10-05 08:22:44.000000000 +0200
24296 @@ -42,7 +42,7 @@
24297    return count;
24298  }
24299  
24300 -static ssize_t
24301 +static ssize_t 
24302  write_cris_profile(struct file *file, const char __user *buf,
24303                size_t count, loff_t *ppos)
24304  {
24305 diff -urN linux-2.6.19.2.old/arch/cris/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/kernel/ptrace.c
24306 --- linux-2.6.19.2.old/arch/cris/kernel/ptrace.c        2007-01-10 20:10:37.000000000 +0100
24307 +++ linux-2.6.19.2.dev/arch/cris/kernel/ptrace.c        2006-03-23 15:54:02.000000000 +0100
24308 @@ -8,6 +8,9 @@
24309   * Authors:   Bjorn Wesen
24310   *
24311   * $Log: ptrace.c,v $
24312 + * Revision 1.11  2006/03/23 14:54:02  starvik
24313 + * Corrected signal handling.
24314 + *
24315   * Revision 1.10  2004/09/22 11:50:01  orjanf
24316   * * Moved get_reg/put_reg to arch-specific files.
24317   * * Added functions to access debug registers (CRISv32).
24318 @@ -82,13 +85,13 @@
24319  /* notification of userspace execution resumption
24320   * - triggered by current->work.notify_resume
24321   */
24322 -extern int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
24323 +extern int do_signal(int canrestart, struct pt_regs *regs);
24324  
24325  
24326 -void do_notify_resume(int canrestart, sigset_t *oldset, struct pt_regs *regs, 
24327 +void do_notify_resume(int canrestart, struct pt_regs *regs, 
24328                       __u32 thread_info_flags  )
24329  {
24330         /* deal with pending signal delivery */
24331         if (thread_info_flags & _TIF_SIGPENDING)
24332 -               do_signal(canrestart,oldset,regs);
24333 +               do_signal(canrestart,regs);
24334  }
24335 diff -urN linux-2.6.19.2.old/arch/cris/kernel/semaphore.c linux-2.6.19.2.dev/arch/cris/kernel/semaphore.c
24336 --- linux-2.6.19.2.old/arch/cris/kernel/semaphore.c     2007-01-10 20:10:37.000000000 +0100
24337 +++ linux-2.6.19.2.dev/arch/cris/kernel/semaphore.c     2005-10-31 09:48:05.000000000 +0100
24338 @@ -4,7 +4,7 @@
24339   */
24340  
24341  #include <linux/sched.h>
24342 -#include <linux/init.h>
24343 +#include <asm/semaphore.h>
24344  #include <asm/semaphore-helper.h>
24345  
24346  /*
24347 @@ -95,6 +95,7 @@
24348         tsk->state = TASK_RUNNING;              \
24349         remove_wait_queue(&sem->wait, &wait);
24350  
24351 +
24352  void __sched __down(struct semaphore * sem)
24353  {
24354         DOWN_VAR
24355 diff -urN linux-2.6.19.2.old/arch/cris/kernel/setup.c linux-2.6.19.2.dev/arch/cris/kernel/setup.c
24356 --- linux-2.6.19.2.old/arch/cris/kernel/setup.c 2007-01-10 20:10:37.000000000 +0100
24357 +++ linux-2.6.19.2.dev/arch/cris/kernel/setup.c 2007-01-09 10:29:20.000000000 +0100
24358 @@ -18,7 +18,7 @@
24359  #include <linux/screen_info.h>
24360  #include <linux/utsname.h>
24361  #include <linux/pfn.h>
24362 -
24363 +#include <linux/cpu.h>
24364  #include <asm/setup.h>
24365  
24366  /*
24367 @@ -36,6 +36,8 @@
24368  
24369  extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */
24370  
24371 +static struct cpu cpu_devices[NR_CPUS];
24372 +
24373  extern void show_etrax_copyright(void);                /* arch-vX/kernel/setup.c */
24374  
24375  /* This mainly sets up the memory area, and can be really confusing.
24376 @@ -187,4 +189,14 @@
24377         .show  = show_cpuinfo,
24378  };
24379  
24380 +static int __init topology_init(void)
24381 +{
24382 +       int i;
24383 +       
24384 +       for_each_possible_cpu(i) {
24385 +                return register_cpu(&cpu_devices[i], i);
24386 +       }
24387 +}
24388 +
24389 +subsys_initcall(topology_init);
24390  
24391 diff -urN linux-2.6.19.2.old/arch/cris/kernel/sys_cris.c linux-2.6.19.2.dev/arch/cris/kernel/sys_cris.c
24392 --- linux-2.6.19.2.old/arch/cris/kernel/sys_cris.c      2007-01-10 20:10:37.000000000 +0100
24393 +++ linux-2.6.19.2.dev/arch/cris/kernel/sys_cris.c      2007-01-09 10:29:20.000000000 +0100
24394 @@ -1,4 +1,4 @@
24395 -/* $Id: sys_cris.c,v 1.6 2004/03/11 11:38:40 starvik Exp $
24396 +/* $Id: sys_cris.c,v 1.7 2007/01/09 09:29:20 starvik Exp $
24397   *
24398   * linux/arch/cris/kernel/sys_cris.c
24399   *
24400 @@ -172,3 +172,4 @@
24401                 return -ENOSYS;
24402         }
24403  }
24404 +
24405 diff -urN linux-2.6.19.2.old/arch/cris/kernel/time.c linux-2.6.19.2.dev/arch/cris/kernel/time.c
24406 --- linux-2.6.19.2.old/arch/cris/kernel/time.c  2007-01-10 20:10:37.000000000 +0100
24407 +++ linux-2.6.19.2.dev/arch/cris/kernel/time.c  2007-01-09 10:29:20.000000000 +0100
24408 @@ -1,4 +1,4 @@
24409 -/* $Id: time.c,v 1.18 2005/03/04 08:16:17 starvik Exp $
24410 +/* $Id: time.c,v 1.23 2007/01/09 09:29:20 starvik Exp $
24411   *
24412   *  linux/arch/cris/kernel/time.c
24413   *
24414 @@ -172,10 +172,6 @@
24415         mon = CMOS_READ(RTC_MONTH);
24416         year = CMOS_READ(RTC_YEAR);
24417  
24418 -       printk(KERN_DEBUG
24419 -              "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n",
24420 -              sec, min, hour, day, mon, year);
24421 -
24422         BCD_TO_BIN(sec);
24423         BCD_TO_BIN(min);
24424         BCD_TO_BIN(hour);
24425 @@ -208,11 +204,11 @@
24426  cris_do_profile(struct pt_regs* regs)
24427  {
24428  
24429 -#if CONFIG_SYSTEM_PROFILER
24430 +#ifdef CONFIG_SYSTEM_PROFILER
24431          cris_profile_sample(regs);
24432  #endif
24433  
24434 -#if CONFIG_PROFILING
24435 +#ifdef CONFIG_PROFILING
24436          profile_tick(CPU_PROFILING, regs);
24437  #endif
24438  }
24439 @@ -222,10 +218,15 @@
24440   */
24441  unsigned long long sched_clock(void)
24442  {
24443 -       return (unsigned long long)jiffies * (1000000000 / HZ);
24444 +       unsigned long long ns;
24445 +
24446 +       ns  = jiffies;
24447 +       ns *= 1000000000 / HZ;
24448 +       ns += get_ns_in_jiffie();
24449 +       return ns;
24450  }
24451  
24452 -static int
24453 +static int 
24454  __init init_udelay(void)
24455  {
24456         loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
24457 diff -urN linux-2.6.19.2.old/arch/cris/kernel/traps.c linux-2.6.19.2.dev/arch/cris/kernel/traps.c
24458 --- linux-2.6.19.2.old/arch/cris/kernel/traps.c 2007-01-10 20:10:37.000000000 +0100
24459 +++ linux-2.6.19.2.dev/arch/cris/kernel/traps.c 2006-12-11 14:04:23.000000000 +0100
24460 @@ -1,66 +1,78 @@
24461 -/* $Id: traps.c,v 1.11 2005/01/24 16:03:19 orjanf Exp $
24462 - *
24463 +/*
24464   *  linux/arch/cris/traps.c
24465   *
24466 - *  Here we handle the break vectors not used by the system call 
24467 - *  mechanism, as well as some general stack/register dumping 
24468 + *  Here we handle the break vectors not used by the system call
24469 + *  mechanism, as well as some general stack/register dumping
24470   *  things.
24471 - * 
24472 - *  Copyright (C) 2000-2002 Axis Communications AB
24473 + *
24474 + *  Copyright (C) 2000-2006 Axis Communications AB
24475   *
24476   *  Authors:   Bjorn Wesen
24477 - *            Hans-Peter Nilsson
24478 + *             Hans-Peter Nilsson
24479   *
24480   */
24481  
24482  #include <linux/init.h>
24483  #include <linux/module.h>
24484 +
24485  #include <asm/pgtable.h>
24486  #include <asm/uaccess.h>
24487  
24488 +extern void arch_enable_nmi(void);
24489 +extern void stop_watchdog(void);
24490 +extern void reset_watchdog(void);
24491 +extern void show_registers(struct pt_regs *regs);
24492 +
24493 +#ifdef CONFIG_DEBUG_BUGVERBOSE
24494 +extern void handle_BUG(struct pt_regs *regs);
24495 +#else
24496 +#define handle_BUG(regs)
24497 +#endif
24498 +
24499  static int kstack_depth_to_print = 24;
24500  
24501 -extern int raw_printk(const char *fmt, ...);
24502 +void (*nmi_handler)(struct pt_regs*);
24503  
24504 -void show_trace(unsigned long * stack)
24505 +void
24506 +show_trace(unsigned long *stack)
24507  {
24508         unsigned long addr, module_start, module_end;
24509         extern char _stext, _etext;
24510         int i;
24511  
24512 -        raw_printk("\nCall Trace: ");
24513 +       printk("\nCall Trace: ");
24514  
24515 -        i = 1;
24516 -        module_start = VMALLOC_START;
24517 -        module_end = VMALLOC_END;
24518 +       i = 1;
24519 +       module_start = VMALLOC_START;
24520 +       module_end = VMALLOC_END;
24521  
24522 -        while (((long) stack & (THREAD_SIZE-1)) != 0) {
24523 -               if (__get_user (addr, stack)) {
24524 +       while (((long)stack & (THREAD_SIZE-1)) != 0) {
24525 +               if (__get_user(addr, stack)) {
24526                         /* This message matches "failing address" marked
24527                            s390 in ksymoops, so lines containing it will
24528                            not be filtered out by ksymoops.  */
24529 -                       raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
24530 +                       printk("Failing address 0x%lx\n", (unsigned long)stack);
24531                         break;
24532                 }
24533                 stack++;
24534  
24535 -                /*
24536 -                 * If the address is either in the text segment of the
24537 -                 * kernel, or in the region which contains vmalloc'ed
24538 -                 * memory, it *may* be the address of a calling
24539 -                 * routine; if so, print it so that someone tracing
24540 -                 * down the cause of the crash will be able to figure
24541 -                 * out the call path that was taken.
24542 -                 */
24543 -                if (((addr >= (unsigned long) &_stext) &&
24544 -                     (addr <= (unsigned long) &_etext)) ||
24545 -                    ((addr >= module_start) && (addr <= module_end))) {
24546 -                        if (i && ((i % 8) == 0))
24547 -                                raw_printk("\n       ");
24548 -                        raw_printk("[<%08lx>] ", addr);
24549 -                        i++;
24550 -                }
24551 -        }
24552 +               /*
24553 +                * If the address is either in the text segment of the
24554 +                * kernel, or in the region which contains vmalloc'ed
24555 +                * memory, it *may* be the address of a calling
24556 +                * routine; if so, print it so that someone tracing
24557 +                * down the cause of the crash will be able to figure
24558 +                * out the call path that was taken.
24559 +                */
24560 +               if (((addr >= (unsigned long)&_stext) &&
24561 +                    (addr <= (unsigned long)&_etext)) ||
24562 +                   ((addr >= module_start) && (addr <= module_end))) {
24563 +                       if (i && ((i % 8) == 0))
24564 +                               printk("\n       ");
24565 +                       printk("[<%08lx>] ", addr);
24566 +                       i++;
24567 +               }
24568 +       }
24569  }
24570  
24571  /*
24572 @@ -78,109 +90,150 @@
24573   * with the ksymoops maintainer.
24574   */
24575  
24576 -void 
24577 +void
24578  show_stack(struct task_struct *task, unsigned long *sp)
24579  {
24580 -        unsigned long *stack, addr;
24581 -        int i;
24582 +       unsigned long *stack, addr;
24583 +       int i;
24584  
24585         /*
24586          * debugging aid: "show_stack(NULL);" prints a
24587          * back trace.
24588          */
24589  
24590 -        if(sp == NULL) {
24591 +       if (sp == NULL) {
24592                 if (task)
24593                         sp = (unsigned long*)task->thread.ksp;
24594                 else
24595                         sp = (unsigned long*)rdsp();
24596         }
24597  
24598 -        stack = sp;
24599 +       stack = sp;
24600  
24601 -       raw_printk("\nStack from %08lx:\n       ", (unsigned long)stack);
24602 -        for(i = 0; i < kstack_depth_to_print; i++) {
24603 -                if (((long) stack & (THREAD_SIZE-1)) == 0)
24604 -                        break;
24605 -                if (i && ((i % 8) == 0))
24606 -                        raw_printk("\n       ");
24607 -               if (__get_user (addr, stack)) {
24608 +       printk("\nStack from %08lx:\n       ", (unsigned long)stack);
24609 +       for (i = 0; i < kstack_depth_to_print; i++) {
24610 +               if (((long)stack & (THREAD_SIZE-1)) == 0)
24611 +                       break;
24612 +               if (i && ((i % 8) == 0))
24613 +                       printk("\n       ");
24614 +               if (__get_user(addr, stack)) {
24615                         /* This message matches "failing address" marked
24616                            s390 in ksymoops, so lines containing it will
24617                            not be filtered out by ksymoops.  */
24618 -                       raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
24619 +                       printk("Failing address 0x%lx\n", (unsigned long)stack);
24620                         break;
24621                 }
24622                 stack++;
24623 -               raw_printk("%08lx ", addr);
24624 -        }
24625 +               printk("%08lx ", addr);
24626 +       }
24627         show_trace(sp);
24628  }
24629  
24630 -static void (*nmi_handler)(struct pt_regs*);
24631 -extern void arch_enable_nmi(void);
24632 +#if 0
24633 +/* displays a short stack trace */
24634  
24635 -void set_nmi_handler(void (*handler)(struct pt_regs*))
24636 +int
24637 +show_stack(void)
24638  {
24639 -  nmi_handler = handler;
24640 -  arch_enable_nmi();
24641 +       unsigned long *sp = (unsigned long *)rdusp();
24642 +       int i;
24643 +
24644 +       printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
24645 +       for (i = 0; i < 16; i++)
24646 +               printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
24647 +       return 0;
24648  }
24649 +#endif
24650  
24651 -void handle_nmi(struct pt_regs* regs)
24652 +void
24653 +dump_stack(void)
24654  {
24655 -  if (nmi_handler)
24656 -    nmi_handler(regs);
24657 +       show_stack(NULL, NULL);
24658 +}
24659 +
24660 +EXPORT_SYMBOL(dump_stack);
24661 +
24662 +void
24663 +set_nmi_handler(void (*handler)(struct pt_regs*))
24664 +{
24665 +       nmi_handler = handler;
24666 +       arch_enable_nmi();
24667  }
24668  
24669  #ifdef CONFIG_DEBUG_NMI_OOPS
24670 -void oops_nmi_handler(struct pt_regs* regs)
24671 +void
24672 +oops_nmi_handler(struct pt_regs* regs)
24673  {
24674 -  stop_watchdog();
24675 -  raw_printk("NMI!\n");
24676 -  show_registers(regs);
24677 +       stop_watchdog();
24678 +       oops_in_progress = 1;
24679 +       printk("NMI!\n");
24680 +       show_registers(regs);
24681 +       oops_in_progress = 0;
24682  }
24683  
24684 -static int
24685 -__init oops_nmi_register(void)
24686 +static int __init
24687 +oops_nmi_register(void)
24688  {
24689 -  set_nmi_handler(oops_nmi_handler);
24690 -  return 0;
24691 +       set_nmi_handler(oops_nmi_handler);
24692 +       return 0;
24693  }
24694  
24695  __initcall(oops_nmi_register);
24696  
24697  #endif
24698  
24699 -#if 0
24700 -/* displays a short stack trace */
24701 -
24702 -int 
24703 -show_stack()
24704 +/*
24705 + * This gets called from entry.S when the watchdog has bitten. Show something
24706 + * similiar to an Oops dump, and if the kernel is configured to be a nice
24707 + * doggy, then halt instead of reboot.
24708 + */
24709 +void
24710 +watchdog_bite_hook(struct pt_regs *regs)
24711  {
24712 -       unsigned long *sp = (unsigned long *)rdusp();
24713 -       int i;
24714 -       raw_printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
24715 -       for(i = 0; i < 16; i++)
24716 -               raw_printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
24717 -       return 0;
24718 -}
24719 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24720 +       local_irq_disable();
24721 +       stop_watchdog();
24722 +       show_registers(regs);
24723 +
24724 +       while (1)
24725 +               ; /* Do nothing. */
24726 +#else
24727 +       show_registers(regs);
24728  #endif
24729 +}
24730  
24731 -void dump_stack(void)
24732 +/* This is normally the Oops function. */
24733 +void
24734 +die_if_kernel(const char *str, struct pt_regs *regs, long err)
24735  {
24736 -       show_stack(NULL, NULL);
24737 -}
24738 +       if (user_mode(regs))
24739 +               return;
24740  
24741 -EXPORT_SYMBOL(dump_stack);
24742 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24743 +       /*
24744 +        * This printout might take too long and could trigger
24745 +        * the watchdog normally. If NICE_DOGGY is set, simply
24746 +        * stop the watchdog during the printout.
24747 +        */
24748 +       stop_watchdog();
24749 +#endif
24750  
24751 -void __init 
24752 -trap_init(void)
24753 -{
24754 -       /* Nothing needs to be done */
24755 +       handle_BUG(regs);
24756 +
24757 +       printk("%s: %04lx\n", str, err & 0xffff);
24758 +
24759 +       show_registers(regs);
24760 +
24761 +       oops_in_progress = 0;
24762 +
24763 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24764 +       reset_watchdog();
24765 +#endif
24766 +       do_exit(SIGSEGV);
24767  }
24768  
24769 -void spinning_cpu(void* addr)
24770 +void __init
24771 +trap_init(void)
24772  {
24773 -  raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr);
24774 -  dump_stack();
24775 +       /* Nothing needs to be done */
24776  }
24777 diff -urN linux-2.6.19.2.old/arch/cris/mm/fault.c linux-2.6.19.2.dev/arch/cris/mm/fault.c
24778 --- linux-2.6.19.2.old/arch/cris/mm/fault.c     2007-01-10 20:10:37.000000000 +0100
24779 +++ linux-2.6.19.2.dev/arch/cris/mm/fault.c     2006-09-29 13:14:06.000000000 +0200
24780 @@ -1,11 +1,27 @@
24781  /*
24782   *  linux/arch/cris/mm/fault.c
24783   *
24784 - *  Copyright (C) 2000, 2001  Axis Communications AB
24785 + *  Copyright (C) 2000-2006  Axis Communications AB
24786 + *
24787 + *  Authors:  Bjorn Wesen
24788   *
24789 - *  Authors:  Bjorn Wesen 
24790 - * 
24791   *  $Log: fault.c,v $
24792 + *  Revision 1.25  2006/09/29 11:14:06  orjanf
24793 + *  * Use arch-independent macro to get irp/erp for v10/v32.
24794 + *
24795 + *  Revision 1.24  2006/09/29 10:58:09  orjanf
24796 + *  * Added user mode SIGSEGV printk.
24797 + *
24798 + *  Revision 1.23  2006/06/20 07:42:56  pkj
24799 + *  Removed an unnecessary reference to raw_printk().
24800 + *
24801 + *  Revision 1.22  2005/08/29 07:32:20  starvik
24802 + *  Merge of 2.6.13
24803 + *
24804 + *  Revision 1.21  2005/07/02 12:29:37  starvik
24805 + *  Use the generic oops_in_progress instead of the raw_printk hack.
24806 + *  Moved some functions to achr-independent code.
24807 + *
24808   *  Revision 1.20  2005/03/04 08:16:18  starvik
24809   *  Merge of Linux 2.6.11.
24810   *
24811 @@ -135,7 +151,6 @@
24812  
24813  extern int find_fixup_code(struct pt_regs *);
24814  extern void die_if_kernel(const char *, struct pt_regs *, long);
24815 -extern int raw_printk(const char *fmt, ...);
24816  
24817  /* debug of low-level TLB reload */
24818  #undef DEBUG
24819 @@ -164,8 +179,8 @@
24820   * address.
24821   *
24822   * error_code:
24823 - *     bit 0 == 0 means no page found, 1 means protection fault
24824 - *     bit 1 == 0 means read, 1 means write
24825 + *      bit 0 == 0 means no page found, 1 means protection fault
24826 + *      bit 1 == 0 means read, 1 means write
24827   *
24828   * If this routine detects a bad access, it returns 1, otherwise it
24829   * returns 0.
24830 @@ -180,9 +195,9 @@
24831         struct vm_area_struct * vma;
24832         siginfo_t info;
24833  
24834 -        D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
24835 -                 address, smp_processor_id(), instruction_pointer(regs),
24836 -                 protection, writeaccess));
24837 +       D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
24838 +                address, smp_processor_id(), instruction_pointer(regs),
24839 +                protection, writeaccess));
24840  
24841         tsk = current;
24842  
24843 @@ -318,6 +333,8 @@
24844                 /* info.si_code has been set above */
24845                 info.si_addr = (void *)address;
24846                 force_sig_info(SIGSEGV, &info, tsk);
24847 +               printk(KERN_NOTICE "%s (pid %d) segfaults for page address %08lx at pc %08lx\n",
24848 +                      tsk->comm, tsk->pid, address, instruction_pointer(regs));
24849                 return;
24850         }
24851  
24852 @@ -325,7 +342,7 @@
24853  
24854         /* Are we prepared to handle this kernel fault?
24855          *
24856 -        * (The kernel has valid exception-points in the source 
24857 +        * (The kernel has valid exception-points in the source
24858          *  when it acesses user-memory. When it fails in one
24859          *  of those points, we find it in a table and do a jump
24860          *  to some fixup code that loads an appropriate error
24861 @@ -340,13 +357,17 @@
24862          * terminate things with extreme prejudice.
24863          */
24864  
24865 -       if ((unsigned long) (address) < PAGE_SIZE)
24866 -               raw_printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
24867 -       else
24868 -               raw_printk(KERN_ALERT "Unable to handle kernel access");
24869 -       raw_printk(" at virtual address %08lx\n",address);
24870 +       if (!oops_in_progress) {
24871 +               oops_in_progress = 1;
24872 +               if ((unsigned long) (address) < PAGE_SIZE)
24873 +                       printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
24874 +               else
24875 +                       printk(KERN_ALERT "Unable to handle kernel access");
24876 +               printk(" at virtual address %08lx\n",address);
24877  
24878 -       die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24879 +               die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24880 +               oops_in_progress = 0;
24881 +       }
24882  
24883         do_exit(SIGKILL);
24884  
24885 @@ -405,8 +426,8 @@
24886                 /* Since we're two-level, we don't need to do both
24887                  * set_pgd and set_pmd (they do the same thing). If
24888                  * we go three-level at some point, do the right thing
24889 -                * with pgd_present and set_pgd here. 
24890 -                * 
24891 +                * with pgd_present and set_pgd here.
24892 +                *
24893                  * Also, since the vmalloc area is global, we don't
24894                  * need to copy individual PTE's, it is enough to
24895                  * copy the pgd pointer into the pte page of the
24896 diff -urN linux-2.6.19.2.old/arch/cris/mm/init.c linux-2.6.19.2.dev/arch/cris/mm/init.c
24897 --- linux-2.6.19.2.old/arch/cris/mm/init.c      2007-01-10 20:10:37.000000000 +0100
24898 +++ linux-2.6.19.2.dev/arch/cris/mm/init.c      2006-06-25 17:00:10.000000000 +0200
24899 @@ -7,6 +7,15 @@
24900   *  Authors:  Bjorn Wesen (bjornw@axis.com)
24901   *
24902   *  $Log: init.c,v $
24903 + *  Revision 1.14  2006/06/25 15:00:10  starvik
24904 + *  Merge of Linux 2.6.17
24905 + *
24906 + *  Revision 1.13  2005/06/20 05:30:00  starvik
24907 + *  Remove unnecessary diff to kernel.org tree
24908 + *
24909 + *  Revision 1.12  2004/08/16 12:37:24  starvik
24910 + *  Merge of Linux 2.6.8
24911 + *
24912   *  Revision 1.11  2004/05/28 09:28:56  starvik
24913   *  Calculation of loops_per_usec moved because initalization order has changed
24914   *  in Linux 2.6.