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
5 config RWSEM_XCHGADD_ALGORITHM
12 config GENERIC_FIND_NEXT_BIT
17 source "fs/Kconfig.binfmt"
19 +config GENERIC_HARDIRQS
26 + SMP support. Always Say N.
34 + bool "Multi-core scheduler support"
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.
43 string "Kernel command line"
44 default "root=/dev/mtdblock3"
47 This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
50 - bool "Preemptible Kernel"
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
58 + bool "Enable reboot at out of memory"
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"
69 Support the xsim ETRAX Simulator.
77 + bool "ETRAX-FS-V32-Simulator"
79 + Support CRIS V32 VCS simualtor.
85 default y if ETRAX100LX || ETRAX100LX_V2
86 default n if !(ETRAX100LX || ETRAX100LX_V2)
88 +config ETRAX_ARCH_V32
90 + default y if ETRAXFS || ETRAXFS_SIM
91 + default n if !(ETRAXFS || ETRAXFS_SIM)
93 config ETRAX_DRAM_SIZE
94 int "DRAM size (dec, in MB)"
97 Size of DRAM (decimal in MB) typically 2, 8 or 16.
99 config ETRAX_FLASH_BUSWIDTH
100 - int "Buswidth of flash in bytes"
101 + int "Buswidth of NOR flash in bytes"
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.
107 -source arch/cris/arch-v10/Kconfig
108 +config ETRAX_NANDFLASH_BUSWIDTH
109 + int "Buswidth of NAND flash in bytes"
112 + Width in bytes of the NAND flash (1 or 2).
114 +config ETRAX_FLASH1_SIZE
115 + int "FLASH1 size (dec, in MB. 0 = Unknown)"
118 +# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
119 +source arch/cris/arch/Kconfig
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
135 source "sound/Kconfig"
137 +source "drivers/pcmcia/Kconfig"
139 +source "drivers/pci/Kconfig"
141 source "drivers/usb/Kconfig"
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
148 menu "Kernel hacking"
150 +source "lib/Kconfig.debug"
152 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
155 bool "Kernel profiling support"
157 config SYSTEM_PROFILER
158 bool "System profiling support"
160 -source "lib/Kconfig.debug"
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
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 $
173 # This file is included by the global makefile so that you can add your own
175 # License. See the file "COPYING" in the main directory of this archive
178 -# A bug in ld prevents us from having a (constant-value) symbol in a
179 -# "ORIGIN =" or "LENGTH =" expression.
182 arch-$(CONFIG_ETRAX_ARCH_V10) := v10
183 arch-$(CONFIG_ETRAX_ARCH_V32) := v32
185 -# No config avaiable for make clean etc
186 +# No config available for make clean etc
188 SARCH := arch-$(arch-y)
191 # cris object files path
192 OBJ_ARCH = $(objtree)/arch/$(ARCH)
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
202 -export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir
204 -vmlinux.bin: vmlinux
205 - $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin
208 - cat vmlinux.bin cramfs.img >timage
211 - cp vmlinux.bin simvmlinux.bin
213 -# the following will remake timage without compiling the kernel
214 -# it does of course require that all object files exist...
217 -## cramfs - Creates a cramfs image
218 - mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img
219 - cat vmlinux.bin cramfs.img >timage
221 -clinux: vmlinux.bin decompress.bin rescue.bin
223 -decompress.bin: $(target_boot_dir)
224 - @$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin
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)
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
236 -$(target_boot_dir): $(target_boot_arch_dir)
239 -$(target_boot_arch_dir):
246 - @if [ -d arch/$(ARCH)/boot ]; then \
247 - $(MAKE) $(clean)=arch/$(ARCH)/boot ; \
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)/$@
254 archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch
256 # Create some links to make all tools happy
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
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
288 + $(Q)if [ -e arch/$(ARCH)/boot ]; then \
289 + $(MAKE) $(clean)=arch/$(ARCH)/boot; \
293 + $(MACHINE)/boot/zImage \
294 + $(SRC_ARCH)/.links \
295 + $(srctree)/include/asm-$(ARCH)/.arch
298 + $(SRC_ARCH)/drivers \
302 + $(SRC_ARCH)/kernel/vmlinux.lds.S \
303 + $(SRC_ARCH)/kernel/asm-offsets.c
306 + echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
307 + echo '* Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
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
316 +Revision 1.2 2005/08/23 09:44:32 starvik
317 +extern inline -> static inline. Patch provided by Adrian Bunk <bunk@stusta.de>
319 Revision 1.1 2001/12/17 13:59:27 bjornw
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
327 -# arch/cris/boot/Makefile
328 +# arch/cris/arch-v10/boot/Makefile
330 -target = $(target_boot_dir)
331 -src = $(src_boot_dir)
333 -zImage: compressed/vmlinuz
334 +OBJCOPY = objcopy-cris
335 +OBJCOPYFLAGS = -O binary --remove-section=.bss
338 - @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz
339 +subdir- := compressed rescue
343 - @$(MAKE) -f $(src)/compressed/Makefile clean
344 +$(obj)/Image: vmlinux FORCE
345 + $(call if_changed,objcopy)
346 + @echo ' Kernel: $@ is ready'
348 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
349 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@
350 + $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
352 +$(obj)/zImage: $(obj)/compressed/vmlinux
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
360 -# create a compressed vmlinuz image from the binary vmlinux.bin file
361 +# arch/cris/arch-v10/boot/compressed/Makefile
363 -target = $(target_compressed_dir)
364 -src = $(src_compressed_dir)
366 CC = gcc-cris -melf $(LINUXINCLUDE)
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
376 -SYSTEM = $(objtree)/vmlinux.bin
377 +quiet_cmd_image = BUILD $@
378 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
380 -all: $(target_compressed_dir)/vmlinuz
381 +targets := vmlinux piggy.gz decompress.o decompress.bin
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)
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
394 +$(obj)/decompress.bin: $(obj)/decompress.o FORCE
395 + $(call if_changed,objcopy)
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 $@
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 $@
407 -# gzip the kernel image
409 -piggy.img: $(SYSTEM)
410 - @cat $(SYSTEM) | gzip -f -9 > piggy.img
416 - rm -f piggy.img $(objtree)/vmlinuz
417 +$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
418 + $(call if_changed,image)
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
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 $
432 * This is a collection of several routines from gzip-1.0.3
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
439 -# Makefile for rescue code
440 +# Makefile for rescue (bootstrap) code
442 -target = $(target_rescue_dir)
443 -src = $(src_rescue_dir)
445 CC = gcc-cris -mlinux $(LINUXINCLUDE)
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
454 +OBJECT = $(obj)/$(obj-y)
456 -all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin
457 +targets := rescue.o rescue.bin
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)
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)
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
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
496 -$(target)/head.o: $(src)/head.S
497 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
499 -$(target)/testrescue.o: $(src)/testrescue.S
500 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
502 -$(target)/kimagerescue.o: $(src)/kimagerescue.S
503 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
506 - rm -f $(target)/*.o $(target)/*.bin
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
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 $
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
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 $
529 * Rescue code to be prepended on a kimage and copied to the
530 * rescue serial port.
534 #define ASSEMBLER_MACROS_ONLY
535 -#include <asm/sv_addr_ag.h>
536 +#include <asm/arch/sv_addr_ag.h>
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
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 $
547 * Simple testcode to download by the rescue block.
548 * Just lits some LEDs to show it was downloaded correctly.
552 #define ASSEMBLER_MACROS_ONLY
553 -#include <asm/sv_addr_ag.h>
554 +#include <asm/arch/sv_addr_ag.h>
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
562 CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
563 # CONFIG_ETRAX_I2C_EEPROM is not set
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
573 This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
577 + bool "PHY not present"
578 + depends on ETRAX_ETHERNET
580 + Enable if PHY is not present.
583 prompt "Network LED behavior"
584 depends on ETRAX_ETHERNET
587 config ETRAX_SERIAL_PORT0_DMA6_OUT
590 + depends on !ETRAX_DEBUG_PORT0
596 config ETRAX_SERIAL_PORT0_DMA7_IN
599 + depends on !ETRAX_DEBUG_PORT0
605 config ETRAX_SERIAL_PORT1_DMA8_OUT
608 + depends on !ETRAX_DEBUG_PORT1
614 config ETRAX_SERIAL_PORT1_DMA9_IN
617 + depends on !ETRAX_DEBUG_PORT1
623 config ETRAX_SERIAL_PORT2_DMA2_OUT
626 + depends on !ETRAX_DEBUG_PORT2
632 config ETRAX_SERIAL_PORT2_DMA3_IN
635 + depends on !ETRAX_DEBUG_PORT2
641 config ETRAX_SERIAL_PORT3_DMA4_OUT
644 + depends on !ETRAX_DEBUG_PORT3
650 config ETRAX_SERIAL_PORT3_DMA5_IN
653 + depends on !ETRAX_DEBUG_PORT3
658 bool "RS-485 support"
659 depends on ETRAX_SERIAL
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.
665 config ETRAX_RS485_ON_PA
666 bool "RS-485 mode on PA"
668 loopback. Not all products are able to do this in software only.
669 Axis 2400/2401 must disable receiver.
671 +config ETRAX_SYNCHRONOUS_SERIAL
672 + bool "Synchronous serial port driver"
674 + Select this to enable the synchronous serial port driver.
676 +config ETRAX_SYNCHRONOUS_SERIAL_PORT0
677 + bool "Synchronous serial port 0 enabled (sser1)"
678 + depends on ETRAX_SYNCHRONOUS_SERIAL
680 +config ETRAX_SYNCHRONOUS_SERIAL0_DMA
681 + bool "Use DMA for synchronous serial port 0"
682 + depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
684 +config ETRAX_SYNCHRONOUS_SERIAL_PORT1
685 + bool "Synchronous serial port 1 enabled (sser3)"
686 + depends on ETRAX_SYNCHRONOUS_SERIAL
688 +config ETRAX_SYNCHRONOUS_SERIAL1_DMA
689 + bool "Use DMA for synchronous serial port 1"
690 + depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
693 bool "ATA/IDE support"
698 select MTD_CFI_AMDSTD
699 - select MTD_OBSOLETE_CHIPS
701 + select MTD_JEDECPROBE
704 select MTD_PARTITIONS
706 This option enables MTD mapping of flash devices. Needed to use
707 flash memories. If unsure, say Y.
709 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
710 + bool "MTD0 is whole boot flash device"
711 + depends on ETRAX_AXISFLASHMAP
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.
718 config ETRAX_PTABLE_SECTOR
719 int "Byte-offset of partition table sector"
720 depends on ETRAX_AXISFLASHMAP
722 Remember that you need to setup the port directions appropriately in
723 the General configuration.
725 -config ETRAX_PA_BUTTON_BITMASK
726 - hex "PA-buttons bitmask"
727 - depends on ETRAX_GPIO
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
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.
738 config ETRAX_PA_CHANGEABLE_DIR
739 hex "PA user changeable dir mask"
740 depends on ETRAX_GPIO
742 Bit set = changeable.
743 You probably want 00 here.
745 +config ETRAX_DEF_R_PORT_G_DIR
746 + bool "Port G Output"
748 + CONFIG_ETRAX_DEF_R_PORT_G_DIR:
749 + Set the direction of specified pins to output.
751 +config ETRAX_DEF_R_PORT_G0_DIR_OUT
753 + depends on ETRAX_DEF_R_PORT_G_DIR
755 + CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT:
758 +config ETRAX_DEF_R_PORT_G8_15_DIR_OUT
760 + depends on ETRAX_DEF_R_PORT_G_DIR
762 + CONFIG_ETRAX_DEF_R_PORT_G8_15_DIR_OUT:
763 + Set G8-G15 to output.
765 +config ETRAX_DEF_R_PORT_G16_23_DIR_OUT
767 + depends on ETRAX_DEF_R_PORT_G_DIR
769 + CONFIG_ETRAX_DEF_R_PORT_G16_23_DIR_OUT:
770 + Set G16-G23 to output.
772 +config ETRAX_DEF_R_PORT_G24_DIR_OUT
774 + depends on ETRAX_DEF_R_PORT_G_DIR
776 + CONFIG_ETRAX_DEF_R_PORT_G24_DIR_OUT:
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
786 obj-$(CONFIG_ETRAX_GPIO) += gpio.o
787 obj-$(CONFIG_ETRAX_DS1302) += ds1302.o
788 obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o
790 +obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
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
796 * partition split defined below.
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.
803 + * Revision 1.16 2006/10/30 15:17:57 pkj
804 + * Avoid a compiler warning.
806 + * Revision 1.15 2006/10/13 12:43:10 starvik
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.
813 + * Revision 1.13 2006/01/04 06:09:45 starvik
814 + * Merge of Linux 2.6.15
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).
819 * Revision 1.11 2004/11/15 10:27:14 starvik
820 * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>).
826 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
827 +/* Main flash device */
828 +static struct mtd_partition main_partition = {
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);
842 -#ifdef CONFIG_MTD_AMDSTD
843 - mtd_cs = do_map_probe("amd_flash", map_cs);
845 #ifdef CONFIG_MTD_CFI
846 + mtd_cs = do_map_probe("cfi_probe", map_cs);
848 +#ifdef CONFIG_MTD_JEDECPROBE
850 - mtd_cs = do_map_probe("cfi_probe", map_cs);
851 + mtd_cs = do_map_probe("jedec_probe", map_cs);
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";
862 if (!(mymtd = flash_probe())) {
863 /* There's no reason to use this module if no flash chip can
868 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
870 + main_partition.size = mymtd->size;
871 + err = add_mtd_partitions(mymtd, &main_partition, 1);
873 + panic("axisflashmap: Could not initialize "
874 + "partition for whole main mtd device!\n");
879 if (use_default_ptable) {
880 printk(KERN_INFO " Using default partition table.\n");
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);
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
895 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
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
901 -*! Revision 1.17 2005/01/05 06:11:22 starvik
902 -*! No need to do local_irq_disable after local_irq_save.
904 -*! Revision 1.16 2004/12/13 12:21:52 starvik
905 -*! Added I/O and DMA allocators from Linux 2.4
907 -*! Revision 1.14 2004/08/24 06:48:43 starvik
908 -*! Whitespace cleanup
910 -*! Revision 1.13 2004/05/28 09:26:59 starvik
911 -*! Modified I2C initialization to work in 2.6.
913 -*! Revision 1.12 2004/05/14 07:58:03 starvik
914 -*! Merge of changes from 2.4
916 -*! Revision 1.10 2004/02/04 09:25:12 starvik
917 -*! Merge of Linux 2.6.2
919 -*! Revision 1.9 2003/07/04 08:27:37 starvik
920 -*! Merge of Linux 2.5.74
922 -*! Revision 1.8 2003/04/09 05:20:47 starvik
923 -*! Merge of Linux 2.5.67
925 -*! Revision 1.6 2003/01/09 14:42:51 starvik
926 -*! Merge of Linux 2.5.55
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)
932 -*! Revision 1.3 2002/11/20 11:56:10 starvik
933 -*! Merge of Linux 2.5.48
935 -*! Revision 1.2 2002/11/18 13:16:06 starvik
936 -*! Linux 2.5 port of latest 2.4 drivers
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.
942 -*! Revision 1.14 2002/10/10 12:15:38 magnusmn
943 -*! Added support for having the RST signal on bit g0
945 -*! Revision 1.13 2002/05/29 15:16:08 johana
946 -*! Removed unused variables.
948 -*! Revision 1.12 2002/04/10 15:35:25 johana
949 -*! Moved probe function closer to init function and marked it __init.
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.
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).
958 -*! Revision 1.8 2001/06/14 08:06:32 jonashg
959 -*! Made tempudelay delay usecs (well, just a tad more).
961 -*! Revision 1.7 2001/06/13 14:18:11 jonashg
962 -*! Only allow processes with SYS_TIME capability to set time and charge.
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).
970 -*! Revision 1.5 2001/06/12 14:35:13 jonashg
971 -*! Gave the module a name and added it to printk's.
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).
977 -*! Revision 1.3 2001/03/26 16:03:06 bjornw
978 -*! Needs linux/config.h
980 -*! Revision 1.2 2001/03/20 19:42:00 bjornw
981 -*! Use the ETRAX prefix on the DS1302 options
983 -*! Revision 1.1 2001/03/20 09:13:50 magnusmn
986 -*! Revision 1.10 2000/07/05 15:38:23 bjornw
987 -*! Dont update kernel time when a RTC_SET_TIME is done
989 -*! Revision 1.9 2000/03/02 15:42:59 macce
990 -*! * Hack to make RTC work on all 2100/2400
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.
995 -*! Revision 1.7 2000/01/17 15:51:43 johana
996 -*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
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.
1002 -*! Revision 1.5 1999/10/27 12:39:37 bjornw
1003 -*! Disabled superuser check. Anyone can now set the time.
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.
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).
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.
1018 -*! Revision 1.1 1999/09/01 09:45:29 bjornw
1019 -*! Implemented a DS1302 RTC driver.
1022 *! ---------------------------------------------------------------------------
1024 -*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN
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
1029 *!***************************************************************************/
1031 @@ -305,14 +178,7 @@
1033 ds1302_writereg(int reg, unsigned char val)
1035 -#ifndef CONFIG_ETRAX_RTC_READONLY
1036 int do_writereg = 1;
1038 - int do_writereg = 0;
1040 - if (reg == RTC_TRICKLECHARGER)
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
1050 *! in the spin-lock.
1052 *! $Log: eeprom.c,v $
1053 +*! Revision 1.13 2006/10/13 12:43:10 starvik
1056 *! Revision 1.12 2005/06/19 17:06:46 starvik
1057 *! Merge of Linux 2.6.12.
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
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 $
1066 * Etrax general port I/O device
1069 * Johan Adolfsson (read/set directions, write, port G)
1072 + * Revision 1.28 2007/02/05 11:54:34 pkj
1073 + * Merge of Linux 2.6.19
1075 + * Revision 1.27 2006/12/12 11:08:30 edgar
1076 + * In etrax_gpio_wake_up_check(), make flags unsigned long.
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.
1082 + * Revision 1.25 2006/10/13 12:43:10 starvik
1085 + * Revision 1.24 2006/07/13 07:42:20 starvik
1086 + * Set unique device id in request_irq
1088 + * Revision 1.23 2006/06/21 09:38:46 starvik
1089 + * Use correct spinlock macros
1091 + * Revision 1.22 2005/08/29 07:32:16 starvik
1094 + * Revision 1.21 2005/08/16 17:10:54 edgar
1095 + * dont leave locked spinlocks when returning.
1097 + * Revision 1.20 2005/08/15 13:10:47 orjanf
1098 + * Don't link struct into alarmlist until fully initialized.
1100 + * Revision 1.19 2005/07/13 11:43:11 karljope
1103 + * Revision 1.18 2005/06/21 12:26:53 starvik
1104 + * Improved alarm list locking.
1106 * Revision 1.17 2005/06/19 17:06:46 starvik
1107 * Merge of Linux 2.6.12.
1110 unsigned int mask = 0;
1111 struct gpio_private *priv = (struct gpio_private *)file->private_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;
1124 + spin_unlock_irq(&gpio_lock);
1128 if ((data & priv->highalarm) ||
1129 (~data & priv->lowalarm)) {
1130 mask = POLLIN|POLLRDNORM;
1133 - spin_unlock(&gpio_lock);
1134 + spin_unlock_irq(&gpio_lock);
1136 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
1138 @@ -314,10 +350,12 @@
1140 int etrax_gpio_wake_up_check(void)
1142 - struct gpio_private *priv = alarmlist;
1143 + struct gpio_private *priv;
1144 unsigned long data = 0;
1146 - spin_lock(&gpio_lock);
1147 + unsigned long flags;
1148 + spin_lock_irqsave(&gpio_lock, flags);
1151 if (USE_PORTS(priv)) {
1153 @@ -332,12 +370,12 @@
1157 - spin_unlock(&gpio_lock);
1158 + spin_unlock_irqrestore(&gpio_lock, flags);
1163 -gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1164 +gpio_poll_timer_interrupt(int irq, void *dev_id)
1166 if (gpio_some_alarms) {
1167 etrax_gpio_wake_up_check();
1172 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1173 +gpio_pa_interrupt(int irq, void *dev_id)
1176 spin_lock(&gpio_lock);
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;
1182 - spin_lock(&gpio_lock);
1184 ssize_t retval = count;
1185 if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
1188 if (clk_mask == 0 || data_mask == 0) {
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));
1199 - spin_unlock(&gpio_lock);
1200 + spin_unlock_irq(&gpio_lock);
1204 @@ -445,13 +481,12 @@
1208 + memset(priv, 0, sizeof(*priv));
1212 - /* initialize the io/alarm struct and link it into our alarmlist */
1213 + /* initialize the io/alarm struct */
1215 - priv->next = alarmlist;
1217 if (USE_PORTS(priv)) { /* A and B */
1218 priv->port = ports[p];
1219 priv->shadow = shads[p];
1220 @@ -476,6 +511,12 @@
1222 filp->private_data = (void *)priv;
1224 + /* link it into our alarmlist */
1225 + spin_lock_irq(&gpio_lock);
1226 + priv->next = alarmlist;
1228 + spin_unlock_irq(&gpio_lock);
1233 @@ -485,10 +526,10 @@
1234 struct gpio_private *p;
1235 struct gpio_private *todel;
1237 - spin_lock(&gpio_lock);
1238 + spin_lock_irq(&gpio_lock);
1241 - todel = (struct gpio_private *)filp->private_data;
1243 + todel = (struct gpio_private *)filp->private_data;
1245 /* unlink from alarmlist and free the private structure */
1247 @@ -506,12 +547,13 @@
1249 if (p->highalarm | p->lowalarm) {
1250 gpio_some_alarms = 1;
1251 + spin_unlock_irq(&gpio_lock);
1256 gpio_some_alarms = 0;
1257 - spin_unlock(&gpio_lock);
1258 + spin_unlock_irq(&gpio_lock);
1263 /* Must update gpio_some_alarms */
1264 struct gpio_private *p = alarmlist;
1266 + spin_lock_irq(&gpio_lock);
1270 if (p->highalarm | p->lowalarm) {
1274 gpio_some_alarms = some_alarms;
1275 + spin_unlock_irq(&gpio_lock);
1278 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
1279 @@ -937,11 +982,11 @@
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");
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");
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
1297 *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff -
1298 *! don't use PB_I2C if DS1302 uses same bits,
1300 +*! June 23 2003 Pieter Grimmerink Added 'i2c_sendnack'. i2c_readreg now
1301 +*! generates nack on last received byte,
1303 +*! i2c_getack changed data level while clock
1304 +*! was high, causing DS75 to see a stop condition
1307 +*! Revision 1.17 2006/10/13 12:43:10 starvik
1310 +*! Revision 1.16 2005/09/29 13:33:35 bjarne
1311 +*! If "first" should have any purpos it should probably change value....
1313 +*! Revision 1.15 2005/08/29 07:32:16 starvik
1316 +*! Revision 1.14 2005/06/30 18:07:31 starvik
1317 +*! Added the sendnack patch from 2.4.
1319 *! Revision 1.13 2005/03/07 13:13:07 starvik
1320 *! Added spinlocks to protect states etc
1323 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
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 $ */
1329 /****************** INCLUDE FILES SECTION ***********************************/
1332 i2c_delay(CLOCK_HIGH_TIME);
1333 i2c_clk(I2C_CLOCK_LOW);
1334 i2c_delay(CLOCK_LOW_TIME);
1341 * last received byte needs to be nacked
1355 /* Setup and enable the Port B I2C interface */
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
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.
1367 - * Copyright (c) 2002, Axis Communications AB
1368 + * Copyright (c) 2002-2006, Axis Communications AB
1369 * All rights reserved.
1371 * Author: Tobias Anderberg <tobiasa@axis.com>.
1373 - * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $
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>
1383 #include <asm/uaccess.h>
1384 #include <asm/system.h>
1386 -#include <asm/arch/svinto.h>
1387 #include <asm/rtc.h>
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 $"
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 $"
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)
1408 static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
1411 static const unsigned char days_in_month[] =
1412 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1414 int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
1416 +/* Cache VL bit value read at driver init since writing the RTC_SECOND
1417 + * register clears the VL status.
1419 +static int voltage_low = 0;
1421 static struct file_operations pcf8563_fops = {
1422 - .owner = THIS_MODULE,
1423 - .ioctl = pcf8563_ioctl,
1424 + owner: THIS_MODULE,
1425 + ioctl: pcf8563_ioctl,
1429 -pcf8563_readreg(int reg)
1430 +pcf8563_readreg(int reg)
1432 - unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
1433 + unsigned char res = rtc_read(reg);
1435 - /* The PCF8563 does not return 0 for unimplemented bits */
1438 + /* The PCF8563 does not return 0 for unimplemented bits. */
1447 case RTC_DAY_OF_MONTH:
1456 - res = (res & 0x1f) - 1; /* PCF8563 returns month in range 1-12 */
1460 + case RTC_CONTROL1:
1463 + case RTC_CONTROL2:
1466 + case RTC_CLOCKOUT_FREQ:
1467 + case RTC_TIMER_CONTROL:
1475 -pcf8563_writereg(int reg, unsigned char val)
1476 +pcf8563_writereg(int reg, unsigned char val)
1478 -#ifdef CONFIG_ETRAX_RTC_READONLY
1479 - if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
1483 rtc_write(reg, val);
1487 get_rtc_time(struct rtc_time *tm)
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);
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);
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;
1522 BCD_TO_BIN(tm->tm_sec);
1523 BCD_TO_BIN(tm->tm_min);
1524 @@ -126,17 +137,25 @@
1529 + static int res = 0;
1530 + static int first = 1;
1537 - if ((ret = i2c_init())) {
1538 - printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
1540 + /* Initiate the i2c protocol. */
1543 + printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
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
1554 if (rtc_write(RTC_CONTROL1, 0x00) < 0)
1556 @@ -147,41 +166,44 @@
1557 if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
1560 - /* Clear the VL bit in the seconds register. */
1561 - ret = rtc_read(RTC_SECONDS);
1563 - if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
1564 + if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
1568 /* Reset the alarms. */
1569 - if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
1570 + if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
1573 - if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
1575 + if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
1578 - if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
1580 + if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
1583 - if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
1585 + if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
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);
1594 + /* Check for low voltage, and warn about it. */
1595 + if (rtc_read(RTC_SECONDS) & 0x80) {
1597 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1598 + "date/time information is no longer guaranteed!\n",
1605 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
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",
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)
1629 /* Some sanity checks. */
1630 if (_IOC_TYPE(cmd) != RTC_MAGIC)
1631 @@ -201,123 +224,151 @@
1636 - struct rtc_time tm;
1638 - spin_lock(&rtc_lock);
1639 - get_rtc_time(&tm);
1641 + struct rtc_time tm;
1643 - if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
1644 - spin_unlock(&rtc_lock);
1647 + spin_lock(&rtc_lock);
1648 + memset(&tm, 0, sizeof tm);
1649 + get_rtc_time(&tm);
1651 + if (copy_to_user((struct rtc_time *) arg, &tm,
1653 spin_unlock(&rtc_lock);
1659 + spin_unlock(&rtc_lock);
1665 -#ifdef CONFIG_ETRAX_RTC_READONLY
1670 + struct rtc_time tm;
1672 + memset(&tm, 0, sizeof tm);
1673 + if (!capable(CAP_SYS_TIME))
1678 - struct rtc_time tm;
1680 - memset(&tm, 0, sizeof (struct rtc_time));
1681 - if (!capable(CAP_SYS_TIME))
1684 - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
1687 - /* Convert from struct tm to struct rtc_time. */
1688 - tm.tm_year += 1900;
1691 - leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
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))
1703 - century = (tm.tm_year >= 2000) ? 0x80 : 0;
1704 - tm.tm_year = tm.tm_year % 100;
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;
1713 - spin_lock(&rtc_lock);
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);
1722 - spin_unlock(&rtc_lock);
1723 + if (copy_from_user(&tm, (struct rtc_time *) arg,
1729 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
1730 + /* Convert from struct tm to struct rtc_time. */
1731 + tm.tm_year += 1900;
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.
1739 + year = tm.tm_year;
1740 + leap = (tm.tm_mon == 2) &&
1741 + ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
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)) {
1758 + century = (tm.tm_year >= 2000) ? 0x80 : 0;
1759 + tm.tm_year = tm.tm_year % 100;
1761 - if (rtc_read(RTC_SECONDS) & 0x80) {
1763 - printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1764 - "date/time information is no longer guaranteed!\n",
1767 - if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
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;
1777 + spin_lock(&rtc_lock);
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);
1787 + spin_unlock(&rtc_lock);
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);
1798 + if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
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. */
1813 int ret = rtc_read(RTC_SECONDS);
1815 rtc_write(RTC_SECONDS, (ret & 0x7F));
1817 + /* Clear the cached value. */
1833 pcf8563_register(void)
1836 + if (pcf8563_init() < 0) {
1837 + printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
1838 + "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
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);
1850 - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
1852 + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
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);
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
1870 + * Simple synchronous serial port driver for ETRAX 100LX.
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
1877 + * Copyright (c) 2001-2006 Axis Communications AB
1879 + * Author: Mikael Starvik, Johan Adolfsson
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>
1902 +/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
1904 +/* Three DMA descriptors are linked together. Each DMA descriptor is */
1905 +/* responsible for port->bufchunk of a common buffer. */
1907 +/* +---------------------------------------------+ */
1908 +/* | +----------+ +----------+ +----------+ | */
1909 +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */
1910 +/* +----------+ +----------+ +----------+ */
1913 +/* +-------------------------------------+ */
1915 +/* +-------------------------------------+ */
1916 +/* |<- data_avail ->| */
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 */
1927 +#define SYNC_SERIAL_MAJOR 125
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
1936 +#define DEFAULT_FRAME_RATE 0
1937 +#define DEFAULT_WORD_RATE 7
1939 +/* NOTE: Enabling some debug will likely cause overrun or underrun,
1940 + * especially if manual mode is use.
1943 +#define DEBUGREAD(x)
1944 +#define DEBUGWRITE(x)
1945 +#define DEBUGPOLL(x)
1946 +#define DEBUGRXINT(x)
1947 +#define DEBUGTXINT(x)
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)
1955 +typedef struct sync_port
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;
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 */
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 */
1980 + char enabled; /* 1 if port is enabled */
1981 + char use_dma; /* 1 if port uses dma */
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 */
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;
2003 + wait_queue_head_t out_wait_q;
2004 + wait_queue_head_t in_wait_q;
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);
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);
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);
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
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);
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
2043 +#ifdef SYNC_SER_MANUAL
2044 +static irqreturn_t manual_interrupt(int irq, void *dev_id);
2048 +static struct sync_port ports[]=
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),
2067 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
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),
2090 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
2098 +/* Register shadows */
2099 +static unsigned sync_serial_prescale_shadow = 0;
2101 +#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
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
2113 +static int __init etrax_sync_serial_init(void)
2115 + ports[0].enabled = 0;
2116 + ports[1].enabled = 0;
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);
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);
2129 + printk(KERN_CRIT "ETRAX100LX sync_serial: Could not allocate IO group for port %d\n", 1);
2134 + if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
2136 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2137 + cris_free_io_interface(if_sync_serial_3);
2139 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2140 + cris_free_io_interface(if_sync_serial_1);
2142 + printk("unable to get major for synchronous serial port\n");
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;
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;
2159 + ports[0].use_dma = 0;
2161 + initialize_port(0);
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;
2171 + ports[1].use_dma = 0;
2173 + initialize_port(1);
2176 + *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
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));
2189 + /* Select synchronous ports */
2190 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2192 + printk("ETRAX 100LX synchronous serial port driver\n");
2196 +static void __init initialize_port(int portnbr)
2198 + struct sync_port* port = &ports[portnbr];
2200 + DEBUG(printk("Init sync serial port %d\n", portnbr));
2202 + port->started = 0;
2203 + port->port_nbr = portnbr;
2205 + port->tr_running = 0;
2207 + port->out_count = 0;
2208 + port->outp = port->out_buffer;
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;
2218 + init_waitqueue_head(&port->out_wait_q);
2219 + init_waitqueue_head(&port->in_wait_q);
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);
2245 + if (port->use_dma)
2246 + port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, on);
2248 + port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, off);
2250 + *port->ctrl_data = port->ctrl_data_shadow;
2253 +static inline int sync_data_avail(struct sync_port *port)
2256 + unsigned char *start;
2257 + unsigned char *end;
2259 + start = (unsigned char*)port->readp; /* cast away volatile */
2260 + end = (unsigned char*)port->writep; /* cast away volatile */
2261 + /* 0123456789 0123456789
2267 + avail = end - start;
2269 + avail = port->in_buffer_size - (start - end);
2273 +static inline int sync_data_avail_to_end(struct sync_port *port)
2276 + unsigned char *start;
2277 + unsigned char *end;
2279 + start = (unsigned char*)port->readp; /* cast away volatile */
2280 + end = (unsigned char*)port->writep; /* cast away volatile */
2281 + /* 0123456789 0123456789
2287 + avail = end - start;
2289 + avail = port->flip + port->in_buffer_size - start;
2294 +static int sync_serial_open(struct inode *inode, struct file *file)
2296 + int dev = MINOR(inode->i_rdev);
2300 + DEBUG(printk("Open sync serial port %d\n", dev));
2302 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2304 + DEBUG(printk("Invalid minor %d\n", dev));
2307 + port = &ports[dev];
2308 + /* Allow open this device twice (assuming one reader and one writer) */
2309 + if (port->busy == 2)
2311 + DEBUG(printk("Device is busy.. \n"));
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,
2321 + "synchronous serial 1 dma tr",
2323 + printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2325 + } else if(request_irq(25,
2328 + "synchronous serial 1 dma rx",
2330 + free_irq(24, &port[0]);
2331 + printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2333 + } else if (cris_request_dma(8,
2334 + "synchronous serial 1 dma tr",
2335 + DMA_VERBOSE_ON_ERROR,
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");
2341 + } else if (cris_request_dma(9,
2342 + "synchronous serial 1 dma rec",
2343 + DMA_VERBOSE_ON_ERROR,
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");
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);
2362 + else if (port == &ports[1]){
2363 +#ifdef SYNC_SER_DMA
2364 + if (request_irq(20,
2367 + "synchronous serial 3 dma tr",
2369 + printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2371 + } else if (request_irq(21,
2374 + "synchronous serial 3 dma rx",
2376 + free_irq(20, &ports[1]);
2377 + printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2379 + } else if (cris_request_dma(4,
2380 + "synchronous serial 3 dma tr",
2381 + DMA_VERBOSE_ON_ERROR,
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");
2387 + } else if (cris_request_dma(5,
2388 + "synchronous serial 3 dma rec",
2389 + DMA_VERBOSE_ON_ERROR,
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");
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);
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,
2415 + IRQF_SHARED | IRQF_DISABLED,
2416 + "synchronous serial manual irq",
2418 + printk("Can't allocate sync serial manual irq");
2421 + } else if (port == &ports[1]) {
2422 + if (request_irq(8,
2424 + IRQF_SHARED | IRQF_DISABLED,
2425 + "synchronous serial manual irq",
2427 + printk(KERN_CRIT "Can't allocate sync serial manual irq");
2431 + port->init_irqs = 0;
2433 + panic("sync_serial: Manual mode not supported.\n");
2434 +#endif /* SYNC_SER_MANUAL */
2436 + } /* port->init_irqs */
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));
2457 +static int sync_serial_release(struct inode *inode, struct file *file)
2459 + int dev = MINOR(inode->i_rdev);
2462 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2464 + DEBUG(printk("Invalid minor %d\n", dev));
2467 + port = &ports[dev];
2471 + *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) |
2472 + (1 << port->transmitter_ready_bit));
2479 +static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
2481 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2482 + unsigned int mask = 0;
2484 + DEBUGPOLL( static unsigned int prev_mask = 0; );
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;
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":"");
2504 +static int sync_serial_ioctl(struct inode *inode, struct file *file,
2505 + unsigned int cmd, unsigned long arg)
2507 + int return_val = 0;
2508 + unsigned long flags;
2510 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2513 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2515 + DEBUG(printk("Invalid minor %d\n", dev));
2518 + port = &ports[dev];
2520 + local_irq_save(flags);
2521 + /* Disable port while changing config */
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);
2532 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
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);
2544 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
2546 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2547 + local_irq_restore(flags);
2552 + if (GET_SPEED(arg) == CODEC)
2555 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec);
2557 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec);
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));
2565 + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg));
2567 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate);
2569 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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)
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);
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);
2679 + case SSP_INBUFCHUNK:
2681 + if (arg > port->in_buffer_size/NUM_IN_DESCR)
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) {
2695 + start_dma_in(port);
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();
2710 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
2712 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
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.
2718 + if (port->use_dma) {
2719 + if (port->port_nbr == 0) {
2726 + start_dma_in(port);
2728 + local_irq_restore(flags);
2729 + return return_val;
2733 +static ssize_t sync_serial_write(struct file * file, const char * buf,
2734 + size_t count, loff_t *ppos)
2736 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2737 + DECLARE_WAITQUEUE(wait, current);
2739 + unsigned long flags;
2740 + unsigned long c, c1;
2741 + unsigned long free_outp;
2742 + unsigned long outp;
2743 + unsigned long out_buffer;
2745 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2747 + DEBUG(printk("Invalid minor %d\n", dev));
2750 + port = &ports[dev];
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 */
2755 + * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE
2756 + * outp^ +out_count
2758 + * out_buffer 45<- c ->0123OUT_BUFFER_SIZE
2759 + * +out_count outp^
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;
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;
2778 + c = outp - free_outp;
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))
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))
2793 + local_irq_save(flags);
2794 + port->out_count += count;
2795 + local_irq_restore(flags);
2797 + /* Make sure transmitter/receiver is running */
2798 + if (!port->started)
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;
2806 + *port->ctrl_data = port->ctrl_data_shadow;
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 */
2814 + /* and enable transmitter ready IRQ */
2815 + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2817 + start_dma(port, (unsigned char* volatile )port->outp, c);
2820 + local_irq_restore(flags);
2821 + DEBUGWRITE(printk("w d%d c %lu NB\n",
2822 + port->port_nbr, count));
2826 + /* Sleep until all sent */
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 */
2835 + /* and enable transmitter ready IRQ */
2836 + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2838 + start_dma(port, port->outp, c);
2841 + local_irq_restore(flags);
2843 + set_current_state(TASK_RUNNING);
2844 + remove_wait_queue(&port->out_wait_q, &wait);
2845 + if (signal_pending(current))
2849 + DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count));
2853 +static ssize_t sync_serial_read(struct file * file, char * buf,
2854 + size_t count, loff_t *ppos)
2856 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2859 + unsigned char* start;
2860 + unsigned char* end;
2861 + unsigned long flags;
2863 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2865 + DEBUG(printk("Invalid minor %d\n", dev));
2868 + port = &ports[dev];
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));
2872 + if (!port->started)
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;
2879 + *port->ctrl_data = port->ctrl_data_shadow;
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 */
2890 + if (file->f_flags & O_NONBLOCK)
2895 + interruptible_sleep_on(&port->in_wait_q);
2896 + if (signal_pending(current))
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);
2906 + /* Lazy read, never return wrapped data. */
2908 + avail = port->in_buffer_size;
2909 + else if (end > start)
2910 + avail = end - start;
2912 + avail = port->flip + port->in_buffer_size - start;
2914 + count = count > avail ? avail : count;
2915 + if (copy_to_user(buf, start, count))
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;
2923 + local_irq_restore(flags);
2924 + DEBUGREAD(printk("r %d\n", count));
2928 +static void send_word(sync_port* port)
2930 + switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow))
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;
2938 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
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;
2948 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
2949 + port->out_count-=2;
2950 + *port->data_out = *(unsigned short *)port->outp;
2952 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2953 + port->outp = port->out_buffer;
2955 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
2956 + port->out_count-=3;
2957 + *port->data_out = *(unsigned int *)port->outp;
2959 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2960 + port->outp = port->out_buffer;
2962 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
2963 + port->out_count-=4;
2964 + *port->data_out = *(unsigned int *)port->outp;
2966 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2967 + port->outp = port->out_buffer;
2973 +static void start_dma(struct sync_port* port, const char* data, int count)
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;
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));
2988 +static void start_dma_in(sync_port* port)
2991 + unsigned long buf;
2992 + port->writep = port->flip;
2994 + if (port->writep > port->flip + port->in_buffer_size)
2996 + panic("Offset too large in sync serial driver\n");
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]);
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);
3020 +#ifdef SYNC_SER_DMA
3021 +static irqreturn_t tr_interrupt(int irq, void *dev_id)
3023 + unsigned long ireg = *R_IRQ_MASK2_RD;
3025 + struct etrax_dma_descr *descr;
3026 + unsigned int sentl;
3029 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3031 + sync_port *port = &ports[i];
3032 + if (!port->enabled || !port->use_dma )
3035 + if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */
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);
3044 + descr = &port->out_descr;
3045 + if (!(descr->status & d_stop)) {
3046 + sentl = descr->sw_len;
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) {
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);
3062 + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
3063 + port->tr_running = 0;
3065 + wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
3068 + return IRQ_RETVAL(handled);
3069 +} /* tr_interrupt */
3071 +static irqreturn_t rx_interrupt(int irq, void *dev_id)
3073 + unsigned long ireg = *R_IRQ_MASK2_RD;
3077 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3079 + sync_port *port = &ports[i];
3081 + if (!port->enabled || !port->use_dma )
3084 + if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */
3087 + while (*port->input_dma_descr != virt_to_phys(port->next_rx_desc)) {
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;
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;
3100 + if (port->writep == port->readp)
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);
3119 + return IRQ_RETVAL(handled);
3120 +} /* rx_interrupt */
3121 +#endif /* SYNC_SER_DMA */
3123 +#ifdef SYNC_SER_MANUAL
3124 +static irqreturn_t manual_interrupt(int irq, void *dev_id)
3129 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3131 + sync_port* port = &ports[i];
3133 + if (!port->enabled || port->use_dma)
3138 + if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit)) /* Data received? */
3142 + switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize))
3144 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
3145 + *port->writep++ = *(volatile char *)port->data_in;
3147 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
3149 + int data = *(unsigned short *)port->data_in;
3150 + *port->writep = (data & 0x0ff0) >> 4;
3151 + *(port->writep + 1) = data & 0x0f;
3155 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
3156 + *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in;
3159 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
3160 + *(unsigned int*)port->writep = *port->data_in;
3163 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
3164 + *(unsigned int*)port->writep = *port->data_in;
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
3175 + if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
3176 + port->readp = port->flip;
3178 + if (sync_data_avail(port) >= port->inbufchunk)
3179 + wake_up_interruptible(&port->in_wait_q); /* Wake up application */
3182 + if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */
3184 + if (port->out_count > 0) /* More data to send */
3186 + else /* transmission finished */
3188 + *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */
3189 + wake_up_interruptible(&port->out_wait_q); /* Wake up application */
3193 + return IRQ_RETVAL(handled);
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
3202 * init_etrax_debug()
3204 * $Log: debugport.c,v $
3205 + * Revision 1.36 2006/10/30 15:17:57 pkj
3206 + * Avoid a compiler warning.
3208 + * Revision 1.35 2006/10/13 12:43:11 starvik
3211 + * Revision 1.34 2006/09/29 10:32:01 starvik
3212 + * Don't reference serial driver if not present
3214 + * Revision 1.33 2006/09/08 07:59:29 karljope
3215 + * Makes v10 boot again when watchdog is enabled
3217 + * Revision 1.32 2006/06/20 08:23:36 pkj
3218 + * Reverted incorrect merge.
3220 + * Revision 1.31 2006/05/17 12:22:10 edgar
3221 + * check port before disable ints
3223 + * Revision 1.30 2005/11/15 12:08:42 starvik
3224 + * Set index when no debug port is defined
3226 + * Revision 1.29 2005/08/29 07:32:17 starvik
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.
3233 * Revision 1.27 2005/06/10 10:34:14 starvik
3234 * Real console support
3237 #include <asm/arch/svinto.h>
3238 #include <asm/io.h> /* Get SIMCOUT. */
3240 +extern void reset_watchdog(void);
3249 +#ifdef CONFIG_ETRAX_SERIAL
3250 extern struct tty_driver *serial_driver;
3253 struct dbg_port* port =
3254 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
3255 @@ -368,11 +400,12 @@
3258 unsigned long flags;
3259 - local_irq_save(flags);
3266 + local_irq_save(flags);
3269 for (i = 0; i < len; i++) {
3271 @@ -386,26 +419,16 @@
3273 *port->write = buf[i];
3275 - local_irq_restore(flags);
3278 -int raw_printk(const char *fmt, ...)
3280 - static char buf[1024];
3282 - static int first = 1;
3284 - /* Force reinitialization of the port to get manual mode. */
3285 - port->started = 0;
3290 - va_start(args, fmt);
3291 - printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
3293 - console_write_direct(NULL, buf, strlen(buf));
3294 - return printed_len;
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?
3303 + local_irq_restore(flags);
3312 /* This is a dummy serial device that throws away anything written to it.
3313 * This is used when no debug output is wanted.
3315 @@ -555,7 +579,13 @@
3318 *index = port->index;
3321 +#ifdef CONFIG_ETRAX_SERIAL
3322 return port ? serial_driver : &dummy_driver;
3324 + return &dummy_driver;
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
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 $
3336 * linux/arch/cris/entry.S
3339 * Authors: Bjorn Wesen (bjornw@axis.com)
3342 + * Revision 1.38 2007/01/09 09:36:17 starvik
3343 + * Corrected kernel_execve
3345 + * Revision 1.37 2007/01/09 09:29:18 starvik
3346 + * Merge of Linux 2.6.19
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.
3354 + * Revision 1.35 2006/10/13 12:43:11 starvik
3357 + * Revision 1.34 2006/06/25 15:00:09 starvik
3358 + * Merge of Linux 2.6.17
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.
3365 + * Revision 1.32 2006/03/23 14:53:57 starvik
3366 + * Corrected signal handling.
3368 + * Revision 1.31 2006/03/22 09:56:55 starvik
3369 + * Merge of Linux 2.6.16
3371 + * Revision 1.30 2005/10/31 08:48:03 starvik
3372 + * Merge of Linux 2.6.14
3374 + * Revision 1.29 2005/08/29 07:32:17 starvik
3377 * Revision 1.28 2005/06/20 05:06:30 starvik
3378 * Remove unnecessary diff to kernel.org tree
3381 ;; deal with pending signals and notify-resume requests
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
3393 ;; special handlers for breakpoint and NMI
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
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.
3411 move.d [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog?
3412 - and.d 0x80000000, $r1
3414 + and.d (1<<30), $r1
3418 setf m ; Enable NMI again
3419 - retb ; Return from NMI
3420 + ba _Rexit ; Return the standard way
3423 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
3424 @@ -774,23 +814,10 @@
3426 push $r10 ; push orig_r10
3427 clear.d [$sp=$sp-4] ; frametype == 0, normal frame
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
3433 - btst $r2, $r0 ; check for the irq given by bit r2
3435 - move.d $r2, $r10 ; First argument to do_IRQ
3436 - move.d $sp, $r11 ; second argument to do_IRQ
3439 - addq 1, $r2 ; next vector bit
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
3444 - move.d $r0, [R_VECT_MASK_SET] ; Unblock all the IRQs
3447 + jsr do_multiple_IRQ
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.
3457 + .global kernel_execve
3459 + move.d __NR_execve, $r9
3466 @@ -1135,7 +1169,38 @@
3468 .long sys_request_key
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 */
3480 + .long sys_fchownat
3481 + .long sys_futimesat
3482 + .long sys_fstatat64 /* 300 */
3483 + .long sys_unlinkat
3484 + .long sys_renameat
3486 + .long sys_symlinkat
3487 + .long sys_readlinkat /* 305 */
3488 + .long sys_fchmodat
3489 + .long sys_faccessat
3490 + .long sys_pselect6
3492 + .long sys_unshare /* 310 */
3493 + .long sys_set_robust_list
3494 + .long sys_get_robust_list
3496 + .long sys_sync_file_range
3497 + .long sys_tee /* 315 */
3498 + .long sys_vmsplice
3499 + .long sys_move_pages
3501 + .long sys_epoll_pwait
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
3510 -/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $
3512 * linux/arch/cris/kernel/fasttimer.c
3514 * Fast timers for ETRAX100/ETRAX100LX
3515 * This may be useful in other OS than Linux so use 2 space indentation...
3517 - * $Log: fasttimer.c,v $
3518 - * Revision 1.9 2005/03/04 08:16:16 starvik
3519 - * Merge of Linux 2.6.11.
3521 - * Revision 1.8 2005/01/05 06:09:29 starvik
3522 - * cli()/sti() will be obsolete in 2.6.11.
3524 - * Revision 1.7 2005/01/03 13:35:46 starvik
3525 - * Removed obsolete stuff.
3526 - * Mark fast timer IRQ as not shared.
3528 - * Revision 1.6 2004/05/14 10:18:39 starvik
3529 - * Export fast_timer_list
3531 - * Revision 1.5 2004/05/14 07:58:01 starvik
3532 - * Merge of changes from 2.4
3534 - * Revision 1.4 2003/07/04 08:27:41 starvik
3535 - * Merge of Linux 2.5.74
3537 - * Revision 1.3 2002/12/12 08:26:32 starvik
3538 - * Don't use C-comments inside CVS comments
3540 - * Revision 1.2 2002/12/11 15:42:02 starvik
3541 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
3543 - * Revision 1.1 2002/11/18 07:58:06 starvik
3544 - * Fast timers (from Linux 2.4)
3546 - * Revision 1.5 2002/10/15 06:21:39 starvik
3547 - * Added call to init_waitqueue_head
3549 - * Revision 1.4 2002/05/28 17:47:59 johana
3550 - * Added del_fast_timer()
3552 - * Revision 1.3 2002/05/28 16:16:07 johana
3553 - * Handle empty fast_timer_list
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)
3559 - * Revision 1.1 2002/05/27 15:32:25 johana
3560 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
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
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.
3578 - * Revision 1.6 2000/12/13 14:02:08 johana
3579 - * Removed volatile for fast_timer_list
3581 - * Revision 1.5 2000/12/13 13:55:35 johana
3582 - * Added DEBUG_LOG, added som cli() and cleanup
3584 - * Revision 1.4 2000/12/05 13:48:50 johana
3585 - * Added range check when writing proc file, modified timer int handling
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
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.
3601 - * Revision 1.1 2000/10/26 15:49:16 johana
3602 - * Added fasttimer, highresolution timers.
3604 - * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
3605 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
3608 #include <linux/errno.h>
3609 @@ -136,13 +49,13 @@
3611 #define __INLINE__ inline
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;
3628 struct fast_timer *fast_timer_list = NULL;
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;
3639 #define DEBUG_LOG(string, value) \
3641 @@ -206,41 +119,25 @@
3642 int timer_delay_settings[NUM_TIMER_STATS];
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)
3648 - unsigned long sec = jiffies;
3649 - unsigned long usec = GET_JIFFIES_USEC();
3651 - usec += (sec % HZ) * (1000000 / HZ);
3654 - if (usec > 1000000)
3660 - tv->tv_usec = usec;
3661 + tv->tv_jiff = jiffies;
3662 + tv->tv_usec = GET_JIFFIES_USEC();
3665 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
3666 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
3668 - if (t0->tv_sec < t1->tv_sec)
3670 + /* Compare jiffies. Takes care of wrapping */
3671 + if (time_before(t0->tv_jiff, t1->tv_jiff))
3674 - else if (t0->tv_sec > t1->tv_sec)
3676 + else if (time_after(t0->tv_jiff, t1->tv_jiff))
3681 if (t0->tv_usec < t1->tv_usec)
3685 else if (t0->tv_usec > t1->tv_usec)
3694 "timer name: %s data: 0x%08lX already in list!\n", name, data);
3701 @@ -356,11 +253,11 @@
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)
3709 t->tv_expires.tv_usec -= 1000000;
3710 - t->tv_expires.tv_sec++;
3711 + t->tv_expires.tv_jiff += HZ;
3713 #ifdef FAST_TIMER_LOG
3714 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
3717 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
3720 local_irq_restore(flags);
3721 } /* start_one_shot_timer */
3723 @@ -444,11 +342,18 @@
3724 /* Timer 1 interrupt handler */
3727 -timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
3728 +timer1_handler(int irq, void *dev_id)
3730 struct fast_timer *t;
3731 unsigned long flags;
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.
3740 local_irq_save(flags);
3742 /* Clear timer1 irq */
3743 @@ -466,16 +371,16 @@
3744 fast_timer_running = 0;
3747 - local_irq_restore(flags);
3749 t = fast_timer_list;
3752 - struct timeval tv;
3753 + struct fasttime_t tv;
3754 + fast_timer_function_type *f;
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));
3762 if (timeval_cmp(&t->tv_expires, &tv) <= 0)
3765 fast_timers_expired++;
3767 /* Remove this timer before call, since it may reuse the timer */
3768 - local_irq_save(flags);
3771 t->prev->next = t->next;
3772 @@ -501,11 +405,21 @@
3776 - local_irq_restore(flags);
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).
3789 - t->function(t->data);
3790 + /* Run the callback function with interrupts enabled. */
3791 + local_irq_restore(flags);
3793 + local_irq_save(flags);
3797 @@ -518,16 +432,19 @@
3801 - local_irq_save(flags);
3802 if ((t = fast_timer_list) != NULL)
3804 /* Start next timer.. */
3806 - struct timeval tv;
3808 + struct fasttime_t tv;
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);
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);
3821 if (!fast_timer_running)
3826 - local_irq_restore(flags);
3830 @@ -548,9 +464,10 @@
3831 D1(printk("e! %d\n", us));
3834 - local_irq_restore(flags);
3837 + local_irq_restore(flags);
3841 D1(printk("t1 stop!\n"));
3842 @@ -575,28 +492,17 @@
3843 void schedule_usleep(unsigned long us)
3845 struct fast_timer t;
3846 -#ifdef DECLARE_WAITQUEUE
3847 wait_queue_head_t sleep_wait;
3848 init_waitqueue_head(&sleep_wait);
3850 - DECLARE_WAITQUEUE(wait, current);
3852 - struct wait_queue *sleep_wait = NULL;
3853 - struct wait_queue wait = { current, NULL };
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,
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));
3868 D1(printk("done schedule_usleep(%d)\n", us));
3869 -#ifdef DECLARE_WAITQUEUE
3874 #ifdef CONFIG_PROC_FS
3876 unsigned long flags;
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;
3885 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
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",
3904 "d: %6li us data: 0x%08lX"
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,
3916 "d: %6li us data: 0x%08lX"
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,
3928 "d: %6li us data: 0x%08lX"
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,
3939 @@ -761,15 +668,15 @@
3940 /* " func: 0x%08lX" */
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,
3953 - local_irq_disable();
3954 + local_irq_save(flags);
3955 if (t->next != nextt)
3957 printk(KERN_WARNING "timer removed!\n");
3959 static struct fast_timer tr[10];
3960 static int exp_num[10];
3962 -static struct timeval tv_exp[100];
3963 +static struct fasttime_t tv_exp[100];
3965 static void test_timeout(unsigned long data)
3971 - struct timeval tv, tv0, tv1, tv2;
3972 + struct fasttime_t tv, tv0, tv1, tv2;
3974 printk("fast_timer_test() start\n");
3975 do_gettimeofday_fast(&tv);
3978 do_gettimeofday_fast(&tv_exp[j]);
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);
3983 for (j = 0; j < 1000; j++)
3985 @@ -859,11 +766,11 @@
3986 for (j = 0; j < 100; j++)
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);
4001 do_gettimeofday_fast(&tv0);
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");
4016 printk("%-10s set: %6is %06ius exp: %6is %06ius "
4017 "data: 0x%08X func: 0x%08X\n",
4020 + t->tv_set.tv_jiff,
4022 - t->tv_expires.tv_sec,
4023 + t->tv_expires.tv_jiff,
4024 t->tv_expires.tv_usec,
4027 @@ -929,10 +836,10 @@
4029 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
4032 + tv_exp[j].tv_jiff,
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);
4038 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
4039 printk("buf5 after all done:\n");
4044 -void fast_timer_init(void)
4045 +int fast_timer_init(void)
4047 /* For some reason, request_irq() hangs when called froom time_init() */
4048 if (!fast_timer_is_init)
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
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 $
4063 * Head of the kernel - alter with care
4066 * Authors: Bjorn Wesen (bjornw@axis.com)
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
4076 + * Revision 1.12 2006/10/13 12:43:11 starvik
4079 + * Revision 1.11 2005/08/29 07:32:17 starvik
4082 * Revision 1.10 2005/06/20 05:12:54 starvik
4083 * Remove unnecessary diff to kernel.org tree
4085 @@ -595,11 +608,17 @@
4089 + ;; Select or disable serial port 2
4090 +#ifdef CONFIG_ETRAX_SERIAL_PORT2
4091 + or.d IO_STATE (R_GEN_CONFIG, ser2, select),$r0
4093 + or.d IO_STATE (R_GEN_CONFIG, ser2, disable),$r0
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]
4108 +#ifdef CONFIG_ETRAX_SERIAL_PORT2
4109 + ;; setup the serial port 2 at 115200 baud for debug purposes
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]
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]
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]
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]
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
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 $
4158 -/* C.f. ETRAX100LX Designer's Reference 20.9 */
4159 +/* C.f. ETRAX100LX Designer's Reference 19.9 */
4161 #include <linux/kernel.h>
4162 #include <linux/slab.h>
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;
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'
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;
4189 enum cris_io_interface ioif;
4190 + // name - the name of the interface
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.
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;
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;
4216 static struct if_group if_groups[6] = {
4248 @@ -94,14 +123,32 @@
4249 /* Begin Non-multiplexed interfaces */
4252 + .name = "ethernet",
4267 .ioif = if_serial_0,
4268 + .name = "serial_0",
4281 @@ -109,172 +156,385 @@
4282 /* End Non-multiplexed interfaces */
4284 .ioif = if_serial_1,
4285 + .name = "serial_1",
4295 .gpio_g_in = 0x00000000,
4296 .gpio_g_out = 0x00000000,
4300 .ioif = if_serial_2,
4301 + .name = "serial_2",
4311 .gpio_g_in = 0x000000c0,
4312 .gpio_g_out = 0x000000c0,
4316 .ioif = if_serial_3,
4317 + .name = "serial_3",
4327 .gpio_g_in = 0xc0000000,
4328 .gpio_g_out = 0xc0000000,
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,
4345 .gpio_g_in = 0x00000000,
4346 .gpio_g_out = 0x00000000,
4350 .ioif = if_sync_serial_3,
4351 + .name = "sync_serial_3",
4352 .groups = group_c | group_f,
4361 .gpio_g_in = 0xc0000000,
4362 .gpio_g_out = 0xc0000000,
4366 .ioif = if_shared_ram,
4367 + .name = "shared_ram",
4370 + .group_a = 0x7f8ff,
4377 .gpio_g_in = 0x0000ff3e,
4378 .gpio_g_out = 0x0000ff38,
4382 .ioif = if_shared_ram_w,
4383 + .name = "shared_ram_w",
4384 .groups = group_a | group_d,
4386 + .group_a = 0x7f8ff,
4393 .gpio_g_in = 0x00ffff3e,
4394 .gpio_g_out = 0x00ffff38,
4402 + .group_a = 0x7fbff,
4409 .gpio_g_in = 0x0000ff3e,
4410 .gpio_g_out = 0x0000ff3e,
4421 + .group_d = 0x7feff,
4425 .gpio_g_in = 0x3eff0000,
4426 .gpio_g_out = 0x3eff0000,
4432 .groups = group_a | group_d,
4434 + .group_a = 0x7fbff,
4441 .gpio_g_in = 0x00ffff3e,
4442 .gpio_g_out = 0x00ffff3e,
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,
4452 + .group_a = 0x7ffff,
4459 .gpio_g_in = 0x0000ffff,
4460 .gpio_g_out = 0x0000ffff,
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,
4473 + .group_d = 0x7ffff,
4477 .gpio_g_in = 0xffff0000,
4478 .gpio_g_out = 0xffff0000,
4484 .groups = group_a | group_b | group_d | group_f,
4486 + .group_a = 0x7ffff,
4489 + .group_d = 0x601ff,
4493 .gpio_g_in = 0x01ffffff,
4494 .gpio_g_out = 0x07ffffff,
4500 .groups = group_a | group_b | group_c | group_d,
4502 + .group_a = 0x7ffff,
4505 + .group_d = 0x7cfff,
4509 .gpio_g_in = 0xf9ffffff,
4510 .gpio_g_out = 0xffffffff,
4515 - .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4517 + .groups = group_f,
4526 .gpio_g_in = 0x00000000,
4527 .gpio_g_out = 0x00000000,
4532 - .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4534 + .groups = group_f,
4543 .gpio_g_in = 0x00000000,
4544 .gpio_g_out = 0x00000000,
4550 .groups = group_e | group_f,
4559 .gpio_g_in = 0x00000000,
4560 .gpio_g_out = 0x00000000,
4567 - .gpio_g_in = 0x0e000000,
4568 - .gpio_g_out = 0x3c000000,
4574 + .group_e = 0x33e00,
4577 + .gpio_g_in = 0x3e000000,
4578 + .gpio_g_out = 0x0c000000,
4583 .ioif = if_gpio_grp_a,
4594 .gpio_g_in = 0x0000ff3f,
4595 .gpio_g_out = 0x0000ff3f,
4599 .ioif = if_gpio_grp_b,
4610 .gpio_g_in = 0x000000c0,
4611 .gpio_g_out = 0x000000c0,
4615 .ioif = if_gpio_grp_c,
4626 .gpio_g_in = 0xc0000000,
4627 .gpio_g_out = 0xc0000000,
4631 .ioif = if_gpio_grp_d,
4642 .gpio_g_in = 0x3fff0000,
4643 .gpio_g_out = 0x3fff0000,
4647 .ioif = if_gpio_grp_e,
4658 .gpio_g_in = 0x00000000,
4659 .gpio_g_out = 0x00000000,
4663 .ioif = if_gpio_grp_f,
4674 .gpio_g_in = 0x00000000,
4675 .gpio_g_out = 0x00000000,
4677 @@ -284,11 +544,13 @@
4679 static struct watcher *watchers = NULL;
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;
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];
4692 struct watcher *w = watchers;
4694 DBG(printk("io_interface_mux: notifying watchers\n"));
4698 w->notify((const unsigned int)gpio_in_pins,
4699 (const unsigned int)gpio_out_pins,
4700 @@ -354,37 +616,48 @@
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,
4708 interfaces[ioif].owner);
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))) {
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);
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);
4735 - local_irq_restore(flags);
4738 + unsigned int if_group_use = 0;
4740 + switch(grp->group) {
4742 + if_group_use = interfaces[ioif].group_a;
4745 + if_group_use = interfaces[ioif].group_b;
4748 + if_group_use = interfaces[ioif].group_c;
4751 + if_group_use = interfaces[ioif].group_d;
4754 + if_group_use = interfaces[ioif].group_e;
4757 + if_group_use = interfaces[ioif].group_f;
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);
4769 group_set = clear_group_from_set(group_set, grp);
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",
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);
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))) {
4788 - grp->owner = ioif;
4789 - group_set = clear_group_from_set(group_set, grp);
4792 + /* Check which registers need to be reconfigured. */
4793 gens = genconfig_shadow;
4794 gens_ii = gen_config_ii_shadow;
4800 @@ -494,9 +761,43 @@
4804 - panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
4807 + local_irq_restore(flags);
4808 + printk(KERN_INFO "cris_request_io_interface: Bad interface %u submitted for %s\n",
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;
4819 + switch(grp->group) {
4821 + if_group_use = interfaces[ioif].group_a;
4824 + if_group_use = interfaces[ioif].group_b;
4827 + if_group_use = interfaces[ioif].group_c;
4830 + if_group_use = interfaces[ioif].group_d;
4833 + if_group_use = interfaces[ioif].group_e;
4836 + if_group_use = interfaces[ioif].group_f;
4841 + grp->used |= if_group_use;
4843 + group_set = clear_group_from_set(group_set, grp);
4846 interfaces[ioif].used = 1;
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));
4853 local_irq_restore(flags);
4856 @@ -559,43 +860,36 @@
4858 group_set = interfaces[ioif].groups;
4859 while (NULL != (grp = get_group(group_set))) {
4860 - if (grp->group == group_f) {
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;
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;
4878 - if ((grp->owner == if_scsi8_0) &&
4879 - interfaces[if_scsi8_1].used) {
4880 - grp->owner = if_scsi8_1;
4885 - if ((grp->owner == if_scsi8_1) &&
4886 - interfaces[if_scsi8_0].used) {
4887 - grp->owner = if_scsi8_0;
4896 + unsigned int if_group_use = 0;
4898 + switch(grp->group) {
4900 + if_group_use = interfaces[ioif].group_a;
4903 + if_group_use = interfaces[ioif].group_b;
4906 + if_group_use = interfaces[ioif].group_c;
4909 + if_group_use = interfaces[ioif].group_d;
4912 + if_group_use = interfaces[ioif].group_e;
4915 + if_group_use = interfaces[ioif].group_f;
4921 + if ((grp->used & if_group_use) != if_group_use) {
4924 + grp->used = grp->used & ~if_group_use;
4926 group_set = clear_group_from_set(group_set, grp);
4928 interfaces[ioif].used = 0;
4929 @@ -784,7 +1078,7 @@
4931 for (i = start_bit; i <= stop_bit; i++) {
4932 owners[i] = if_unclaimed;
4935 local_irq_restore(flags);
4938 @@ -821,7 +1115,7 @@
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))
4947 @@ -870,7 +1164,7 @@
4949 module_init(cris_io_interface_init);
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
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 $
4963 * linux/arch/cris/kernel/irq.c
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>
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 */
4990 +extern void do_IRQ(int irq, struct pt_regs * regs);
4992 +/* Handle multiple IRQs */
4993 +void do_multiple_IRQ(struct pt_regs* regs)
4998 + unsigned ethmask = 0;
5000 + /* Get interrupts to mask and handle */
5001 + mask = masked = *R_VECT_MASK_RD;
5003 + /* Never mask timer IRQ */
5004 + mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));
5007 + * If either ethernet interrupt (rx or tx) is active then block
5008 + * the other one too. Unblock afterwards also.
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));
5018 + *R_VECT_MASK_CLR = (mask | ethmask);
5020 + /* An extra irq_enter here to prevent softIRQs to run after
5021 + * each do_IRQ. This will decrease the interrupt latency.
5025 + /* Handle all IRQs */
5026 + for (bit = 2; bit < 32; bit++) {
5027 + if (masked & (1 << bit)) {
5028 + do_IRQ(bit, regs);
5032 + /* This irq_exit() will trigger the soft IRQs. */
5035 + /* Unblock the IRQs again */
5036 + *R_VECT_MASK_SET = (masked | ethmask);
5039 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
5040 setting the irq vector table.
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
5046 *! Jul 21 1999 Bjorn Wesen eLinux port
5049 +*! Revision 1.7 2006/03/22 09:56:55 starvik
5050 +*! Merge of Linux 2.6.16
5053 *! Revision 1.6 2005/01/14 10:12:17 starvik
5054 *! KGDB on separate port.
5055 *! Console fixes from 2.4.
5058 *!---------------------------------------------------------------------------
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 $
5063 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
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
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 $
5072 * linux/arch/cris/kernel/process.c
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
5078 ptrace_disable(struct task_struct *child)
5080 /* Todo - pending singlesteps? */
5081 + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
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
5092 * linux/arch/cris/arch-v10/kernel/setup.c
5095 #include <linux/seq_file.h>
5096 #include <linux/proc_fs.h>
5097 #include <linux/delay.h>
5098 +#include <linux/param.h>
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
5107 #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
5109 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
5110 +void do_signal(int canrestart, struct pt_regs *regs);
5113 * Atomically swap in the new signal mask, and wait for a signal. Define
5115 sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
5116 long srp, struct pt_regs *regs)
5121 spin_lock_irq(¤t->sighand->siglock);
5122 - saveset = current->blocked;
5123 - siginitset(¤t->blocked, mask);
5124 - recalc_sigpending();
5125 - spin_unlock_irq(¤t->sighand->siglock);
5127 - regs->r10 = -EINTR;
5129 - current->state = TASK_INTERRUPTIBLE;
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;
5143 -/* Define dummy arguments to be able to reach the regs argument. (Note that
5144 - * this arrangement relies on size_t occupying one register.)
5147 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
5148 - long mof, long srp, struct pt_regs *regs)
5150 - sigset_t saveset, newset;
5152 - /* XXX: Don't preclude handling different sized sigset_t's. */
5153 - if (sigsetsize != sizeof(sigset_t))
5156 - if (copy_from_user(&newset, unewset, sizeof(newset)))
5158 - sigdelsetmask(&newset, ~_BLOCKABLE);
5160 - spin_lock_irq(¤t->sighand->siglock);
5161 - saveset = current->blocked;
5162 - current->blocked = newset;
5163 + current->saved_sigmask = current->blocked;
5164 + siginitset(¤t->blocked, mask);
5165 recalc_sigpending();
5166 spin_unlock_irq(¤t->sighand->siglock);
5168 - regs->r10 = -EINTR;
5170 - current->state = TASK_INTERRUPTIBLE;
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;
5182 + current->state = TASK_INTERRUPTIBLE;
5184 + set_thread_flag(TIF_RESTORE_SIGMASK);
5185 + return -ERESTARTNOHAND;
5190 * user-mode trampoline.
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)
5198 struct sigframe __user *frame;
5199 unsigned long return_ip;
5200 @@ -402,14 +350,15 @@
5202 wrusp((unsigned long)frame);
5208 force_sigsegv(sig, current);
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)
5217 struct rt_sigframe __user *frame;
5218 unsigned long return_ip;
5219 @@ -466,21 +415,24 @@
5221 wrusp((unsigned long)frame);
5227 force_sigsegv(sig, current);
5232 * OK, we're invoking a handler
5237 handle_signal(int canrestart, unsigned long sig,
5238 siginfo_t *info, struct k_sigaction *ka,
5239 sigset_t *oldset, struct pt_regs * regs)
5243 /* Are we from a system call? */
5245 /* If so, check system call restarting.. */
5246 @@ -510,19 +462,20 @@
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);
5253 - setup_frame(sig, ka, oldset, regs);
5254 + ret = setup_frame(sig, ka, oldset, regs);
5256 - if (ka->sa.sa_flags & SA_ONESHOT)
5257 - ka->sa.sa_handler = SIG_DFL;
5259 + spin_lock_irq(¤t->sighand->siglock);
5260 + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
5261 + if (!(ka->sa.sa_flags & SA_NODEFER))
5262 + sigaddset(¤t->blocked,sig);
5263 + recalc_sigpending();
5264 + spin_unlock_irq(¤t->sighand->siglock);
5267 - spin_lock_irq(¤t->sighand->siglock);
5268 - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
5269 - if (!(ka->sa.sa_flags & SA_NODEFER))
5270 - sigaddset(¤t->blocked,sig);
5271 - recalc_sigpending();
5272 - spin_unlock_irq(¤t->sighand->siglock);
5277 @@ -537,12 +490,13 @@
5281 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
5282 +void do_signal(int canrestart, struct pt_regs *regs)
5286 struct k_sigaction ka;
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 @@
5296 if (!user_mode(regs))
5301 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
5302 + oldset = ¤t->saved_sigmask;
5304 oldset = ¤t->blocked;
5306 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
5308 /* Whee! Actually deliver the signal. */
5309 - handle_signal(canrestart, signr, &info, &ka, oldset, regs);
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);
5323 /* Did we come from a system call? */
5324 @@ -575,5 +539,11 @@
5330 + /* if there's no signal to deliver, we just put the saved sigmask
5332 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
5333 + clear_thread_flag(TIF_RESTORE_SIGMASK);
5334 + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
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
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 $
5344 * linux/arch/cris/arch-v10/kernel/time.c
5348 #include <asm/delay.h>
5349 #include <asm/rtc.h>
5350 +#include <asm/irq_regs.h>
5352 /* define this if you need to use print_timestamp */
5353 /* it will make jiffies at 96 hz instead of 100 hz though */
5355 extern void cris_do_profile(struct pt_regs *regs);
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)
5361 + struct pt_regs* regs = get_irq_regs();
5362 /* acknowledge the timer irq */
5364 #ifdef USE_CASCADE_TIMERS
5365 @@ -222,9 +224,11 @@
5368 /* reset watchdog otherwise it resets us! */
5372 + /* Update statistics. */
5373 + update_process_times(user_mode(regs));
5375 /* call the real timer interrupt handler */
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
5382 -/* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $
5384 + * Helper functions for trap handlers
5386 - * linux/arch/cris/arch-v10/traps.c
5387 + * Copyright (C) 2000-2006, Axis Communications AB.
5389 - * Heler functions for trap handlers
5391 - * Copyright (C) 2000-2002 Axis Communications AB
5393 - * Authors: Bjorn Wesen
5394 - * Hans-Peter Nilsson
5395 + * Authors: Bjorn Wesen
5396 + * Hans-Peter Nilsson
5400 @@ -15,124 +12,118 @@
5401 #include <asm/uaccess.h>
5402 #include <asm/arch/sv_addr_ag.h>
5404 -extern int raw_printk(const char *fmt, ...);
5407 -show_registers(struct pt_regs * regs)
5409 +show_registers(struct pt_regs *regs)
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
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.
5422 unsigned long usp = rdusp();
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);
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",
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",
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",
5445 + printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n",
5446 + regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs);
5448 + printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
5450 + printk("Process %s (pid: %d, stackpage=%08lx)\n",
5451 current->comm, current->pid, (unsigned long)current);
5454 - * When in-kernel, we also print out the stack and code at the
5455 - * time of the fault..
5457 - if (! user_mode(regs)) {
5459 + * When in-kernel, we also print out the stack and code at the
5460 + * time of the fault..
5462 + if (!user_mode(regs)) {
5465 - show_stack(NULL, (unsigned long*)usp);
5466 + show_stack(NULL, (unsigned long *)usp);
5468 - /* Dump kernel stack if the previous dump wasn't one. */
5470 + * If the previous stack-dump wasn't a kernel one, dump the
5471 + * kernel stack now.
5474 - show_stack (NULL, NULL);
5475 + show_stack(NULL, NULL);
5477 - raw_printk("\nCode: ");
5478 - if(regs->irp < PAGE_OFFSET)
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++)
5492 - if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
5494 - raw_printk(" Bad IP value.");
5497 + printk("\nCode: ");
5499 + if (regs->irp < PAGE_OFFSET)
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.
5511 + for (i = -12; i < 12; i++) {
5514 + if (__get_user(c, &((unsigned char *)regs->irp)[i])) {
5516 + printk(" Bad IP value.");
5521 - raw_printk("(%02x) ", c);
5522 + printk("(%02x) ", c);
5524 - raw_printk("%02x ", c);
5528 + printk("%02x ", c);
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.
5540 -extern void reset_watchdog(void);
5541 -extern void stop_watchdog(void);
5545 -watchdog_bite_hook(struct pt_regs *regs)
5546 +arch_enable_nmi(void)
5548 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5549 - local_irq_disable();
5551 - show_registers(regs);
5552 - while(1) /* nothing */;
5554 - show_registers(regs);
5556 + asm volatile ("setf m");
5559 -/* This is normally the 'Oops' routine */
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)
5565 - if(user_mode(regs))
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.
5576 - raw_printk("%s: %04lx\n", str, err & 0xffff);
5578 - show_registers(regs);
5580 + nmi_handler(regs);
5582 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
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));
5592 -void arch_enable_nmi(void)
5593 +#ifdef CONFIG_DEBUG_BUGVERBOSE
5595 +handle_BUG(struct pt_regs *regs)
5597 - asm volatile("setf m");
5598 + struct bug_frame f;
5600 + unsigned long irp = regs->irp;
5602 + if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f))
5604 + if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
5606 + if (__get_user(c, f.filename))
5607 + f.filename = "<bad filename>";
5609 + printk("kernel BUG at %s:%d!\n", f.filename, f.line);
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
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
5625 - ax ; do it again, since we might have generated a carry
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
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
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
5654 - ax ; do it again, since we might have generated a carry
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
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
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 $
5677 * DRAM/SDRAM initialization - alter with care
5678 * This file is intended to be included from other assembler files
5680 * Authors: Mikael Starvik (starvik@axis.com)
5682 * $Log: dram_init.S,v $
5683 + * Revision 1.5 2006/10/13 12:43:11 starvik
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
5693 /* leave it to the MM system fault handler */
5695 do_page_fault(address, regs, 0, writeac);
5698 do_page_fault(address, regs, 1, we);
5700 /* Reload TLB with new entry to avoid an extra miss exception.
5702 local_irq_disable();
5703 pmd = (pmd_t *)(pgd + pgd_index(address));
5707 pte = *pte_offset_kernel(pmd, address);
5708 if (!pte_present(pte))
5711 *R_TLB_SELECT = select;
5713 *R_TLB_LO = pte_val(pte);
5715 local_irq_restore(flags);
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)
5724 - /* make sure we have a context */
5725 + if (prev != next) {
5726 + /* make sure we have a context */
5727 + get_mmu_context(next);
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
5736 - get_mmu_context(next);
5737 + per_cpu(current_pgd, smp_processor_id()) = next->pgd;
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
5746 - per_cpu(current_pgd, smp_processor_id()) = next->pgd;
5748 - /* switch context in the MMU */
5749 + /* switch context in the MMU */
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));
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);
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
5765 +source drivers/cpufreq/Kconfig
5767 config ETRAX_DRAM_VIRTUAL_BASE
5769 depends on ETRAX_ARCH_V32
5773 - string "First green LED bit"
5775 + prompt "Nbr of Ethernet LED groups"
5776 depends on ETRAX_ARCH_V32
5777 + default ETRAX_NBR_LED_GRP_ONE
5779 + Select how many Ethernet LED groups that can be used. Usually one per Ethernet
5780 + interface is a good choice.
5782 +config ETRAX_NBR_LED_GRP_ZERO
5783 + bool "Use zero LED groups"
5785 + Select this if you do not want any Ethernet LEDs.
5787 +config ETRAX_NBR_LED_GRP_ONE
5788 + bool "Use one LED group"
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.
5794 +config ETRAX_NBR_LED_GRP_TWO
5795 + bool "Use two LED groups"
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
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)
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.
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)
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.
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
5829 + Bit to use for the green LED in Ethernet LED group 1.
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
5836 + Bit to use for the red LED in Ethernet LED group 1.
5839 string "Second green LED bit"
5840 @@ -294,3 +337,22 @@
5842 Configures the initial data for the general port E bits. Most
5843 products should use 00000 here.
5845 +config ETRAX_DEF_GIO_PV_OE
5847 + depends on ETRAX_VIRTUAL_GPIO
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.
5856 +config ETRAX_DEF_GIO_PV_OUT
5858 + depends on ETRAX_VIRTUAL_GPIO
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
5868 # arch/cris/arch-v32/boot/Makefile
5870 -target = $(target_boot_dir)
5871 -src = $(src_boot_dir)
5873 -zImage: compressed/vmlinuz
5874 +OBJCOPY = objcopy-cris
5875 +OBJCOPYFLAGS = -O binary -R .note -R .comment
5877 -compressed/vmlinuz: $(objtree)/vmlinux
5878 - @$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz
5879 +subdir- := compressed rescue
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'
5889 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
5890 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@
5891 + $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
5893 +$(obj)/zImage: $(obj)/compressed/vmlinux
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
5901 -# lx25/arch/cris/arch-v32/boot/compressed/Makefile
5902 +# arch/cris/arch-v32/boot/compressed/Makefile
5904 -# create a compressed vmlinux image from the original vmlinux files and romfs
5907 -target = $(target_compressed_dir)
5908 -src = $(src_compressed_dir)
5910 CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include
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
5920 -# files to compress
5921 -SYSTEM = $(objtree)/vmlinux.bin
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
5929 -$(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
5930 - cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz
5932 - cp $(objtree)/vmlinuz $(src)
5933 +quiet_cmd_image = BUILD $@
5934 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
5936 -$(target)/head.o: $(src)/head.S
5937 - $(CC) -D__ASSEMBLY__ -c $< -o $@
5938 +targets := vmlinux piggy.gz decompress.o decompress.bin
5940 -# gzip the kernel image
5941 +$(obj)/decompress.o: $(OBJECTS) FORCE
5942 + $(call if_changed,ld)
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)
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)
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
5960 This can be slightly confusing because it's a process with many steps.
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
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.
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.
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
5980 /*#OUTPUT_FORMAT(elf32-us-cris) */
5981 OUTPUT_ARCH (crisv32)
5986 dram : ORIGIN = 0x40700000,
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
5992 * Code that sets up the DRAM registers, calls the
5993 * decompressor to unpack the piggybacked kernel, and jumps.
5995 - * Copyright (C) 1999 - 2003, Axis Communications AB
5996 + * Copyright (C) 1999 - 2006, Axis Communications AB
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>
6005 #define RAM_INIT_MAGIC 0x56902387
6006 #define COMMAND_LINE_MAGIC 0x87109563
6015 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
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
6029 - ;; Before this code the tools add a partitiontable so the PC
6030 - ;; has an offset from the linked address.
6032 - lapcq ., $r13 ; get PC
6033 - add.d first_copy_complete-offset1, $r13
6035 -#include "../../lib/nand_init.S"
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
6044 #include "../../lib/dram_init.S"
6048 - lapcq ., $r13 ; get PC
6049 - add.d second_copy_complete-dram_init_finished, $r13
6051 - move.d REG_ADDR(config, regi_config, r_bootsel), $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
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
6064 -second_copy_complete:
6066 - ;; Initiate the PA port.
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
6073 move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r1
6076 + move.d CONFIG_ETRAX_DEF_GIO_PB_OUT, $r0
6077 + move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r1
6080 + move.d CONFIG_ETRAX_DEF_GIO_PB_OE, $r0
6081 + move.d REG_ADDR(gio, regi_gio, rw_pb_oe), $r1
6084 + move.d CONFIG_ETRAX_DEF_GIO_PC_OUT, $r0
6085 + move.d REG_ADDR(gio, regi_gio, rw_pc_dout), $r1
6088 + move.d CONFIG_ETRAX_DEF_GIO_PC_OE, $r0
6089 + move.d REG_ADDR(gio, regi_gio, rw_pc_oe), $r1
6092 + move.d CONFIG_ETRAX_DEF_GIO_PD_OUT, $r0
6093 + move.d REG_ADDR(gio, regi_gio, rw_pd_dout), $r1
6096 + move.d CONFIG_ETRAX_DEF_GIO_PD_OE, $r0
6097 + move.d REG_ADDR(gio, regi_gio, rw_pd_oe), $r1
6100 + move.d CONFIG_ETRAX_DEF_GIO_PE_OUT, $r0
6101 + move.d REG_ADDR(gio, regi_gio, rw_pe_dout), $r1
6104 + move.d CONFIG_ETRAX_DEF_GIO_PE_OE, $r0
6105 + move.d REG_ADDR(gio, regi_gio, rw_pe_oe), $r1
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.
6113 move.d 0x40800000, $sp
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.
6127 - move.d REG_ADDR(config, regi_config, r_bootsel), $r0
6129 - and.d REG_MASK(config, r_bootsel, boot_mode), $r0
6130 - cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
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'
6140 sub.d hereami, $r5 ; r5 = flash address of '_edata'
6141 move.d hereami, $r1 ; destination
6145 - lapcq ., $r5 ; get PC
6146 - and.d 0x00ffffff, $r5 ; strip any non-cache bit
6148 - or.d 0x40200000, $r6
6149 - move.d $r6, $r0 ; save for later - flash address of 'herami'
6151 - sub.d hereami2, $r5 ; r5 = flash address of '_edata'
6152 - add.d 0x40200000, $r5
6153 - move.d hereami2, $r1 ; destination
6155 - ;; Copy text+data to DRAM
6157 + ;; Copy text+data to DRAM
6159 move.d _edata, $r2 ; end destination
6160 -1: move.w [$r0+], $r3
6161 - move.w $r3, [$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
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
6173 ;; Clear the decompressors BSS (between _edata and _end)
6179 @@ -144,40 +124,47 @@
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]
6188 + move.d _cmd_line_magic, $r0
6189 + move.d $r10, [$r0]
6190 + move.d _cmd_line_addr, $r0
6191 + move.d $r11, [$r0]
6193 + ;; Save boot source indicator
6194 + move.d _boot_source, $r0
6195 + move.d $r12, [$r0]
6197 ;; Do the decompression and save compressed size in _inptr
6199 jsr decompress_kernel
6202 + ;; Restore boot source indicator
6203 + move.d _boot_source, $r12
6204 + move.d [$r12], $r12
6206 ;; Restore command line magic and address.
6207 move.d _cmd_line_magic, $r10
6209 move.d _cmd_line_addr, $r11
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
6218 add.d [$r0], $r9 ; size of compressed kernel
6219 - cmp.d 0x40200000, $r9
6222 - sub.d 0x40200000, $r9
6226 + cmp.d 0x40000000, $r9 ; image in DRAM ?
6227 + blo enter_kernel ; no, must be [NOR] flash, jump
6229 + and.d 0x001fffff, $r9 ; assume compressed kernel was < 2M
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
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
6260 - * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $
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 $
6265 + * This is a collection of several routines from gzip-1.0.3
6266 * adapted for Linux.
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
6275 /* where the piggybacked kernel image expects itself to live.
6278 #define KERNEL_LOAD_ADR 0x40004000
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>
6290 #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
6291 #define RESERVED 0xC0 /* bit 6,7: reserved */
6293 -#define get_byte() inbuf[inptr++]
6295 +#define get_byte() inbuf[inptr++]
6297 /* Diagnostic functions */
6299 # define Assert(cond,msg) {if(!(cond)) error(msg);}
6301 static long bytes_out = 0;
6302 static uch *output_data;
6303 static unsigned long output_ptr = 0;
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 **);
6313 static void puts(const char *);
6315 /* the "heap" is put directly after the BSS ends, at end */
6319 static long free_mem_ptr = (long)&_end;
6322 #include "../../../../../lib/inflate.c"
6324 static void *malloc(int size)
6326 rs = REG_RD(ser, regi_ser, rs_stat_din);
6328 while (!rs.tr_rdy);/* Wait for tranceiver. */
6331 REG_WR(ser, regi_ser, rw_dout, dout);
6335 ulg c = crc; /* temporary variable */
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);
6353 - puts("\n\n -- System halted\n");
6354 + puts("\r\n\n -- System halted\n");
6356 while(1); /* Halt */
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;
6364 /* Turn off XOFF. */
6365 xoff = REG_RD(ser, regi_ser, rw_xoff);
6369 xoff.automatic = regk_ser_no;
6372 REG_WR(ser, regi_ser, rw_xoff, xoff);
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);
6381 tr_ctrl.stop_bits = 1; /* 2 stop bits. */
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
6387 + tr_ctrl.en = 1; /* enable transmitter */
6388 + rec_ctrl.en = 1; /* enabler receiver */
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.
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;
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 @@
6410 + reg_pinmux_rw_hwprot hwprot;
6412 /* input_data is set in head.S */
6416 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
6417 #ifdef CONFIG_ETRAX_DEBUG_PORT0
6418 serial_setup(regi_ser0);
6420 #ifdef CONFIG_ETRAX_DEBUG_PORT1
6421 + hwprot.ser1 = regk_pinmux_yes;
6422 serial_setup(regi_ser1);
6424 #ifdef CONFIG_ETRAX_DEBUG_PORT2
6425 + hwprot.ser2 = regk_pinmux_yes;
6426 serial_setup(regi_ser2);
6428 #ifdef CONFIG_ETRAX_DEBUG_PORT3
6429 + hwprot.ser3 = regk_pinmux_yes;
6430 serial_setup(regi_ser3);
6432 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
6434 setup_normal_output_buffer();
6436 @@ -307,11 +315,11 @@
6437 __asm__ volatile ("move $vr,%0" : "=rm" (revision));
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");
6445 - puts("Uncompressing Linux...\n");
6446 + puts("Uncompressing Linux...\r\n");
6448 - puts("Done. Now booting the kernel.\n");
6449 + puts("Done. Now booting the kernel.\r\n");
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
6456 -# Makefile for rescue code
6457 +# Makefile for rescue (bootstrap) code
6459 -target = $(target_rescue_dir)
6460 -src = $(src_rescue_dir)
6462 CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
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
6471 -all: $(target)/rescue.bin
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)
6482 - mkdir -p $(target)
6484 -$(target)/head.o: $(src)/head.S
6485 - $(CC) -D__ASSEMBLY__ -c $< -o $*.o
6488 - rm -f $(target)/*.o $(target)/*.bin
6495 +obj-y = head.o bootload.o crisv32_nand.o nand_base.o nand_ids.o nand_ecc.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
6502 +targets := rescue.o rescue.bin
6504 +quiet_cmd_ldlibgcc = LD $@
6505 +cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
6507 +$(obj)/rescue.o: $(OBJECTS) FORCE
6508 + $(call if_changed,ldlibgcc)
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
6519 + * Simple boot loader for NAND chips on Etrax FS
6521 + * $Id: bootload.c,v 1.8 2006/11/28 10:05:39 ricardw Exp $
6525 +#include <linux/types.h>
6526 +#include <linux/delay.h>
6531 +#include <asm/arch/hwregs/reg_rdwr.h>
6532 +#include <asm/arch/hwregs/reg_map.h>
6533 +#include <asm/arch/hwregs/pinmux_defs.h>
6537 +#define BOOT_ADDR (CONFIG_ETRAX_PTABLE_SECTOR + 0x40200000)
6539 +/* bits for nand_rw() `cmd'; or together as needed */
6541 +#define NANDRW_READ 0x01
6542 +#define NANDRW_WRITE 0x00
6543 +#define NANDRW_JFFS2 0x02
6544 +#define NANDRW_JFFS2_SKIP 0x04
6546 +#define ROUND_DOWN(value, boundary) ((value) & (~((boundary)-1)))
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\
6558 +extern struct mtd_info *crisv32_nand_flash_probe(void);
6560 +extern int _end, _bss, _edata;
6563 + * NAND read/write from U-Boot 1.4.4
6564 + * Modified for newer mtd and use of mtd interface instead of nand directly.
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
6573 +nand_rw (struct mtd_info* mtd, int cmd,
6574 + size_t start, size_t len,
6575 + size_t *retlen, u_char * buf)
6577 + int ret = 0, n, total = 0;
6579 + /* eblk (once set) is the start of the erase block containing the
6580 + * data being processed.
6582 + size_t eblk = ~0; /* force mismatch on first pass */
6583 + size_t erasesize = mtd->erasesize;
6586 + if ((start & (-erasesize)) != eblk) {
6587 + /* have crossed into new erase block, deal with
6588 + * it if it is marked bad.
6590 + eblk = start & (-erasesize); /* start of block */
6592 + puts("New block ");
6596 + if (mtd->block_isbad(mtd, eblk)) {
6597 + if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
6599 + start - eblk < erasesize) {
6606 + } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
6607 + start += erasesize;
6609 + } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
6610 + /* skip bad block */
6611 + start += erasesize;
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");
6626 + buf = (void *) 0x38008000; /* to fixed address, for testing */
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,
6635 + ret = mtd->write_ecc(mtd, start,
6636 + min(len, eblk + erasesize - start),
6637 + (size_t *)&n, (u_char*)buf,
6661 + struct mtd_info *mtd;
6665 + __asm__ volatile ("move $vr,%0" : "=rm" (revision));
6666 + if (revision < 32)
6668 + puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
6672 + puts("\r\n\nETRAX FS NAND boot loader\r\n");
6673 + puts("=========================\r\n");
6674 + puts("Rev 1, " __DATE__ " " __TIME__ "\r\n");
6676 + puts("CPU revision: ");
6680 + puts("Bootloader main at ") ;
6681 + putx((int) bootload);
6684 + puts("Data end: ");
6685 + putx((long) &_edata);
6689 + putx((long) &_bss);
6693 + putx((long) &_end);
6696 +#if 0 /* loop calibration */
6698 + puts ("10000 loops...");
6699 + for (i = 0; i < 10000; i++)
6704 + puts("Identifying nand chip...\r\n");
6705 + mtd = crisv32_nand_flash_probe();
6706 + puts("Done.\r\n");
6709 + puts("Chip identified. ");
6710 +#if 0 /* print chip parameters */
6714 + puts("\r\ntype: ");
6716 + puts("\r\nflags: ");
6718 + puts("\r\nsize: ");
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);
6733 + puts("Bad blocks:\r\n");
6736 + for (i = 0; i < mtd->size; i += mtd->erasesize) {
6737 + if (mtd->block_isbad(mtd, i)) {
6743 +#if 0 /* print oob parameters */
6744 + puts("Oob info:\r\n");
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]);
6757 + puts("Bootload in progress...");
6759 + res = nand_rw(mtd,
6760 + NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
6761 + CONFIG_ETRAX_PTABLE_SECTOR,
6762 + 0x200000, /* 2 megs */
6764 + (void *) BOOT_ADDR);
6766 + puts("complete, status ");
6768 + puts(", loaded ");
6770 + puts(" bytes\r\n");
6772 + puts("Data in DRAM:\r\n");
6773 + putx(* (int *) (BOOT_ADDR + 0));
6775 + putx(* (int *) (BOOT_ADDR + 4));
6777 + putx(* (int *) (BOOT_ADDR + 8));
6782 + error("Corrupt data in NAND flash.");
6785 + puts("Booting...\r\n");
6789 + error("No NAND flash chip found to boot from.");
6792 + ; /* hang around until hell freezes over */
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
6799 + * Taken from arch/cris/arch-v32/drivers/nandflash.c
6800 + * and modified to use for boot loader.
6802 + * Copyright (c) 2004
6804 + * Derived from drivers/mtd/nand/spia.c
6805 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
6807 + * $Id: crisv32_nand.c,v 1.2 2006/11/21 14:40:02 ricardw Exp $
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.
6819 +#include <linux/mtd/partitions.h>
6823 +#include <asm/arch/memmap.h>
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>
6840 +#define NAND_RD_ADDR 0x90000000 /* read address */
6841 +#define NAND_WR_ADDR 0x94000000 /* write address */
6843 +static struct mtd_info *crisv32_mtd = NULL;
6846 + * hardware specific access to control-lines
6848 +static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
6850 + unsigned long flags;
6851 + reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
6854 + case NAND_CTL_SETCLE:
6855 + dout.data |= (1<<CLE_BIT);
6857 + case NAND_CTL_CLRCLE:
6858 + dout.data &= ~(1<<CLE_BIT);
6860 + case NAND_CTL_SETALE:
6861 + dout.data |= (1<<ALE_BIT);
6863 + case NAND_CTL_CLRALE:
6864 + dout.data &= ~(1<<ALE_BIT);
6866 + case NAND_CTL_SETNCE:
6867 + dout.data &= ~(1<<CE_BIT);
6869 + case NAND_CTL_CLRNCE:
6870 + dout.data |= (1<<CE_BIT);
6873 + REG_WR(gio, regi_gio, rw_pa_dout, dout);
6875 + /* read from gpio reg to flush pipeline.
6876 + * doesn't seem to be necessary.
6878 + (void) REG_RD(gio, regi_gio, rw_pa_dout); /* gpio sync */
6883 + * read device ready pin
6885 +int crisv32_device_ready(struct mtd_info *mtd)
6887 + reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din);
6888 + return ((din.data & (1 << BY_BIT)) >> BY_BIT);
6892 + * Main initialization routine
6894 +struct mtd_info* crisv32_nand_flash_probe (void)
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;
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");
6909 + /* Get pointer to private data */
6910 + this = (struct nand_chip *) (&crisv32_mtd[1]);
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);
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);
6922 + /* Initialize structures */
6923 + memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info));
6924 + memset((char *) this, 0, sizeof(struct nand_chip));
6926 + /* Link the private data with the MTD structure */
6927 + crisv32_mtd->priv = this;
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;
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;
6942 + /* don't scan for BBT */
6943 + this->options = NAND_SKIP_BBTSCAN;
6945 + /* Scan to find existance of the device */
6946 + if (nand_scan (crisv32_mtd, 1)) {
6948 + puts ("nand_scan failed\r\n");
6949 + free (crisv32_mtd);
6953 + return crisv32_mtd;
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
6959 -/* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $
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 $
6965 + * Simple boot loader which can also handle NAND chips.
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>
6973 +#define RAM_INIT_MAGIC 0x56902387
6974 +#define NAND_BOOT_MAGIC 0x9A9DB001
6976 +;; Debugging. Normally all these are set to 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)
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>
6991 +#include <asm/arch/hwregs/asm/ser_defs_asm.h>
6992 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
6996 +#if (SERIAL_PORT == 0)
6997 +#define regi_serial regi_ser0
6999 +#if (SERIAL_PORT == 1)
7000 +#define regi_serial regi_ser1
7019 + move.d \x, $r6 ; save value
7020 + moveq 28, $r5 ; counter / shift amount
7022 + move.d $r6, $r3 ; fetch value
7024 + lsr.d $r5, $r3 ; shift nybble we want (delay slot)
7025 + subq 4, $r5 ; count down bits
7029 + moveq 13, $r3 ; delay slot
7031 + moveq 10, $r3 ; delay slot
7045 + ;; TODO: Add code for Ronny's search-for-good-block boot rom algorithm
7047 ;; Start clocks for used blocks.
7048 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
7050 @@ -17,22 +88,258 @@
7051 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
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
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
7068 + move.d REG_ADDR(pinmux, regi_pinmux, rw_pb_gio), $r2
7075 + move.d REG_ADDR(gio, regi_gio, rw_pb_oe), $r2
7084 + moveq 0, $r1 ; led 5-bit binary counter
7091 + move.d 100000000, $r2 ; delay loop (100e6 => 1s @200Mc)
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
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
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
7129 + movu.w 0x0200, $r11 ; source in flash (byte address) (DELAY SLOT)
7131 #include "../../lib/nand_init.S"
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
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
7155 + ;; Normal NOR boot
7156 move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10
7157 - jump $r10 ; Jump to decompresser
7158 + jump $r10 ; Jump to decompresser
7162 + add.d $r13, $r11 ; mem offs + src offs -> src addr
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
7174 +#if FLASH_LEDS_INSTEAD_OF_BOOT
7180 + moveq 0, $r1 ; led binary counter
7187 + move.d 100000000, $r2 ; delay loop (100e6 => 1s)
7192 + ba 1b ; loop forever
7197 - move.d 0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10
7198 - jump $r10 ; Jump to decompresser
7201 + ;; dump memory to serial port
7203 +#if (SERIAL_PORT == 1)
7204 + ;; set up serial-1 pins
7205 + move.d REG_ADDR(pinmux, regi_pinmux, rw_hwprot), $r1
7207 + or.d REG_STATE(pinmux, rw_hwprot, ser1, yes), $r0
7211 + ;; rw_xoff: chr and automatic = 0
7212 + move.d REG_ADDR(ser, regi_serial, rw_xoff), $r1
7214 + and.d ~(REG_MASK(ser, rw_xoff, automatic) | REG_MASK(ser, rw_xoff, chr)), $r0
7218 + move.d REG_ADDR(ser, regi_serial, rw_tr_ctrl), $r1
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
7225 + move.d REG_ADDR(ser, regi_serial, rw_tr_baud_div), $r1
7227 + move.w (29493000 / 8) / 115200, $r0
7232 + move.d REG_ADDR(ser, regi_serial, rw_rec_ctrl), $r1
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
7239 + move.d REG_ADDR(ser, regi_serial, rw_rec_baud_div), $r1
7241 + move.w (29493000 / 8) / 115200, $r0
7247 + move.d 0x38000000, $r5 ; pointer
7257 + movu.b [$r5+], $r3 ; get value
7258 + move.d $r3, $r6 ; save
7261 + lsrq 4, $r3 ; high nybble (delay slot)
7263 + move.d $r6, $r3 ; restore
7265 + andq 15, $r3 ; delay slot
7277 + moveq 13, $r3 ; delay slot
7279 + moveq 10, $r3 ; delay slot
7281 + ba 1b ; loop forever
7287 + addq 48, $r3 ; delay slot
7291 + move.d REG_ADDR(ser, regi_serial, rs_stat_din), $r1
7292 + move.d REG_ADDR(ser, regi_serial, rw_dout), $r2
7295 + btstq REG_BIT(ser, rs_stat_din, tr_rdy), $r4
7299 + move.d $r3, [$r2] ; delay slot
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
7309 +;; TODO: Clear .bss (not needed yet because size of .bss is zero)
7310 +;; TODO: Change .ld script so that BSS is in DRAM?
7312 +;; Ok, time to do something. Continue with boot loader in C.
7313 +;; Must set up minimal C environment first though.
7315 + move.d 0x38020000, $sp ; stack pointer at top of internal RAM
7317 + move.d bootload, $r10
7318 + jump $r10 ; Jump to boot loader
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
7327 + * Small practical functions for boot loader
7330 + * writeb/writew/readb/readw
7331 + * putc/puts/putnybble/putx
7332 + * error/error2/BUG
7335 + * $Id: lib.c,v 1.4 2006/11/03 10:35:52 pkj Exp $
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>
7347 +/* the "heap" is put directly after BSS ends, at _end */
7350 +static long free_mem_ptr = (long)&_end;
7352 +void *malloc(int size)
7356 + if (size <0) error("Malloc error");
7358 + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
7360 + p = (void *)free_mem_ptr;
7361 + free_mem_ptr += size;
7366 +void free(void *where)
7372 +unsigned char readb(const volatile void *addr)
7374 + return *(volatile unsigned char *) addr;
7377 +unsigned short readw(const volatile void *addr)
7379 + return *(volatile unsigned short *) addr;
7382 +void writeb(unsigned char b, volatile void *addr)
7384 + *(volatile unsigned char *) addr = b;
7387 +void writew(unsigned short b, volatile void *addr)
7389 + *(volatile unsigned short *) addr = b;
7392 +/* info and error messages to serial console */
7394 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
7396 +serout(const char c, reg_scope_instances regi_ser)
7398 + reg_ser_rs_stat_din rs;
7399 + reg_ser_rw_dout dout = {.data = c};
7402 + rs = REG_RD(ser, regi_ser, rs_stat_din);
7404 + while (!rs.tr_rdy);/* Wait for tranceiver. */
7406 + REG_WR(ser, regi_ser, rw_dout, dout);
7413 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7414 + serout(c, regi_ser0);
7416 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7417 + serout(c, regi_ser1);
7419 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7420 + serout(c, regi_ser2);
7422 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7423 + serout(c, regi_ser3);
7429 +puts(const char *s)
7438 + putc("0123456789abcdef"[n & 15]);
7447 + for (i = 7; i >= 0; i--)
7448 + putnybble(x >> 4*i);
7457 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
7460 +memset(void* s, int c, size_t n)
7463 + char *ss = (char*)s;
7465 + for (i=0;i<n;i++) ss[i] = c;
7469 +memcpy(void* __dest, __const void* __src,
7473 + char *d = (char *)__dest, *s = (char *)__src;
7475 + for (i=0;i<__n;i++) d[i] = s[i];
7479 +error(const char *x)
7483 + puts("\r\n\n -- System halted\n");
7485 + while(1); /* Halt */
7489 +error2(const char *x, int y, const char *z)
7497 + puts("\r\n\n -- System halted\n");
7499 + while(1); /* Halt */
7503 +serial_setup(reg_scope_instances regi_ser)
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;
7511 + /* Turn off XOFF. */
7512 + xoff = REG_RD(ser, regi_ser, rw_xoff);
7515 + xoff.automatic = regk_ser_no;
7517 + REG_WR(ser, regi_ser, rw_xoff, xoff);
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);
7525 + tr_ctrl.stop_bits = 1; /* 2 stop bits. */
7526 + tr_ctrl.en = 1; /* enable transmitter */
7527 + rec_ctrl.en = 1; /* enabler receiver */
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.
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;
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);
7548 + reg_pinmux_rw_hwprot hwprot;
7550 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
7551 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7552 + serial_setup(regi_ser0);
7554 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7555 + hwprot.ser1 = regk_pinmux_yes;
7556 + serial_setup(regi_ser1);
7558 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7559 + hwprot.ser2 = regk_pinmux_yes;
7560 + serial_setup(regi_ser2);
7562 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7563 + hwprot.ser3 = regk_pinmux_yes;
7564 + serial_setup(regi_ser3);
7566 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
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
7574 + * Small practical functions for boot loader
7577 + * putc/puts/putnybble/putd
7578 + * writeb/writew/readb/readw
7579 + * error/error2/BUG
7582 + * $Id: lib.h,v 1.3 2006/11/03 10:35:52 pkj Exp $
7589 +#include <linux/types.h>
7591 +/* nice stuff we need without having any library around */
7593 +void* memset(void* s, int c, size_t n);
7594 +void* memcpy(void* __dest, __const void* __src,
7597 +#define memzero(s, n) memset ((s), 0, (n))
7600 +#define BUG() error2("BUG in " __FILE__, __LINE__, __FUNCTION__)
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);
7608 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
7609 +void putc(const char);
7610 +void puts(const char *);
7611 +void putnybble(int n);
7617 +#define putnybble(nyb)
7620 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
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);
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
7633 + * $Id: mtd-abi.h,v 1.1 2006/09/06 09:21:07 ricardw Exp $
7635 + * Portions of MTD ABI definition which are shared by kernel and user space
7638 +#ifndef __MTD_ABI_H__
7639 +#define __MTD_ABI_H__
7641 +#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into
7642 + separate files was to avoid #ifdef __KERNEL__ */
7646 +struct erase_info_user {
7651 +struct mtd_oob_buf {
7654 + unsigned char __user *ptr;
7657 +#define MTD_ABSENT 0
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
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
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)
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
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
7698 +/* OTP mode selection */
7699 +#define MTD_OTP_OFF 0
7700 +#define MTD_OTP_FACTORY 1
7701 +#define MTD_OTP_USER 2
7703 +struct mtd_info_user {
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)
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;
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)
7745 +struct nand_oobinfo {
7747 + uint32_t eccbytes;
7748 + uint32_t oobfree[8][2];
7749 + uint32_t eccpos[32];
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
7758 + * $Id: mtd.h,v 1.5 2006/12/14 06:59:24 ricardw Exp $
7760 + * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
7762 + * Released under GPL
7765 +#ifndef __MTD_MTD_H__
7766 +#define __MTD_MTD_H__
7769 +#error This is a kernel header. Perhaps include mtd-user.h instead?
7772 +/* only include absolutely necessary linux headers which will not change
7775 +#include <linux/types.h>
7776 +#include <linux/errno.h>
7779 +#include <linux/module.h>
7780 +#include <linux/uio.h>
7781 +#include <linux/notifier.h>
7783 +#include <linux/mtd/compatmac.h>
7784 +#include <mtd/mtd-abi.h>
7787 +#include "mtd-abi.h"
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
7796 +/* our MTD config */
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
7806 +#define MTD_CHAR_MAJOR 90
7807 +#define MTD_BLOCK_MAJOR 31
7808 +#define MAX_MTD_DEVICES 16
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
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;
7823 + u_int32_t fail_addr;
7828 + void (*callback) (struct erase_info *self);
7831 + struct erase_info *next;
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 */
7843 + u_int32_t size; // Total size of the MTD
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
7849 + u_int32_t erasesize;
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;
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?)
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
7867 + // Kernel-only stuff starts here.
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
7875 + /* Data for variable erase regions. If numeraseregions is zero,
7876 + * it means that the whole device has erasesize as given above.
7878 + int numeraseregions;
7879 + struct mtd_erase_region_info *eraseregions;
7881 + /* This really shouldn't be here. It can go away in 2.5 */
7882 + u_int32_t bank_size;
7884 + int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
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);
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);
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);
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);
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);
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.
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);
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.
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);
7929 + void (*sync) (struct mtd_info *mtd);
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);
7935 + /* Power Management functions */
7936 + int (*suspend) (struct mtd_info *mtd);
7937 + void (*resume) (struct mtd_info *mtd);
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);
7943 +#if 0 /* don't know what this is for */
7944 + struct notifier_block reboot_notifier; /* default mode before reboot */
7949 + struct module *owner;
7953 +#if 0 /* don't need these */
7954 + /* Kernel-side ioctl definitions */
7956 +extern int add_mtd_device(struct mtd_info *mtd);
7957 +extern int del_mtd_device (struct mtd_info *mtd);
7959 +extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
7961 +extern void put_mtd_device(struct mtd_info *mtd);
7964 +struct mtd_notifier {
7965 + void (*add)(struct mtd_info *mtd);
7966 + void (*remove)(struct mtd_info *mtd);
7967 + struct list_head list;
7971 +extern void register_mtd_user (struct mtd_notifier *new);
7972 +extern int unregister_mtd_user (struct mtd_notifier *old);
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);
7979 +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
7980 + unsigned long count, loff_t from, size_t *retlen);
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)
7997 +#ifdef CONFIG_MTD_PARTITIONS
7998 +void mtd_erase_callback(struct erase_info *instr);
8000 +static inline void mtd_erase_callback(struct erase_info *instr)
8002 + if (instr->callback)
8003 + instr->callback(instr);
8008 + * Debugging macro and defines
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 */
8015 +#ifdef CONFIG_MTD_DEBUG
8016 +#define DEBUG(n, args...) \
8018 + if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
8019 + printk(KERN_INFO args); \
8021 +#else /* CONFIG_MTD_DEBUG */
8022 +#define DEBUG(n, args...) do { } while(0)
8024 +#endif /* CONFIG_MTD_DEBUG */
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
8032 + * linux/include/linux/mtd/nand.h
8034 + * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
8035 + * Steven J. Hill <sjhill@realitydiluted.com>
8036 + * Thomas Gleixner <tglx@linutronix.de>
8038 + * $Id: nand.h,v 1.4 2006/11/03 10:35:52 pkj Exp $
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.
8045 + * Contains standard defines and IDs for NAND flash devices
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
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,
8075 + * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
8076 + * Split manufacturer and device ID structures
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.
8086 +#ifndef __LINUX_MTD_NAND_H
8087 +#define __LINUX_MTD_NAND_H
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>
8095 +#include "mtd.h" /* local */
8097 +#include <linux/kernel.h> /* we do need this though ... */
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);
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);
8109 +/* The maximum number of NAND chips in an array */
8110 +#define NAND_MAX_CHIPS 8
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.
8116 +#define NAND_MAX_OOBSIZE 64
8119 + * Constants for hardware specific CLE/ALE/NCE function
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
8139 + * Standard NAND flash commands
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
8153 +/* Extended commands for large page devices */
8154 +#define NAND_CMD_READSTART 0x30
8155 +#define NAND_CMD_CACHEDPROG 0x15
8157 +/* Extended commands for AG-AND device */
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.
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
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
8184 + * Constants for ECC_MODES
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
8203 + * Constants for Hardware ECC
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
8212 +/* Bit mask for flags passed to do_nand_read_ecc */
8213 +#define NAND_GET_DEVICE 0x80
8216 +/* Option constants for bizarre disfunctionality and real
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
8240 +/* Options valid for Samsung large page devices */
8241 +#define NAND_SAMSUNG_LP_OPTIONS \
8242 + (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
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))
8250 +/* Mask to zero out the chip options, which come from the id table */
8251 +#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR)
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
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
8272 + * nand_state_t - chip states
8273 + * Enumeration for NAND flash chip state
8285 +/* Keep gcc happy */
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
8295 +#if NAND_HWECC_SUPPORT
8296 +struct nand_hw_control {
8298 + struct nand_chip *active;
8299 + wait_queue_head_t wq;
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)
8364 + void __iomem *IO_ADDR_R;
8365 + void __iomem *IO_ADDR_W;
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);
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);
8392 +#if 0 /* no spinlocks or wait queues in boot loader */
8393 + spinlock_t chip_lock;
8394 + wait_queue_head_t wq;
8396 + nand_state_t state;
8398 + int phys_erase_shift;
8399 + int bbt_erase_shift;
8405 + unsigned int options;
8408 + unsigned long chipsize;
8411 + struct nand_oobinfo *autooob;
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;
8418 + int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
8422 + * NAND Flash Manufacturer ID Codes
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
8433 + * struct nand_flash_dev - NAND Flash Device ID Structure
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
8445 +struct nand_flash_dev {
8448 + unsigned long pagesize;
8449 + unsigned long chipsize;
8450 + unsigned long erasesize;
8451 + unsigned long options;
8455 + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
8456 + * @name: Manufacturer name
8457 + * @id: manufacturer ID code of device.
8459 +struct nand_manufacturers {
8464 +extern struct nand_flash_dev nand_flash_ids[];
8465 +extern struct nand_manufacturers nand_manuf_ids[];
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
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
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.
8490 +struct nand_bbt_descr {
8492 + int pages[NAND_MAX_CHIPS];
8495 + uint8_t version[NAND_MAX_CHIPS];
8498 + int reserved_block_code;
8502 +/* Options for the bad block table descriptors */
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
8533 +/* The maximum number of blocks to scan for a bbt */
8534 +#define NAND_BBT_SCAN_MAXBLOCKS 4
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);
8546 +* Constants for oob configuration
8548 +#define NAND_SMALL_BADBLOCK_POS 5
8549 +#define NAND_LARGE_BADBLOCK_POS 0
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
8557 + * Snitched from drivers/mtd/nand_base.c
8558 + * Modified to run outside Linux.
8559 + * #if 0'd to remove non-essential functionality
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.
8566 + * Additional technical information is available on
8567 + * http://www.linux-mtd.infradead.org/tech/nand.html
8569 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8570 + * 2002 Thomas Gleixner (tglx@linutronix.de)
8572 + * 02-08-2004 tglx: support for strange chips, which cannot auto increment
8573 + * pages on read / read_oob
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
8580 + * 04-14-2004 tglx: first working version for 2k page size chips
8582 + * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
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>
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.
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.
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.
8606 + * 08-20-2005 vwool: suspend/resume added
8609 + * David Woodhouse for adding multichip support
8611 + * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
8612 + * rework for 2K page size chips
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.
8621 + * $Id: nand_base.c,v 1.11 2006/11/10 08:55:58 ricardw Exp $
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.
8629 +#include <linux/types.h>
8630 +#include <linux/delay.h>
8631 +#include <linux/errno.h>
8633 +#include <linux/sched.h>
8634 +#include <linux/slab.h>
8639 +#include "nand_ecc.h"
8642 +#include <linux/mtd/compatmac.h>
8643 +#include <linux/interrupt.h>
8644 +#include <linux/bitops.h>
8645 +#include <asm/io.h>
8648 +#ifdef CONFIG_MTD_PARTITIONS
8649 +#include <linux/mtd/partitions.h>
8655 +#define GPIO_SYNC 0
8657 +#undef DEBUG /* from mtd.h */
8658 +#define DEBUG(n, args...) do { } while(0)
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,
8666 + .eccpos = {0, 1, 2},
8667 + .oobfree = { {3, 2}, {6, 2} }
8670 +static struct nand_oobinfo nand_oob_16 = {
8671 + .useecc = MTD_NANDECC_AUTOPLACE,
8673 + .eccpos = {0, 1, 2, 3, 6, 7},
8674 + .oobfree = { {8, 8} }
8677 +static struct nand_oobinfo nand_oob_64 = {
8678 + .useecc = MTD_NANDECC_AUTOPLACE,
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} }
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,
8702 + * NAND low-level MTD interface functions
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);
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);
8722 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
8723 +static void nand_sync (struct mtd_info *mtd);
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);
8732 +#define nand_verify_pages(...) (0)
8735 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
8738 + * nand_release_device - [GENERIC] release chip
8739 + * @mtd: MTD device structure
8741 + * Deselect, release chip lock and wake up anyone waiting on the device
8743 +static void nand_release_device (struct mtd_info *mtd)
8745 + struct nand_chip *this = mtd->priv;
8747 + /* De-select the NAND device */
8748 + this->select_chip(mtd, -1);
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);
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);
8769 + * nand_read_byte - [DEFAULT] read one byte from the chip
8770 + * @mtd: MTD device structure
8772 + * Default read function for 8bit buswith
8774 +static u_char nand_read_byte(struct mtd_info *mtd)
8776 + struct nand_chip *this = mtd->priv;
8777 + return readb(this->IO_ADDR_R);
8781 + * nand_write_byte - [DEFAULT] write one byte to the chip
8782 + * @mtd: MTD device structure
8783 + * @byte: pointer to data byte to write
8785 + * Default write function for 8it buswith
8787 +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
8789 + struct nand_chip *this = mtd->priv;
8790 + writeb(byte, this->IO_ADDR_W);
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).
8801 + (void) readb(this->IO_ADDR_W); /* that's right, IO_ADDR_W */
8806 + * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
8807 + * @mtd: MTD device structure
8809 + * Default read function for 16bit buswith with
8810 + * endianess conversion
8812 +static u_char nand_read_byte16(struct mtd_info *mtd)
8814 + struct nand_chip *this = mtd->priv;
8815 + return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
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
8823 + * Default write function for 16bit buswith with
8824 + * endianess conversion
8826 +static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
8828 + struct nand_chip *this = mtd->priv;
8829 + writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
8833 + * nand_read_word - [DEFAULT] read one word from the chip
8834 + * @mtd: MTD device structure
8836 + * Default read function for 16bit buswith without
8837 + * endianess conversion
8839 +static u16 nand_read_word(struct mtd_info *mtd)
8841 + struct nand_chip *this = mtd->priv;
8842 + return readw(this->IO_ADDR_R);
8846 + * nand_write_word - [DEFAULT] write one word to the chip
8847 + * @mtd: MTD device structure
8848 + * @word: data word to write
8850 + * Default write function for 16bit buswith without
8851 + * endianess conversion
8853 +static void nand_write_word(struct mtd_info *mtd, u16 word)
8855 + struct nand_chip *this = mtd->priv;
8856 + writew(word, this->IO_ADDR_W);
8860 + * nand_select_chip - [DEFAULT] control CE line
8861 + * @mtd: MTD device structure
8862 + * @chip: chipnumber to select, -1 for deselect
8864 + * Default select function for 1 chip devices.
8866 +static void nand_select_chip(struct mtd_info *mtd, int chip)
8868 + struct nand_chip *this = mtd->priv;
8871 + this->hwcontrol(mtd, NAND_CTL_CLRNCE);
8874 + this->hwcontrol(mtd, NAND_CTL_SETNCE);
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
8888 + * Default write function for 8bit buswith
8890 +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
8893 + struct nand_chip *this = mtd->priv;
8895 + for (i=0; i<len; i++)
8896 + writeb(buf[i], this->IO_ADDR_W);
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
8905 + * Default read function for 8bit buswith
8907 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
8910 + struct nand_chip *this = mtd->priv;
8912 + for (i=0; i<len; i++)
8913 + buf[i] = readb(this->IO_ADDR_R);
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
8922 + * Default verify function for 8bit buswith
8924 +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
8927 + struct nand_chip *this = mtd->priv;
8929 + for (i=0; i<len; i++)
8930 + if (buf[i] != readb(this->IO_ADDR_R))
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
8942 + * Default write function for 16bit buswith
8944 +static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8947 + struct nand_chip *this = mtd->priv;
8948 + u16 *p = (u16 *) buf;
8951 + for (i=0; i<len; i++)
8952 + writew(p[i], this->IO_ADDR_W);
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
8962 + * Default read function for 16bit buswith
8964 +static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
8967 + struct nand_chip *this = mtd->priv;
8968 + u16 *p = (u16 *) buf;
8971 + for (i=0; i<len; i++)
8972 + p[i] = readw(this->IO_ADDR_R);
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
8981 + * Default verify function for 16bit buswith
8983 +static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8986 + struct nand_chip *this = mtd->priv;
8987 + u16 *p = (u16 *) buf;
8990 + for (i=0; i<len; i++)
8991 + if (p[i] != readw(this->IO_ADDR_R))
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
9003 + * Check, if the block is bad.
9005 +static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
9007 + int page, chipnr, res = 0;
9008 + struct nand_chip *this = mtd->priv;
9012 + page = (int)(ofs >> this->page_shift);
9013 + chipnr = (int)(ofs >> this->chip_shift);
9015 + /* Grab the lock and see if the device is available */
9016 + nand_get_device (this, mtd, FL_READING);
9018 + /* Select the NAND device */
9019 + this->select_chip(mtd, chipnr);
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)
9028 + if ((bad & 0xFF) != 0xff)
9031 + this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
9032 + if (this->read_byte(mtd) != 0xff)
9037 + /* Deselect and wake up anyone waiting on the device */
9038 + nand_release_device(mtd);
9045 + * nand_default_block_markbad - [DEFAULT] mark a block bad
9046 + * @mtd: MTD device structure
9047 + * @ofs: offset from device start
9049 + * This is the default implementation, which can be overridden by
9050 + * a hardware specific driver.
9052 +#if NAND_WRITE_SUPPORT
9053 +static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
9055 + struct nand_chip *this = mtd->priv;
9056 + u_char buf[2] = {0, 0};
9060 + /* Get block number */
9061 + block = ((int) ofs) >> this->bbt_erase_shift;
9063 + this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
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);
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);
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
9082 + * The function expects, that the device is already selected
9084 +#if NAND_WRITE_SUPPORT
9085 +static int nand_check_wp (struct mtd_info *mtd)
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;
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
9101 + * Check, if the block is bad. Either by reading the bad block table or
9102 + * calling of the scan function.
9104 +static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
9106 + struct nand_chip *this = mtd->priv;
9109 + return this->block_bad(mtd, ofs, getchip);
9111 +#if NAND_BBT_SUPPORT
9112 + /* Return info from the table */
9113 + return nand_isbad_bbt (mtd, ofs, allowbbt);
9115 + BUG(); /* should not happen */
9119 + * Wait for the ready pin, after a command
9120 + * The timeout is catched later.
9122 +static void nand_wait_ready(struct mtd_info *mtd)
9124 + struct nand_chip *this = mtd->priv;
9126 + unsigned long timeo = jiffies + 2;
9129 + /* wait until command is processed or timeout occures */
9131 + if (this->dev_ready(mtd))
9134 + touch_softlockup_watchdog();
9135 + } while (time_before(jiffies, timeo));
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
9147 + * Send command to NAND device. This function is used for small page
9148 + * devices (256/512 Bytes per page)
9150 +static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9152 + register struct nand_chip *this = mtd->priv;
9154 + /* Begin command latch cycle */
9155 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9157 + * Write out the command to the device.
9159 + if (command == NAND_CMD_SEQIN) {
9162 + if (column >= mtd->oobblock) {
9164 + column -= mtd->oobblock;
9165 + readcmd = NAND_CMD_READOOB;
9166 + } else if (column < 256) {
9167 + /* First 256 bytes --> READ0 */
9168 + readcmd = NAND_CMD_READ0;
9171 + readcmd = NAND_CMD_READ1;
9173 + this->write_byte(mtd, readcmd);
9175 + this->write_byte(mtd, command);
9177 + /* Set ALE and clear CLE to start address cycle */
9178 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9180 + if (column != -1 || page_addr != -1) {
9181 + this->hwcontrol(mtd, NAND_CTL_SETALE);
9183 + /* Serially input address */
9184 + if (column != -1) {
9185 + /* Adjust columns for 16 bit buswidth */
9186 + if (this->options & NAND_BUSWIDTH_16)
9188 + this->write_byte(mtd, column);
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));
9197 + /* Latch in address */
9198 + this->hwcontrol(mtd, NAND_CTL_CLRALE);
9202 + * program and erase have their own busy handlers
9203 + * status and sequential in needs no delay
9205 + switch (command) {
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:
9214 + case NAND_CMD_RESET:
9215 + if (this->dev_ready)
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));
9224 + /* This applies to read commands */
9227 + * If we don't have access to the busy pin, we apply the given
9230 + if (!this->dev_ready) {
9231 + udelay (this->chip_delay);
9235 + /* Apply this short delay always to ensure that we do wait tWB in
9236 + * any case on any machine. */
9239 + nand_wait_ready(mtd);
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
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.
9254 +static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9256 + register struct nand_chip *this = mtd->priv;
9258 + /* Emulate NAND_CMD_READOOB */
9259 + if (command == NAND_CMD_READOOB) {
9260 + column += mtd->oobblock;
9261 + command = NAND_CMD_READ0;
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);
9272 + if (column != -1 || page_addr != -1) {
9273 + this->hwcontrol(mtd, NAND_CTL_SETALE);
9275 + /* Serially input address */
9276 + if (column != -1) {
9277 + /* Adjust columns for 16 bit buswidth */
9278 + if (this->options & NAND_BUSWIDTH_16)
9280 + this->write_byte(mtd, column & 0xff);
9281 + this->write_byte(mtd, column >> 8);
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));
9290 + /* Latch in address */
9291 + this->hwcontrol(mtd, NAND_CTL_CLRALE);
9295 + * program and erase have their own busy handlers
9296 + * status, sequential in, and deplete1 need no delay
9298 + switch (command) {
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:
9310 + * read error status commands require only a short delay
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);
9320 + case NAND_CMD_RESET:
9321 + if (this->dev_ready)
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));
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 */
9339 + /* This applies to read commands */
9342 + * If we don't have access to the busy pin, we apply the given
9345 + if (!this->dev_ready) {
9346 + udelay (this->chip_delay);
9351 + /* Apply this short delay always to ensure that we do wait tWB in
9352 + * any case on any machine. */
9355 + nand_wait_ready(mtd);
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
9364 + * Get the device and lock it for exclusive access
9366 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
9368 + this->state = new_state;
9371 + struct nand_chip *active;
9373 + wait_queue_head_t *wq;
9374 + DECLARE_WAITQUEUE (wait, current);
9376 + lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
9377 + wq = (this->controller) ? &this->controller->wq : &this->wq;
9382 + /* Hardware controller shared among independend devices */
9383 + if (this->controller) {
9384 + if (this->controller->active)
9385 + active = this->controller->active;
9387 + this->controller->active = this;
9389 + if (active == this && this->state == FL_READY) {
9390 + this->state = new_state;
9391 + spin_unlock(lock);
9394 + if (new_state == FL_PM_SUSPENDED) {
9395 + spin_unlock(lock);
9396 + return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
9398 + set_current_state(TASK_UNINTERRUPTIBLE);
9399 + add_wait_queue(wq, &wait);
9400 + spin_unlock(lock);
9402 + remove_wait_queue(wq, &wait);
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
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
9418 +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
9422 + unsigned long timeo = jiffies;
9427 + if (state == FL_ERASING)
9428 + timeo += (HZ * 400) / 1000;
9430 + timeo += (HZ * 20) / 1000;
9433 + /* Apply this short delay always to ensure that we do wait tWB in
9434 + * any case on any machine. */
9437 + if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
9438 + this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
9440 + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
9443 + while (time_before(jiffies, timeo)) {
9444 + /* Check, if we were interrupted */
9445 + if (this->state != state)
9448 + while (1) { /* wait indefinitely */
9450 + if (this->dev_ready) {
9451 + if (this->dev_ready(mtd))
9454 + if (this->read_byte(mtd) & NAND_STATUS_READY)
9462 + status = (int) this->read_byte(mtd);
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
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 :)
9479 + * Cached programming is not supported yet.
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)
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;
9492 + /* FIXME: Enable cached programming */
9495 + /* Send command to begin auto page programming */
9496 + this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
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);
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;
9514 + this->write_buf(mtd, this->data_poi, mtd->oobblock);
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;
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);
9539 + this->write_buf(mtd, oob_buf, mtd->oobsize);
9541 + /* Send command to actually program the data */
9542 + this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
9545 + /* call wait ready function */
9546 + status = this->waitfunc (mtd, this, FL_WRITING);
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);
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);
9559 + /* FIXME: Implement cached programming ! */
9560 + /* wait until cache is ready*/
9561 + // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
9567 +#if NAND_WRITE_SUPPORT
9568 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
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
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.
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)
9591 + int i, j, datidx = 0, oobofs = 0, res = -EIO;
9592 + int eccsteps = this->eccsteps;
9594 + u_char oobdata[64];
9596 + hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
9598 + /* Send command to read back the first page */
9599 + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
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);
9608 + datidx += mtd->eccsize;
9609 + /* Have we a hw generator layout ? */
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);
9616 + oobofs += hweccbytes;
9619 + /* check, if we must compare all data or if we just have to
9620 + * compare the ecc bytes
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);
9628 + /* Read always, else autoincrement fails */
9629 + this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
9631 + if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
9632 + int ecccnt = oobsel->eccbytes;
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);
9645 + oobofs += mtd->oobsize - hweccbytes * eccsteps;
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.
9656 + if (!this->dev_ready)
9657 + udelay (this->chip_delay);
9659 + nand_wait_ready(mtd);
9661 + /* All done, return happy */
9666 + /* Check, if the chip supports auto page increment */
9667 + if (!NAND_CANAUTOINCR(this))
9668 + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
9671 + * Terminate the read command. We come here in case of an error
9672 + * So we must issue a reset command.
9675 + this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
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
9689 + * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
9690 + * and flags = 0xff
9692 +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
9694 + return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
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
9708 + * This function simply calls nand_do_read_ecc with flags = 0xff
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)
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);
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
9734 + * NAND read with ECC
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)
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;
9751 + int compareecc = 1;
9755 + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
9757 + puts ("nand_read_ecc: from = ");
9759 + puts (", len = ");
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"));
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);
9776 + /* Autoplace of oob data ? Use the default placement scheme */
9777 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
9778 + oobsel = this->autooob;
9780 + eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
9781 + oob_config = oobsel->eccpos;
9783 + /* Select the NAND device */
9784 + chipnr = (int)(from >> this->chip_shift);
9785 + this->select_chip(mtd, chipnr);
9787 + /* First we calculate the starting page */
9788 + realpage = (int) (from >> this->page_shift);
9789 + page = realpage & this->pagemask;
9791 + /* Get raw starting column */
9792 + col = from & (mtd->oobblock - 1);
9794 + end = mtd->oobblock;
9795 + ecc = this->eccsize;
9796 + eccbytes = this->eccbytes;
9798 + if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
9801 + oobreadlen = mtd->oobsize;
9802 + if (this->options & NAND_HWECC_SYNDROME)
9803 + oobreadlen -= oobsel->eccbytes;
9805 + /* Loop until all data read */
9806 + while (read < len) {
9808 + int aligned = (!col && (len - read) >= end);
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
9814 + data_poi = &buf[read];
9816 + data_poi = this->data_buf;
9818 + /* Check, if we have this page in the buffer
9820 + * FIXME: Make it work when we must provide oob data too,
9821 + * check the usage of data_buf oob field
9823 + if (realpage == this->pagebuf && !oob_buf) {
9824 + /* aligned read ? */
9826 + memcpy (data_poi, this->data_buf, end);
9830 + /* Check, if we must send the read command */
9832 + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
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];
9841 + eccsteps = this->eccsteps;
9843 + switch (eccmode) {
9844 + case NAND_ECC_NONE: { /* No ECC, Read in a page */
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;
9852 + this->read_buf(mtd, data_poi, end);
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]);
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);
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);
9885 + this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
9892 + /* read oobdata */
9893 + this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
9895 + /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
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]];
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]);
9907 + /* Get next chunk of ecc bytes */
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
9914 + if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
9915 + int *p = (int *)(&oob_data[mtd->oobsize]);
9916 + p[i] = ecc_status;
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);
9922 + puts ("nand_read_ecc: " "Failed ECC read, page ");
9931 + /* check, if we have a fs supplied oob-buffer */
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);
9945 + case MTD_NANDECC_PLACE:
9946 + /* YAFFS1 legacy mode */
9947 + oob_data += this->eccsteps * sizeof (int);
9949 + oob_data += mtd->oobsize;
9953 + /* Partial page read, transfer data into fs buffer */
9955 + for (j = col; j < end && read < len; j++)
9956 + buf[read++] = data_poi[j];
9957 + this->pagebuf = realpage;
9959 + read += mtd->oobblock;
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.
9966 + if (!this->dev_ready)
9967 + udelay (this->chip_delay);
9969 + nand_wait_ready(mtd);
9974 + /* For subsequent reads align to page boundary. */
9976 + /* Increment page address */
9979 + page = realpage & this->pagemask;
9980 + /* Check, if we cross a chip boundary */
9983 + this->select_chip(mtd, -1);
9984 + this->select_chip(mtd, chipnr);
9986 + /* Check, if the chip supports auto page increment
9987 + * or if we have hit a block boundary.
9989 + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
9993 + /* Deselect and wake up anyone waiting on the device */
9994 + if (flags & NAND_GET_DEVICE)
9995 + nand_release_device(mtd);
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
10003 + return ecc_failed ? -EBADMSG : 0;
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
10014 + * NAND read out-of-band data from the spare area
10016 +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
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;
10022 + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
10024 + /* Shift to get page */
10025 + page = (int)(from >> this->page_shift);
10026 + chipnr = (int)(from >> this->chip_shift);
10028 + /* Mask to get column */
10029 + col = from & (mtd->oobsize - 1);
10031 + /* Initialize return length value */
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");
10041 + /* Grab the lock and see if the device is available */
10042 + nand_get_device (this, mtd , FL_READING);
10044 + /* Select the NAND device */
10045 + this->select_chip(mtd, chipnr);
10047 + /* Send the read command */
10048 + this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
10050 + * Read the data, if we read more than one page
10051 + * oob data, let the device transfer the data !
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);
10060 + /* Read more ? */
10065 + /* Check, if we cross a chip boundary */
10066 + if (!(page & this->pagemask)) {
10068 + this->select_chip(mtd, -1);
10069 + this->select_chip(mtd, chipnr);
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.
10077 + if (!this->dev_ready)
10078 + udelay (this->chip_delay);
10080 + nand_wait_ready(mtd);
10082 + /* Check, if the chip supports auto page increment
10083 + * or if we have hit a block boundary.
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);
10092 + /* Deselect and wake up anyone waiting on the device */
10093 + nand_release_device(mtd);
10095 + /* Return happy */
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
10108 + * Read raw data including oob into buffer
10110 +int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
10112 + struct nand_chip *this = mtd->priv;
10113 + int page = (int) (from >> this->page_shift);
10114 + int chip = (int) (from >> this->chip_shift);
10117 + int pagesize = mtd->oobblock + mtd->oobsize;
10118 + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
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");
10126 + /* Grab the lock and see if the device is available */
10127 + nand_get_device (this, mtd , FL_READING);
10129 + this->select_chip (mtd, chip);
10131 + /* Add requested oob length */
10136 + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
10139 + this->read_buf (mtd, &buf[cnt], pagesize);
10145 + if (!this->dev_ready)
10146 + udelay (this->chip_delay);
10148 + nand_wait_ready(mtd);
10150 + /* Check, if the chip supports auto page increment */
10151 + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
10155 + /* Deselect and wake up anyone waiting on the device */
10156 + nand_release_device(mtd);
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
10170 + * 1. Filesystem buffer available and autoplacement is off,
10171 + * return filesystem buffer
10172 + * 2. No filesystem buffer or autoplace is off, return internal
10174 + * 3. Filesystem buffer is given and autoplace selected
10175 + * put data from fs buffer into internal buffer and
10176 + * retrun internal buffer
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.
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)
10188 + struct nand_chip *this = mtd->priv;
10191 + /* Zero copy fs supplied buffer */
10192 + if (fsbuf && !autoplace)
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;
10202 + /* If we have no autoplacement or no fs buffer use the internal one */
10203 + if (!autoplace || !fsbuf)
10204 + return this->oob_buf;
10206 + /* Walk through the pages and place the data */
10207 + this->oobdirty = 1;
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);
10217 + ofs += mtd->oobavail;
10219 + return this->oob_buf;
10223 +#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
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
10233 + * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
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)
10239 + return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
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
10253 + * NAND write with ECC
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)
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));
10265 + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10267 + /* Initialize retlen, in case of early exit */
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");
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");
10282 + /* Grab the lock and see if the device is available */
10283 + nand_get_device (this, mtd, FL_WRITING);
10285 + /* Calculate chipnr */
10286 + chipnr = (int)(to >> this->chip_shift);
10287 + /* Select the NAND device */
10288 + this->select_chip(mtd, chipnr);
10290 + /* Check, if it is write protected */
10291 + if (nand_check_wp(mtd))
10294 + /* if oobsel is NULL, use chip defaults */
10295 + if (oobsel == NULL)
10296 + oobsel = &mtd->oobinfo;
10298 + /* Autoplace of oob data ? Use the default placement scheme */
10299 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10300 + oobsel = this->autooob;
10303 + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
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;
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;
10321 + /* Loop until all data is written */
10322 + while (written < len) {
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.
10330 + ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
10332 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
10335 + /* Next oob page */
10336 + oob += mtd->oobsize;
10337 + /* Update written bytes count */
10338 + written += mtd->oobblock;
10339 + if (written == len)
10342 + /* Increment page address */
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.
10349 + if (!(page & (ppblock - 1))){
10351 + this->data_poi = bufstart;
10352 + ret = nand_verify_pages (mtd, this, startpage,
10353 + page - startpage,
10354 + oobbuf, oobsel, chipnr, (eccbuf != NULL));
10356 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10359 + *retlen = written;
10361 + ofs = autoplace ? mtd->oobavail : mtd->oobsize;
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);
10371 + /* Check, if we cross a chip boundary */
10374 + this->select_chip(mtd, -1);
10375 + this->select_chip(mtd, chipnr);
10379 + /* Verify the remaining pages */
10381 + this->data_poi = bufstart;
10382 + ret = nand_verify_pages (mtd, this, startpage, totalpages,
10383 + oobbuf, oobsel, chipnr, (eccbuf != NULL));
10385 + *retlen = written;
10387 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10390 + /* Deselect and wake up anyone waiting on the device */
10391 + nand_release_device(mtd);
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
10406 + * NAND write out-of-band
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)
10411 + int column, page, status, ret = -EIO, chipnr;
10412 + struct nand_chip *this = mtd->priv;
10414 + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10416 + /* Shift to get page */
10417 + page = (int) (to >> this->page_shift);
10418 + chipnr = (int) (to >> this->chip_shift);
10420 + /* Mask to get column */
10421 + column = to & (mtd->oobsize - 1);
10423 + /* Initialize return length value */
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");
10432 + /* Grab the lock and see if the device is available */
10433 + nand_get_device (this, mtd, FL_WRITING);
10435 + /* Select the NAND device */
10436 + this->select_chip(mtd, chipnr);
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);
10445 + /* Check, if it is write protected */
10446 + if (nand_check_wp(mtd))
10449 + /* Invalidate the page cache, if we write to the cached page */
10450 + if (page == this->pagebuf)
10451 + this->pagebuf = -1;
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);
10459 + this->write_buf(mtd, buf, len);
10460 + /* postpad 0xff for partial programming */
10461 + this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
10463 + /* Write out desired data */
10464 + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
10466 + this->write_buf(mtd, buf, len);
10468 + /* Send command to program the OOB data */
10469 + this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
10471 + status = this->waitfunc (mtd, this, FL_WRITING);
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);
10479 + /* Return happy */
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);
10486 + if (this->verify_buf(mtd, buf, len)) {
10487 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
10494 + /* Deselect and wake up anyone waiting on the device */
10495 + nand_release_device(mtd);
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
10510 + * NAND write with kvec. This just calls the ecc function
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)
10517 + return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
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
10532 + * NAND write with iovec with ecc
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)
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;
10545 + /* Preset written len for early exit */
10548 + /* Calculate total length of data */
10550 + for (i = 0; i < count; i++)
10551 + total_len += (int) vecs[i].iov_len;
10553 + DEBUG (MTD_DEBUG_LEVEL3,
10554 + "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
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");
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");
10568 + /* Grab the lock and see if the device is available */
10569 + nand_get_device (this, mtd, FL_WRITING);
10571 + /* Get the current chip-nr */
10572 + chipnr = (int) (to >> this->chip_shift);
10573 + /* Select the NAND device */
10574 + this->select_chip(mtd, chipnr);
10576 + /* Check, if it is write protected */
10577 + if (nand_check_wp(mtd))
10580 + /* if oobsel is NULL, use chip defaults */
10581 + if (oobsel == NULL)
10582 + oobsel = &mtd->oobinfo;
10584 + /* Autoplace of oob data ? Use the default placement scheme */
10585 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10586 + oobsel = this->autooob;
10589 + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
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;
10598 + startpage = page & this->pagemask;
10600 + /* Loop until all kvec' data has been written */
10603 + /* If the given tuple is >= pagesize then
10604 + * write it out from the iov
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;
10615 + this->data_poi = bufstart;
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.
10622 + ret = nand_write_page (mtd, this, page & this->pagemask,
10623 + &oobbuf[oob], oobsel, i != numpages);
10626 + this->data_poi += mtd->oobblock;
10627 + len += mtd->oobblock;
10628 + oob += mtd->oobsize;
10631 + /* Check, if we have to switch to the next tuple */
10632 + if (len >= (int) vecs->iov_len) {
10638 + /* We must use the internal buffer, read data out of each
10639 + * tuple until we have a full page to write
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) {
10652 + this->pagebuf = page;
10653 + this->data_poi = this->data_buf;
10654 + bufstart = this->data_poi;
10656 + oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
10657 + ret = nand_write_page (mtd, this, page & this->pagemask,
10658 + oobbuf, oobsel, 0);
10664 + this->data_poi = bufstart;
10665 + ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
10669 + written += mtd->oobblock * numpages;
10674 + startpage = page & this->pagemask;
10675 + /* Check, if we cross a chip boundary */
10676 + if (!startpage) {
10678 + this->select_chip(mtd, -1);
10679 + this->select_chip(mtd, chipnr);
10684 + /* Deselect and wake up anyone waiting on the device */
10685 + nand_release_device(mtd);
10687 + *retlen = written;
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
10698 + * Standard erase command for NAND chips
10700 +#if NAND_ERASE_SUPPORT
10701 +static void single_erase_cmd (struct mtd_info *mtd, int page)
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);
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
10715 + * AND multi block erase command function
10716 + * Erase 4 consecutive blocks
10718 +#if NAND_ERASE_SUPPORT
10719 +static void multi_erase_cmd (struct mtd_info *mtd, int page)
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);
10732 + * nand_erase - [MTD Interface] erase block(s)
10733 + * @mtd: MTD device structure
10734 + * @instr: erase instruction
10736 + * Erase one ore more blocks
10738 +#if NAND_ERASE_SUPPORT
10739 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
10741 + return nand_erase_nand (mtd, instr, 0);
10745 +#define BBT_PAGE_MASK 0xffffff3f
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
10752 + * Erase one ore more blocks
10754 +#if NAND_ERASE_SUPPORT
10755 +int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
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. */
10764 + DEBUG (MTD_DEBUG_LEVEL3,
10765 + "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
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");
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");
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");
10785 + instr->fail_addr = 0xffffffff;
10787 + /* Grab the lock and see if the device is available */
10788 + nand_get_device (this, mtd, FL_ERASING);
10790 + /* Shift to get first page */
10791 + page = (int) (instr->addr >> this->page_shift);
10792 + chipnr = (int) (instr->addr >> this->chip_shift);
10794 + /* Calculate pages in each block */
10795 + pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
10797 + /* Select the NAND device */
10798 + this->select_chip(mtd, chipnr);
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;
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;
10812 + bbt_masked_page = 0xffffffff; /* should not match anything */
10815 + /* Loop through the pages */
10816 + len = instr->len;
10818 + instr->state = MTD_ERASING;
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 ");
10826 + instr->state = MTD_ERASE_FAILED;
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;
10835 + this->erase_cmd (mtd, page & this->pagemask);
10837 + status = this->waitfunc (mtd, this, FL_ERASING);
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);
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);
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);
10860 + /* Increment page address and decrement length */
10861 + len -= (1 << this->phys_erase_shift);
10862 + page += pages_per_block;
10864 + /* Check, if we cross a chip boundary */
10865 + if (len && !(page & this->pagemask)) {
10867 + this->select_chip(mtd, -1);
10868 + this->select_chip(mtd, chipnr);
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;
10878 + instr->state = MTD_ERASE_DONE;
10882 + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
10884 + /* Do call back function */
10886 + mtd_erase_callback(instr);
10889 + /* Deselect and wake up anyone waiting on the device */
10890 + nand_release_device(mtd);
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]);
10906 + /* Return more or less happy */
10912 + * nand_sync - [MTD Interface] sync
10913 + * @mtd: MTD device structure
10915 + * Sync is actually a wait for chip ready function
10917 +#if 0 /* not needed */
10918 +static void nand_sync (struct mtd_info *mtd)
10920 + struct nand_chip *this = mtd->priv;
10922 + DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
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);
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
10937 +static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
10939 + /* Check for invalid offset */
10940 + if (ofs > mtd->size)
10943 + return nand_block_checkbad (mtd, ofs, 1, 0);
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
10951 +#if NAND_WRITE_SUPPORT
10952 +static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
10954 + struct nand_chip *this = mtd->priv;
10957 + if ((ret = nand_block_isbad(mtd, ofs))) {
10958 + /* If it was bad already, return success and do nothing. */
10964 + return this->block_markbad(mtd, ofs);
10969 + * nand_suspend - [MTD Interface] Suspend the NAND flash
10970 + * @mtd: MTD device structure
10972 +#if 0 /* don't need it */
10973 +static int nand_suspend(struct mtd_info *mtd)
10975 + struct nand_chip *this = mtd->priv;
10977 + return nand_get_device (this, mtd, FL_PM_SUSPENDED);
10982 + * nand_resume - [MTD Interface] Resume the NAND flash
10983 + * @mtd: MTD device structure
10985 +#if 0 /* don't need it */
10986 +static void nand_resume(struct mtd_info *mtd)
10988 + struct nand_chip *this = mtd->priv;
10990 + if (this->state == FL_PM_SUSPENDED)
10991 + nand_release_device(mtd);
10993 + puts("resume() called for the chip which is not in suspended state\n");
11000 + * nand_scan - [NAND Interface] Scan for the NAND device
11001 + * @mtd: MTD device structure
11002 + * @maxchips: Number of chips to scan for
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
11011 +int nand_scan (struct mtd_info *mtd, int maxchips)
11013 + int i, nand_maf_id, nand_dev_id, busw, maf_id;
11014 + struct nand_chip *this = mtd->priv;
11016 + /* Get buswidth to select the correct functions*/
11017 + busw = this->options & NAND_BUSWIDTH_16;
11019 + /* check for proper chip_delay setup, set 20us if not */
11020 + if (!this->chip_delay)
11021 + this->chip_delay = 20;
11023 + /* check, if a user supplied command function given */
11024 + if (this->cmdfunc == NULL)
11025 + this->cmdfunc = nand_command;
11027 + /* check, if a user supplied wait function given */
11028 + if (this->waitfunc == NULL)
11029 + this->waitfunc = nand_wait;
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;
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;
11058 + /* Select the device */
11059 + this->select_chip(mtd, 0);
11061 + /* Send the command for reading device ID */
11062 + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11064 + /* Read manufacturer and device IDs */
11065 + nand_maf_id = this->read_byte(mtd);
11066 + nand_dev_id = this->read_byte(mtd);
11068 + /* Print and store flash device information */
11069 + for (i = 0; nand_flash_ids[i].name != NULL; i++) {
11071 + if (nand_dev_id != nand_flash_ids[i].id)
11074 + if (!mtd->name) mtd->name = nand_flash_ids[i].name;
11075 + this->chipsize = nand_flash_ids[i].chipsize << 20;
11077 + /* New devices have all the information in additional id bytes */
11078 + if (!nand_flash_ids[i].pagesize) {
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);
11087 + /* Calc oobsize */
11088 + mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
11090 + /* Calc blocksize. Blocksize is multiples of 64KiB */
11091 + mtd->erasesize = (64 * 1024) << (extid & 0x03);
11093 + /* Get buswidth information */
11094 + busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
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;
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)
11111 + /* Check, if buswidth is correct. Hardware drivers should set
11112 + * this correct ! */
11113 + if (busw != (this->options & NAND_BUSWIDTH_16)) {
11115 + puts ("Manufacturer ID: ");
11116 + putx (nand_maf_id);
11117 + puts (", Chip ID: ");
11118 + putx (nand_dev_id);
11120 + puts (nand_manuf_ids[maf_id].name);
11122 + puts (mtd->name);
11125 + puts ("Expected NAND bus width ");
11126 + putx ((this->options & NAND_BUSWIDTH_16) ? 16 : 8);
11127 + puts (",found ");
11128 + putx (busw ? 16 : 8);
11130 + this->select_chip(mtd, -1);
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;
11139 + /* Set the bad block position */
11140 + this->badblockpos = mtd->oobblock > 512 ?
11141 + NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
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.
11151 + if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
11152 + this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
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;
11159 + this->erase_cmd = single_erase_cmd;
11162 + /* Do not replace user supplied command function ! */
11163 + if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
11164 + this->cmdfunc = nand_command_lp;
11166 + puts ("Manufacturer ID / Chip ID: ");
11167 + putx (nand_maf_id << 8 | nand_dev_id);
11169 + puts (nand_manuf_ids[maf_id].name);
11171 + puts (nand_flash_ids[i].name);
11176 + if (!nand_flash_ids[i].name) {
11177 + puts ("No NAND device found!!!\r\n");
11178 + this->select_chip(mtd, -1);
11182 +#if NAND_MULTICHIP_SUPPORT
11183 + for (i=1; i < maxchips; i++) {
11184 + this->select_chip(mtd, i);
11186 + /* Send the command for reading device ID */
11187 + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11189 + /* Read manufacturer and device IDs */
11190 + if (nand_maf_id != this->read_byte(mtd) ||
11191 + nand_dev_id != this->read_byte(mtd))
11196 + puts (" NAND chips detected\r\n");
11200 + /* Allocate buffers, if neccecary */
11201 + if (!this->oob_buf) {
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");
11209 + this->options |= NAND_OOBBUF_ALLOC;
11212 + if (!this->data_buf) {
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");
11222 + this->options |= NAND_DATABUF_ALLOC;
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;
11230 + /* Store the number of chips and calc total size for mtd */
11231 + this->numchips = 1;
11232 + mtd->size = this->chipsize;
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));
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) {
11247 + this->autooob = &nand_oob_8;
11250 + this->autooob = &nand_oob_16;
11253 + this->autooob = &nand_oob_64;
11256 + puts ("No oob scheme defined for oobsize ");
11257 + putx (mtd->oobsize);
11263 + /* The number of bytes available for the filesystem to place fs dependend
11265 + mtd->oobavail = 0;
11266 + for (i = 0; this->autooob->oobfree[i][1]; i++)
11267 + mtd->oobavail += this->autooob->oobfree[i][1];
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
11274 + this->eccsize = 256; /* set default eccsize */
11275 + this->eccbytes = 3;
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;
11288 + this->eccsize = 2048;
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;
11300 + this->eccsize = 512; /* set eccsize to 512 */
11303 + case NAND_ECC_HW3_256:
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;
11312 + case NAND_ECC_SOFT:
11313 + this->calculate_ecc = nand_calculate_ecc;
11314 + this->correct_data = nand_correct_data;
11318 + puts ("Invalid NAND_ECC_MODE ");
11319 + putx (this->eccmode);
11324 + /* Check hardware ecc function availability and adjust number of ecc bytes per
11325 + * calculation step
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)
11338 + puts ("No ECC functions supplied, Hardware ECC not possible\r\n");
11342 + mtd->eccsize = this->eccsize;
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;
11349 + case NAND_ECC_HW3_512:
11350 + case NAND_ECC_HW6_512:
11351 + case NAND_ECC_HW8_512:
11352 + this->eccsteps = mtd->oobblock / 512;
11354 + case NAND_ECC_HW3_256:
11355 + case NAND_ECC_SOFT:
11356 + this->eccsteps = mtd->oobblock / 256;
11359 + case NAND_ECC_NONE:
11360 + this->eccsteps = 1;
11364 + /* Initialize state, waitqueue and spinlock */
11365 + this->state = FL_READY;
11367 + init_waitqueue_head (&this->wq);
11368 + spin_lock_init (&this->chip_lock);
11371 + /* De-select the device */
11372 + this->select_chip(mtd, -1);
11374 + /* Invalidate the pagebuffer reference */
11375 + this->pagebuf = -1;
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;
11384 +#if 0 /* not needed */
11385 + mtd->point = NULL;
11386 + mtd->unpoint = NULL;
11388 + mtd->read = nand_read;
11389 +#if NAND_WRITE_SUPPORT
11390 + mtd->write = nand_write;
11392 + mtd->read_ecc = nand_read_ecc;
11393 +#if NAND_WRITE_SUPPORT
11394 + mtd->write_ecc = nand_write_ecc;
11396 + mtd->read_oob = nand_read_oob;
11397 +#if NAND_WRITE_SUPPORT
11398 + mtd->write_oob = nand_write_oob;
11400 +#if NAND_KVEC_SUPPORT
11401 + mtd->readv = NULL;
11403 +#if NAND_WRITE_SUPPORT && NAND_KVEC_SUPPORT
11404 + mtd->writev = nand_writev;
11405 + mtd->writev_ecc = nand_writev_ecc;
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;
11414 + mtd->block_isbad = nand_block_isbad;
11415 +#if NAND_WRITE_SUPPORT
11416 + mtd->block_markbad = nand_block_markbad;
11419 + /* and make the autooob the default one */
11420 + memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
11422 +#ifdef THIS_MODULE /* normally isn't for us */
11423 + mtd->owner = THIS_MODULE;
11426 + /* Check, if we should skip the bad block table scan */
11427 + if (this->options & NAND_SKIP_BBTSCAN)
11430 +#if NAND_BBT_SUPPORT
11431 + /* Build bad block table */
11432 + return this->scan_bbt (mtd);
11439 + * nand_release - [NAND Interface] Free resources held by the NAND device
11440 + * @mtd: MTD device structure
11442 +#if 0 /* don't need it */
11443 +void nand_release (struct mtd_info *mtd)
11445 + struct nand_chip *this = mtd->priv;
11448 +#ifdef CONFIG_MTD_PARTITIONS
11449 + /* Deregister partitions */
11450 + del_mtd_partitions (mtd);
11452 + /* Deregister the device */
11453 + del_mtd_device (mtd);
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);
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
11471 + * drivers/mtd/nand_bbt.c
11474 + * Bad block table support for the NAND driver
11476 + * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
11478 + * $Id: nand_bbt.c,v 1.5 2006/11/10 08:55:58 ricardw Exp $
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.
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.
11497 + * For manufacturer created bbts like the one found on M-SYS DOC devices
11498 + * the bbt is searched and read but never created
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.
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
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
11516 + * Multichip devices like DOC store the bad block info per floor.
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
11525 +#include <linux/slab.h>
11528 +#include <linux/types.h>
11531 +#include "nand_ecc.h"
11534 +#include <linux/mtd/compatmac.h>
11535 +#include <linux/bitops.h>
11538 +#include <linux/delay.h>
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
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
11556 +static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
11559 + uint8_t *p = buf;
11561 + end = paglen + td->offs;
11562 + if (td->options & NAND_BBT_SCANEMPTY) {
11563 + for (i = 0; i < end; i++) {
11564 + if (p[i] != 0xff)
11570 + /* Compare the pattern */
11571 + for (i = 0; i < td->len; i++) {
11572 + if (p[i] != td->pattern[i])
11576 + if (td->options & NAND_BBT_SCANEMPTY) {
11579 + for (i = end; i < len; i++) {
11580 + if (*p++ != 0xff)
11588 + * check_short_pattern - [GENERIC] check if a pattern is in the buffer
11589 + * @buf: the buffer to search
11590 + * @td: search pattern descriptor
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
11597 +static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
11600 + uint8_t *p = buf;
11602 + /* Compare the pattern */
11603 + for (i = 0; i < td->len; i++) {
11604 + if (p[td->offs + i] != td->pattern[i])
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
11620 + * Read the bad block table starting from page.
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)
11626 + int res, i, j, act = 0;
11627 + struct nand_chip *this = mtd->priv;
11628 + size_t retlen, len, totlen;
11630 + uint8_t msk = (uint8_t) ((1 << bits) - 1);
11632 + totlen = (num * bits) >> 3;
11633 + from = ((loff_t)page) << this->page_shift;
11636 + len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
11637 + res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
11639 + if (retlen != len) {
11640 + puts ("nand_bbt: Error reading bad block table\n");
11643 + puts ("nand_bbt: ECC error while reading bad block table\n");
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;
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);
11658 + this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
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);
11666 + /* Factory marked bad or worn out ? */
11668 + this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
11670 + this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
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
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.
11690 +static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
11692 + struct nand_chip *this = mtd->priv;
11696 + bits = td->options & NAND_BBT_NRBITS_MSK;
11697 + if (td->options & NAND_BBT_PERCHIP) {
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);
11704 + offs += this->chipsize >> (this->bbt_erase_shift + 2);
11707 + res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
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
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.
11725 +static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
11726 + struct nand_bbt_descr *md)
11728 + struct nand_chip *this = mtd->priv;
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]);
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]);
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
11763 + * Create a bad block table by scanning the device
11764 + * for the given good/bad block identify pattern
11766 +static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
11768 + struct nand_chip *this = mtd->priv;
11769 + int i, j, numblocks, len, scanlen;
11772 + size_t readlen, ooblen;
11774 + puts ("Scanning device for bad blocks\n");
11776 + if (bd->options & NAND_BBT_SCANALLPAGES)
11777 + len = 1 << (this->bbt_erase_shift - this->page_shift);
11779 + if (bd->options & NAND_BBT_SCAN2NDPAGE)
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;
11790 + /* Full page content should be read */
11791 + scanlen = mtd->oobblock + mtd->oobsize;
11792 + readlen = len * mtd->oobblock;
11793 + ooblen = len * mtd->oobsize;
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);
11803 + if (chip >= this->numchips) {
11804 + puts ("create_bbt(): chipnr (");
11806 + puts (" > available chips ");
11807 + putx (this->numchips);
11811 + numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
11812 + startblock = chip * numblocks;
11813 + numblocks += startblock;
11814 + from = startblock << (this->bbt_erase_shift - 1);
11817 + for (i = startblock; i < numblocks;) {
11820 + if (bd->options & NAND_BBT_SCANEMPTY)
11821 + if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
11824 + for (j = 0; j < len; j++) {
11825 + if (!(bd->options & NAND_BBT_SCANEMPTY)) {
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);
11835 + if (check_short_pattern (buf, bd)) {
11836 + this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11837 + puts ("Bad eraseblock ");
11840 + putx ((unsigned int) from);
11845 + if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
11846 + this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11847 + puts ("Bad eraseblock ");
11850 + putx ((unsigned int) from);
11857 + from += (1 << this->bbt_erase_shift);
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
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
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.
11876 + * The bbt ident pattern resides in the oob area of the first page
11879 +static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
11881 + struct nand_chip *this = mtd->priv;
11883 + int bits, startblock, block, dir;
11884 + int scanlen = mtd->oobblock + mtd->oobsize;
11887 + /* Search direction top -> down ? */
11888 + if (td->options & NAND_BBT_LASTBLOCK) {
11889 + startblock = (mtd->size >> this->bbt_erase_shift) -1;
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;
11903 + bbtblocks = mtd->size >> this->bbt_erase_shift;
11906 + /* Number of bits for each erase block in the bbt */
11907 + bits = td->options & NAND_BBT_NRBITS_MSK;
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];
11926 + startblock += this->chipsize >> this->bbt_erase_shift;
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 ");
11935 + puts ("Bad block table found at page ");
11936 + putx (td->pages[i]);
11937 + puts (" version ");
11938 + putx (td->version[i]);
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
11952 + * Search and read the bad block table(s)
11954 +static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
11955 + struct nand_bbt_descr *td, struct nand_bbt_descr *md)
11957 + /* Search the primary table */
11958 + search_bbt (mtd, buf, td);
11960 + /* Search the mirror table */
11962 + search_bbt (mtd, buf, md);
11964 + /* Force result check */
11970 + * write_bbt - [GENERIC] (Re)write the bad block table
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
11978 + * (Re)write the bad block table
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)
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;
11991 + uint8_t rcode = td->reserved_block_code;
11992 + size_t retlen, len = 0;
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;
12004 + nrchips = chipsel + 1;
12008 + numblocks = (int) (mtd->size >> this->bbt_erase_shift);
12012 + /* Loop through the chips */
12013 + for (; chip < nrchips; chip++) {
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.
12019 + if (td->pages[chip] != -1) {
12020 + page = td->pages[chip];
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;
12030 + startblock = chip * numblocks;
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) {
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)
12047 + puts ("No space left to write bad block table\r\n");
12051 + /* Set up shift count and masks for the flash table */
12052 + bits = td->options & NAND_BBT_NRBITS_MSK;
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;
12061 + bbtoffs = chip * (numblocks >> 2);
12063 + to = ((loff_t) page) << this->page_shift;
12065 + memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
12066 + oobinfo.useecc = MTD_NANDECC_PLACEONLY;
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);
12075 + if (retlen != len) {
12076 + puts ("nand_bbt: Error reading block for writing the bad block table\r\n");
12079 + puts ("nand_bbt: ECC error while reading block for writing bad block table\r\n");
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];
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);
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];
12107 + /* walk through the memory table */
12108 + for (i = 0; i < numblocks; ) {
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);
12119 + memset (&einfo, 0, sizeof (einfo));
12121 + einfo.addr = (unsigned long) to;
12122 + einfo.len = 1 << this->bbt_erase_shift;
12123 + res = nand_erase_nand (mtd, &einfo, 1);
12125 + puts ("nand_bbt: Error during block erase: ");
12131 + res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
12133 + puts ("nand_bbt: Error while writing bad block table ");
12138 + puts ("Bad block table written to ");
12139 + putx ((unsigned int) to);
12140 + puts (", version ");
12141 + putx (td->version[chip]);
12144 + /* Mark it as used */
12145 + td->pages[chip] = page;
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
12155 + * The function creates a memory based bbt by scanning the device
12156 + * for manufacturer / software marked good / bad blocks
12158 +static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12160 + struct nand_chip *this = mtd->priv;
12162 + bd->options &= ~NAND_BBT_SCANEMPTY;
12163 + return create_bbt (mtd, this->data_buf, bd, -1);
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
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
12178 +static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
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;
12186 + /* Do we have a bbt per chip ? */
12187 + if (td->options & NAND_BBT_PERCHIP)
12188 + chips = this->numchips;
12192 + for (i = 0; i < chips; i++) {
12196 + /* Per chip or per device ? */
12197 + chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
12198 + /* Mirrored table avilable ? */
12200 + if (td->pages[i] == -1 && md->pages[i] == -1) {
12205 + if (td->pages[i] == -1) {
12207 + td->version[i] = md->version[i];
12212 + if (md->pages[i] == -1) {
12214 + md->version[i] = td->version[i];
12219 + if (td->version[i] == md->version[i]) {
12221 + if (!(td->options & NAND_BBT_VERSION))
12226 + if (((int8_t) (td->version[i] - md->version[i])) > 0) {
12228 + md->version[i] = td->version[i];
12232 + td->version[i] = md->version[i];
12239 + if (td->pages[i] == -1) {
12247 + /* Create the bad block table by scanning the device ? */
12248 + if (!(td->options & NAND_BBT_CREATE))
12251 + /* Create the table in memory by scanning the chip(s) */
12252 + create_bbt (mtd, buf, bd, chipsel);
12254 + td->version[i] = 1;
12256 + md->version[i] = 1;
12258 + /* read back first ? */
12260 + read_abs_bbt (mtd, buf, rd, chipsel);
12261 + /* If they weren't versioned, read both. */
12263 + read_abs_bbt (mtd, buf, rd2, chipsel);
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);
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);
12283 + * mark_bbt_regions - [GENERIC] mark the bad block table regions
12284 + * @mtd: MTD device structure
12285 + * @td: bad block table descriptor
12287 + * The bad block table regions are marked as "bad" to prevent
12288 + * accidental erasures / writes. The regions are identified by
12291 +static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
12293 + struct nand_chip *this = mtd->priv;
12294 + int i, j, chips, block, nrblocks, update;
12295 + uint8_t oldval, newval;
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);
12303 + nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
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);
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));
12320 + if (td->options & NAND_BBT_LASTBLOCK)
12321 + block = ((i + 1) * nrblocks) - td->maxblocks;
12323 + block = i * nrblocks;
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;
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));
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
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.
12350 + * The bad block table memory is allocated here. It must be freed
12351 + * by calling the nand_free_bbt function.
12354 +int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12356 + struct nand_chip *this = mtd->priv;
12357 + int len, res = 0;
12359 + struct nand_bbt_descr *td = this->bbt_td;
12360 + struct nand_bbt_descr *md = this->bbt_md;
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");
12369 + /* Clear the memory bad block table */
12370 + memset (this->bbt, 0x00, len);
12372 + /* If no primary table decriptor is given, scan the device
12373 + * to build a memory based bad block table
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;
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);
12389 + puts ("nand_bbt: Out of memory\r\n");
12390 + free (this->bbt);
12391 + this->bbt = NULL;
12395 + /* Is the bbt at a given page ? */
12396 + if (td->options & NAND_BBT_ABSPAGE) {
12397 + res = read_abs_bbts (mtd, buf, td, md);
12399 + /* Search the bad block table using a pattern in oob */
12400 + res = search_read_bbts (mtd, buf, td, md);
12404 + res = check_create (mtd, buf, bd);
12406 + /* Prevent the bbt regions from erasing / writing */
12407 + mark_bbt_region (mtd, td);
12409 + mark_bbt_region (mtd, md);
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
12421 + * The function updates the bad block table(s)
12423 +int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
12425 + struct nand_chip *this = mtd->priv;
12426 + int len, res = 0, writeops = 0;
12427 + int chip, chipsel;
12429 + struct nand_bbt_descr *td = this->bbt_td;
12430 + struct nand_bbt_descr *md = this->bbt_md;
12432 + if (!this->bbt || !td)
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);
12441 + puts ("nand_update_bbt: Out of memory\r\n");
12445 + writeops = md != NULL ? 0x03 : 0x01;
12447 + /* Do we have a bbt per chip ? */
12448 + if (td->options & NAND_BBT_PERCHIP) {
12449 + chip = (int) (offs >> this->chip_shift);
12456 + td->version[chip]++;
12458 + md->version[chip]++;
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);
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);
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 };
12480 +static struct nand_bbt_descr smallpage_memorybased = {
12481 + .options = NAND_BBT_SCAN2NDPAGE,
12484 + .pattern = scan_ff_pattern
12487 +static struct nand_bbt_descr largepage_memorybased = {
12491 + .pattern = scan_ff_pattern
12494 +static struct nand_bbt_descr smallpage_flashbased = {
12495 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12498 + .pattern = scan_ff_pattern
12501 +static struct nand_bbt_descr largepage_flashbased = {
12502 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12505 + .pattern = scan_ff_pattern
12508 +static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
12510 +static struct nand_bbt_descr agand_flashbased = {
12511 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12514 + .pattern = scan_agand_pattern
12517 +/* Generic flash bbt decriptors
12519 +static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
12520 +static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
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,
12529 + .pattern = bbt_pattern
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,
12539 + .pattern = mirror_pattern
12543 + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
12544 + * @mtd: MTD device structure
12546 + * This function selects the default bad block table
12547 + * support for the device and calls the nand_scan_bbt function
12550 +int nand_default_bbt (struct mtd_info *mtd)
12552 + struct nand_chip *this = mtd->priv;
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
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;
12567 + this->options |= NAND_USE_FLASH_BBT;
12568 + return nand_scan_bbt (mtd, &agand_flashbased);
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;
12579 + if (!this->badblock_pattern) {
12580 + this->badblock_pattern = (mtd->oobblock > 512) ?
12581 + &largepage_flashbased : &smallpage_flashbased;
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;
12591 + return nand_scan_bbt (mtd, this->badblock_pattern);
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
12601 +int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
12603 + struct nand_chip *this = mtd->priv;
12607 + /* Get block number * 2 */
12608 + block = (int) (offs >> (this->bbt_erase_shift - 1));
12609 + res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
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);
12614 + switch ((int)res) {
12615 + case 0x00: return 0;
12616 + case 0x01: return 1;
12617 + case 0x02: return allowbbt ? 0 : 1;
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
12626 + * This file contains an ECC algorithm from Toshiba that detects and
12627 + * corrects 1 bit errors in a 256 byte block of data.
12629 + * Taken from drivers/mtd/nand/nand_ecc.c, modified for
12630 + * NAND flash boot on Etrax FS.
12632 + * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
12633 + * Toshiba America Electronics Components, Inc.
12635 + * $Id: nand_ecc.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
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
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.
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.
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.
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.
12663 +#include <linux/types.h>
12665 +#include <linux/kernel.h>
12666 +#include <linux/module.h>
12668 +#include "nand_ecc.h"
12671 + * Pre-calculated 256-way 1 byte column parity
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
12694 + * nand_trans_result - [GENERIC] create non-inverted ECC
12695 + * @reg2: line parity reg 2
12696 + * @reg3: line parity reg 3
12699 + * Creates non-inverted ECC code from line parity
12701 +static void nand_trans_result(u_char reg2, u_char reg3,
12702 + u_char *ecc_code)
12704 + u_char a, b, i, tmp1, tmp2;
12706 + /* Initialize variables */
12710 + /* Calculate first ECC byte */
12711 + for (i = 0; i < 4; i++) {
12712 + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
12715 + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
12721 + /* Calculate second ECC byte */
12723 + for (i = 0; i < 4; i++) {
12724 + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
12727 + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
12733 + /* Store two of the ECC bytes */
12734 + ecc_code[0] = tmp1;
12735 + ecc_code[1] = tmp2;
12739 + * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block
12740 + * @mtd: MTD block structure
12742 + * @ecc_code: buffer for ECC
12744 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
12746 + u_char idx, reg1, reg2, reg3;
12749 + /* Initialize variables */
12750 + reg1 = reg2 = reg3 = 0;
12751 + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
12753 + /* Build up column parity */
12754 + for(j = 0; j < 256; j++) {
12756 + /* Get CP0 - CP5 from table */
12757 + idx = nand_ecc_precalc_table[dat[j]];
12758 + reg1 ^= (idx & 0x3f);
12760 + /* All bit XOR = 1 ? */
12761 + if (idx & 0x40) {
12762 + reg3 ^= (u_char) j;
12763 + reg2 ^= ~((u_char) j);
12767 + /* Create non-inverted ECC code from line parity */
12768 + nand_trans_result(reg2, reg3, ecc_code);
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;
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
12784 + * Detect and correct a 1 bit error for 256 byte block
12786 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
12788 + u_char a, b, c, d1, d2, d3, add, bit, i;
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];
12795 + if ((d1 | d2 | d3) == 0) {
12800 + a = (d1 ^ (d1 >> 1)) & 0x55;
12801 + b = (d2 ^ (d2 >> 1)) & 0x55;
12802 + c = (d3 ^ (d3 >> 1)) & 0x54;
12804 + /* Found and will correct single bit error in the data */
12805 + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
12809 + for (i=0; i<4; i++) {
12816 + for (i=0; i<4; i++) {
12825 + for (i=0; i<3; i++) {
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];
12862 + /* Uncorrectable Error */
12868 + /* Should never happen */
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
12876 + * drivers/mtd/nand_ecc.h
12878 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
12880 + * $Id: nand_ecc.h,v 1.1 2006/08/04 14:38:14 ricardw Exp $
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.
12886 + * This file is the header for the ECC algorithm.
12889 +#ifndef __MTD_NAND_ECC_H__
12890 +#define __MTD_NAND_ECC_H__
12895 + * Calculate 3 byte ECC code for 256 byte block
12897 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
12900 + * Detect and correct a 1 bit error for 256 byte block
12902 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
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
12910 + * drivers/mtd/nandids.c
12912 + * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
12914 + * $Id: nand_ids.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
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.
12922 +#include <linux/module.h>
12929 +* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
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
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},
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},
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},
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},
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},
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},
12977 + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
12979 + /* These are the new chips with large page size. The pagesize
12980 + * and the erasesize is determined from the extended id bytes
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},
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},
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},
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},
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},
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},
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
13024 + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
13030 +* Manufacturer ID list
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"},
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
13047 +/*#OUTPUT_FORMAT(elf32-us-cris) */
13048 +OUTPUT_ARCH (crisv32)
13052 - flash : ORIGIN = 0x00000000,
13053 - LENGTH = 0x00100000
13054 + bootblk : ORIGIN = 0x38000000,
13055 + LENGTH = 0x00004000
13056 + intmem : ORIGIN = 0x38004000,
13057 + LENGTH = 0x00005000
13084 + _end = ALIGN( 0x10 ) ;
13087 + /* Get rid of stuff from EXPORT_SYMBOL(foo). */
13090 + *(__ksymtab_strings)
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
13098 This option enables the ETRAX FS built-in 10/100Mbit Ethernet
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
13107 - Hardware acceleration of checksumming and scatter/gather
13109 config ETRAX_ETHERNET_IFACE0
13110 depends on ETRAX_ETHERNET
13111 bool "Enable network interface 0"
13113 bool "Enable network interface 1 (uses DMA6 and DMA7)"
13116 + prompt "Eth0 led group"
13117 + depends on ETRAX_ETHERNET_IFACE0
13118 + default ETRAX_ETH0_USE_LEDGRP0
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
13124 + Use LED grp 0 for eth0
13126 +config ETRAX_ETH0_USE_LEDGRP1
13127 + bool "Use LED grp 1"
13128 + depends on ETRAX_NBR_LED_GRP_TWO
13130 + Use LED grp 1 for eth0
13132 +config ETRAX_ETH0_USE_LEDGRPNULL
13133 + bool "Use no LEDs for eth0"
13135 + Use no LEDs for eth0
13139 + prompt "Eth1 led group"
13140 + depends on ETRAX_ETHERNET_IFACE1
13141 + default ETRAX_ETH1_USE_LEDGRP1
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
13147 + Use LED grp 0 for eth1
13149 +config ETRAX_ETH1_USE_LEDGRP1
13150 + bool "Use LED grp 1"
13151 + depends on ETRAX_NBR_LED_GRP_TWO
13153 + Use LED grp 1 for eth1
13155 +config ETRAX_ETH1_USE_LEDGRPNULL
13156 + bool "Use no LEDs for eth1"
13158 + Use no LEDs for eth1
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
13172 Enables the ETRAX FS serial driver for ser0 (ttyS0)
13173 You probably want this enabled.
13175 +config ETRAX_RS485
13176 + bool "RS-485 support"
13177 + depends on ETRAXFS_SERIAL
13179 + Enables support for RS-485 serial communication.
13181 +config ETRAX_RS485_DISABLE_RECEIVER
13182 + bool "Disable serial receiver"
13183 + depends on ETRAX_RS485
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.
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.
13195 + prompt "Ser0 default port type "
13196 + depends on ETRAX_SERIAL_PORT0
13197 + default ETRAX_SERIAL_PORT0_TYPE_232
13199 + Type of serial port.
13201 +config ETRAX_SERIAL_PORT0_TYPE_232
13202 + bool "Ser0 is a RS-232 port"
13204 + Configure serial port 0 to be a RS-232 port.
13206 +config ETRAX_SERIAL_PORT0_TYPE_485HD
13207 + bool "Ser0 is a half duplex RS-485 port"
13208 + depends on ETRAX_RS485
13210 + Configure serial port 0 to be a half duplex (two wires) RS-485 port.
13212 +config ETRAX_SERIAL_PORT0_TYPE_485FD
13213 + bool "Ser0 is a full duplex RS-485 port"
13214 + depends on ETRAX_RS485
13216 + Configure serial port 0 to be a full duplex (four wires) RS-485 port.
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).
13227 + prompt "Ser1 default port type"
13228 + depends on ETRAX_SERIAL_PORT1
13229 + default ETRAX_SERIAL_PORT1_TYPE_232
13231 + Type of serial port.
13233 +config ETRAX_SERIAL_PORT1_TYPE_232
13234 + bool "Ser1 is a RS-232 port"
13236 + Configure serial port 1 to be a RS-232 port.
13238 +config ETRAX_SERIAL_PORT1_TYPE_485HD
13239 + bool "Ser1 is a half duplex RS-485 port"
13240 + depends on ETRAX_RS485
13242 + Configure serial port 1 to be a half duplex (two wires) RS-485 port.
13244 +config ETRAX_SERIAL_PORT1_TYPE_485FD
13245 + bool "Ser1 is a full duplex RS-485 port"
13246 + depends on ETRAX_RS485
13248 + Configure serial port 1 to be a full duplex (four wires) RS-485 port.
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).
13259 + prompt "Ser2 default port type"
13260 + depends on ETRAX_SERIAL_PORT2
13261 + default ETRAX_SERIAL_PORT2_TYPE_232
13263 + What DMA channel to use for ser2
13265 +config ETRAX_SERIAL_PORT2_TYPE_232
13266 + bool "Ser2 is a RS-232 port"
13268 + Configure serial port 2 to be a RS-232 port.
13270 +config ETRAX_SERIAL_PORT2_TYPE_485HD
13271 + bool "Ser2 is a half duplex RS-485 port"
13272 + depends on ETRAX_RS485
13274 + Configure serial port 2 to be a half duplex (two wires) RS-485 port.
13276 +config ETRAX_SERIAL_PORT2_TYPE_485FD
13277 + bool "Ser2 is a full duplex RS-485 port"
13278 + depends on ETRAX_RS485
13280 + Configure serial port 2 to be a full duplex (four wires) RS-485 port.
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).
13291 + prompt "Ser3 default port type"
13292 + depends on ETRAX_SERIAL_PORT3
13293 + default ETRAX_SERIAL_PORT3_TYPE_232
13295 + What DMA channel to use for ser3.
13297 +config ETRAX_SERIAL_PORT3_TYPE_232
13298 + bool "Ser3 is a RS-232 port"
13300 + Configure serial port 3 to be a RS-232 port.
13302 +config ETRAX_SERIAL_PORT3_TYPE_485HD
13303 + bool "Ser3 is a half duplex RS-485 port"
13304 + depends on ETRAX_RS485
13306 + Configure serial port 3 to be a half duplex (two wires) RS-485 port.
13308 +config ETRAX_SERIAL_PORT3_TYPE_485FD
13309 + bool "Ser3 is a full duplex RS-485 port"
13310 + depends on ETRAX_RS485
13312 + Configure serial port 3 to be a full duplex (four wires) RS-485 port.
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
13323 -config ETRAX_RS485
13324 - bool "RS-485 support"
13325 - depends on ETRAX_SERIAL
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>.
13330 -config ETRAX_RS485_DISABLE_RECEIVER
13331 - bool "Disable serial receiver"
13332 - depends on ETRAX_RS485
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.
13338 -config ETRAX_AXISFLASHMAP
13339 - bool "Axis flash-map support"
13340 - depends on ETRAX_ARCH_V32
13343 - select MTD_CFI_AMDSTD
13344 - select MTD_OBSOLETE_CHIPS
13345 - select MTD_AMDSTD
13348 - select MTD_PARTITIONS
13349 - select MTD_CONCAT
13350 - select MTD_COMPLEX_MAPPINGS
13352 - This option enables MTD mapping of flash devices. Needed to use
13353 - flash memories. If unsure, say Y.
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.
13362 +config ETRAX_AXISFLASHMAP
13363 + bool "Axis flash-map support"
13364 + depends on ETRAX_ARCH_V32
13367 + select MTD_CFI_AMDSTD
13368 + select MTD_JEDECPROBE
13371 + select MTD_PARTITIONS
13372 + select MTD_CONCAT
13373 + select MTD_COMPLEX_MAPPINGS
13375 + This option enables MTD mapping of flash devices. Needed to use
13376 + flash memories. If unsure, say Y.
13378 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
13379 + bool "MTD0 is whole boot flash device"
13380 + depends on ETRAX_AXISFLASHMAP
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.
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.
13394 +config ETRAX_NANDBOOT
13395 + bool "Boot from NAND flash"
13396 + depends on ETRAX_NANDFLASH
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.
13404 depends on ETRAX_ARCH_V32
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.
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.
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
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
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.
13432 +config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
13433 + int "Virtual GPIO interrupt pin on PA pin"
13435 + depends on ETRAX_VIRTUAL_GPIO
13437 + The pin to use on PA for virtual gpio interrupt.
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.
13445 +config ETRAX_PV_CHANGEABLE_DIR
13446 + hex "PV user changeable dir mask"
13447 + depends on ETRAX_VIRTUAL_GPIO
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.
13455 +config ETRAX_PV_CHANGEABLE_BITS
13456 + hex "PV user changeable bits mask"
13457 + depends on ETRAX_VIRTUAL_GPIO
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.
13465 bool "ATA/IDE support"
13466 depends on ETRAX_ARCH_V32
13467 @@ -603,11 +777,11 @@
13469 select PCCARD_NONSTATIC
13471 - Enabled the ETRAX Carbus driver.
13472 + Enabled the ETRAX Carbus driver.
13476 - depends on ETRAX_CARDBUS
13477 + depends on ETRAX_CARDBUS
13480 config ETRAX_IOP_FW_LOAD
13481 @@ -623,3 +797,175 @@
13483 This option enables a driver for the stream co-processor
13484 for cryptographic operations.
13486 +source drivers/mmc/Kconfig
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.
13497 + select ETRAX_SPI_MMC_BOARD
13499 +# For the parts that can't be a module (due to restrictions in
13500 +# framework elsewhere).
13501 +config ETRAX_SPI_MMC_BOARD
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
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).
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
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.)
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
13533 + Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0.
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
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
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
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.
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
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.)
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
13572 + Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1.
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
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
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
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.
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
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.)
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
13612 + The pin to use for SPI chip select.
13614 +config ETRAX_SPI_CLK_PIN
13615 + string "SPI clock pin"
13616 + depends on ETRAX_SPI_GPIO
13619 + The pin to use for the SPI clock.
13621 +config ETRAX_SPI_DATAIN_PIN
13622 + string "SPI MISO (data in) pin"
13623 + depends on ETRAX_SPI_GPIO
13626 + The pin to use for SPI data in from the device.
13628 +config ETRAX_SPI_DATAOUT_PIN
13629 + string "SPI MOSI (data out) pin"
13630 + depends on ETRAX_SPI_GPIO
13633 + The pin to use for SPI data out to the device.
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
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
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
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.
13653 +# Avoid choices causing non-working configs by conditionalizing the inclusion.
13655 +source drivers/spi/Kconfig
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
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
13669 * partition split defined below.
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.
13678 #include <linux/mtd/mtdram.h>
13679 #include <linux/mtd/partitions.h>
13681 +#include <linux/cramfs_fs.h>
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
13690 +#define PAGESIZE (512)
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
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 */
13707 +struct partition_name {
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
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 */
13726 +#define NUM_DEFAULT_PARTITIONS 3
13727 +#define DEFAULT_ROOTFS_PARTITION_NO (-1)
13728 +#define DEFAULT_MEDIA_SIZE 0x800000 /* 8 megs */
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
13736 -static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13738 - .name = "boot firmware",
13739 - .size = CONFIG_ETRAX_PTABLE_SECTOR,
13743 - .name = "kernel",
13744 - .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
13745 - .offset = CONFIG_ETRAX_PTABLE_SECTOR
13748 - .name = "filesystem",
13749 - .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
13750 - .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
13753 +#if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS)
13754 +#error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS
13757 /* Initialize the ones normally used. */
13758 static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
13759 @@ -178,6 +176,56 @@
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.
13769 +static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13771 + .name = "boot firmware",
13772 + .size = CONFIG_ETRAX_PTABLE_SECTOR,
13776 + .name = "kernel",
13777 + .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13778 + .offset = CONFIG_ETRAX_PTABLE_SECTOR
13780 +#define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR)
13781 +#ifdef CONFIG_ETRAX_NANDBOOT
13783 + .name = "rootfs",
13784 + .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13785 + .offset = FILESYSTEM_SECTOR
13787 +#undef FILESYSTEM_SECTOR
13788 +#define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR)
13792 + .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR,
13793 + .offset = FILESYSTEM_SECTOR
13797 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
13798 +/* Main flash device */
13799 +static struct mtd_partition main_partition = {
13806 +/* Auxilliary partition if we find another flash */
13807 +static struct mtd_partition aux_partition = {
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 @@
13818 struct mtd_info *mtd_cs = NULL;
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);
13825 -#ifdef CONFIG_MTD_AMDSTD
13826 - mtd_cs = do_map_probe("amd_flash", map_cs);
13828 #ifdef CONFIG_MTD_CFI
13829 + mtd_cs = do_map_probe("cfi_probe", map_cs);
13831 +#ifdef CONFIG_MTD_JEDECPROBE
13833 - mtd_cs = do_map_probe("cfi_probe", map_cs);
13834 + mtd_cs = do_map_probe("jedec_probe", map_cs);
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 @@
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];
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;
13862 -#ifdef CONFIG_ETRAX_NANDFLASH
13863 - if ((mtd_nand = crisv32_nand_flash_probe()) != NULL)
13864 - mtds[count++] = mtd_nand;
13867 - if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) {
13868 + if (!mtd_cse0 && !mtd_cse1) {
13869 /* No chip found. */
13872 @@ -248,7 +291,7 @@
13874 mtd_total = mtd_concat_create(mtds,
13876 - "cse0+cse1+nand");
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 @@
13883 /* The best we can do now is to only use what we found
13887 mtd_total = mtd_cse0;
13888 map_destroy(mtd_cse1);
13891 - mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand;
13893 + mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1;
13900 -extern unsigned long crisv32_nand_boot;
13901 -extern unsigned long crisv32_nand_cramfs_offset;
13904 * Probe the flash chip(s) and, if it succeeds, read the partition-table
13905 * and register the partitions with MTD.
13907 static int __init init_axis_flash(void)
13909 - struct mtd_info *mymtd;
13910 + struct mtd_info *main_mtd;
13911 + struct mtd_info *aux_mtd = NULL;
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];
13922 + int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */
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.
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");
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();
13944 + printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n",
13945 + main_mtd->name, main_mtd->size);
13947 +#ifdef CONFIG_ETRAX_NANDFLASH
13948 + aux_mtd = crisv32_nand_flash_probe();
13950 + printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n",
13951 + aux_mtd->name, aux_mtd->size);
13954 +#ifdef CONFIG_ETRAX_NANDBOOT
13956 + struct mtd_info *tmp_mtd;
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;
13964 +#endif /* CONFIG_ETRAX_NANDBOOT */
13965 +#endif /* CONFIG_ETRAX_NANDFLASH */
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.
13971 printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
13973 - printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
13974 - mymtd->name, mymtd->size);
13975 - axisflash_mtd = mymtd;
13979 - mymtd->owner = THIS_MODULE;
13980 +#if 0 /* Dump flash memory so we can see what is going on */
13982 + int sectoraddr, i;
13983 + for (sectoraddr = 0; sectoraddr < 2*65536+4096; sectoraddr += PAGESIZE) {
13984 + main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, page);
13986 + "Sector at %d (length %d):\n",
13987 + sectoraddr, len);
13988 + for (i = 0; i < PAGESIZE; i += 16) {
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);
14007 + main_mtd->owner = THIS_MODULE;
14008 + axisflash_mtd = main_mtd;
14010 + loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR;
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.
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);
14026 + if (ptable_sector) {
14027 + main_mtd->read(main_mtd, ptable_sector, PAGESIZE, &len, page);
14028 + ptable_head = &((struct partitiontable *) page)->head;
14031 +#if 0 /* Dump partition table so we can see what is going on */
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);
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);
14054 - pidx++; /* First partition is always set to the default. */
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.
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;
14069 unsigned long csum = 0;
14072 ptable = (struct partitiontable_entry *)
14073 ((unsigned long)ptable_head + sizeof(*ptable_head));
14075 @@ -343,108 +483,177 @@
14081 ptable_ok = (csum == ptable_head->checksum);
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,
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.
14096 - && ptable->offset != 0xffffffff
14097 + && ptable->offset != PARTITIONTABLE_END_MARKER
14098 && ptable < max_addr
14099 - && pidx < MAX_PARTITIONS) {
14100 + && pidx < MAX_PARTITIONS - 1) {
14102 - axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0);
14103 - axis_partitions[pidx].size = ptable->size;
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) ?
14114 + ((ptable+1)->offset + offset)) -
14115 + (ptable->offset + offset);
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.
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 */
14134 - use_default_ptable = !ptable_ok;
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) */
14142 - axis_partitions[pidx].name = "romfs";
14143 - if (crisv32_nand_boot) {
14144 - char* data = kmalloc(1024, GFP_KERNEL);
14146 - int offset = crisv32_nand_cramfs_offset & ~(1024-1);
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;
14155 - axis_partitions[pidx].size = romfs_length;
14156 - axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
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;
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;
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;
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);
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 */
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 |=
14209 - panic("axisflashmap could not add MTD partitions!\n");
14211 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
14213 + main_partition.size = main_mtd->size;
14214 + err = add_mtd_partitions(main_mtd, &main_partition, 1);
14216 + panic("axisflashmap: Could not initialize "
14217 + "partition for whole main mtd device!\n");
14219 -/* CONFIG_EXTRAXFS_SIM */
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. */
14228 + for (part = 0; part < pidx; part++) {
14229 + if (part == ram_rootfs_partition) {
14230 + /* add MTDRAM partition here */
14231 + struct mtd_info *mtd_ram;
14233 + mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
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);
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);
14253 + err = add_mtd_partitions(main_mtd,
14254 + &partition[part], 1);
14256 + panic("axisflashmap: Could not add mtd "
14257 + "partition %d\n", part);
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");
14267 - struct mtd_info *mtd_ram;
14268 +#endif /* CONFIG_EXTRAXFS_SIM */
14270 - mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14273 - panic("axisflashmap couldn't allocate memory for "
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.
14281 + struct mtd_info *mtd_ram;
14283 + mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14286 + panic("axisflashmap: Couldn't allocate memory for "
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);
14296 + err = mtdram_init_device(mtd_ram, (void*)romfs_start,
14297 + romfs_length, "romfs");
14299 + panic("axisflashmap: Could not initialize MTD RAM "
14302 +#endif /* CONFIG_EXTRAXFS_SIM */
14304 +#ifndef CONFIG_ETRAXFS_SIM
14306 + aux_partition.size = aux_mtd->size;
14307 + err = add_mtd_partitions(aux_mtd, &aux_partition, 1);
14309 + panic("axisflashmap: Could not initialize "
14310 + "aux mtd device!\n");
14312 - err = mtdram_init_device(mtd_ram, (void*)romfs_start,
14313 - romfs_length, "romfs");
14315 - panic("axisflashmap could not initialize MTD RAM "
14320 +#endif /* CONFIG_EXTRAXFS_SIM */
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
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.
14334 + * Copyright (c) 2007 Axis Communications AB
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).
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.
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>
14355 +#include <asm/io.h>
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)
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
14367 +#if !defined(CONFIG_ETRAX_SPI_SSER0) && defined(CONFIG_ETRAX_SPI_SSER0_MODULE)
14368 +#define CONFIG_ETRAX_SPI_SSER0
14371 +#if !defined(CONFIG_ETRAX_SPI_SSER1) && defined(CONFIG_ETRAX_SPI_SSER1_MODULE)
14372 +#define CONFIG_ETRAX_SPI_SSER1
14375 +#if !defined(CONFIG_SPI_ETRAX_GPIO) && defined(CONFIG_SPI_ETRAX_GPIO_MODULE)
14376 +#define CONFIG_SPI_ETRAX_GPIO
14379 +#define CONFIGURED_PIN(x) ((x) != NULL && *(x) != 0 && *(x) != ' ')
14381 +/* Helper function to configure an iopin for input. */
14383 +static int crisv32_config_pin_in(struct crisv32_iopin *pin, const char *name)
14385 + int ret = crisv32_io_get_name(pin, name);
14389 + crisv32_io_set_dir(pin, crisv32_io_dir_in);
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.
14399 +struct crisv32_mmc_spi_pinstate {
14400 + struct crisv32_iopin write_protect_pin;
14401 + struct crisv32_iopin card_detect_pin;
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;
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 *);
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.
14417 + void *detectfunc_param2;
14419 + /* State for the card-detect worker. */
14420 + int card_present;
14423 +/* Rearming "work" function for card-detect polling. */
14425 +static void crisv32_cd_worker(void *x)
14427 + struct crisv32_mmc_spi_pinstate *state = x;
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;
14432 + if (card_present != state->card_present) {
14433 + state->card_present = card_present;
14434 + state->detectfunc(0, state->detectfunc_param2);
14436 + schedule_delayed_work(&state->cd_work, CARD_DETECT_CHECK_INTERVAL);
14439 +/* The parts of MMC-specific configuration common to GPIO and SSER. */
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)
14447 + struct crisv32_mmc_spi_pinstate *ps = pd->pinstate;
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.
14454 + if (CONFIGURED_PIN(pd->card_detect)) {
14455 + ret = crisv32_config_pin_in(&ps->card_detect_pin,
14456 + pd->card_detect);
14459 + goto bad_card_detect;
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);
14468 + ps->detectfunc = NULL;
14471 + * We set up for checking for presence of a write-protect pin
14472 + * as pin.port being non-NULL.
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);
14480 + goto bad_write_protect;
14485 + bad_write_protect:
14486 + if (ps->detectfunc) {
14487 + cancel_rearming_delayed_work(&ps->cd_work);
14488 + ps->detectfunc = NULL;
14495 +/* A function to undo crisv32_mmcspi_config_common. */
14497 +static void crisv32_mmcspi_deconfig_common(const struct
14498 + crisv32_mmc_spi_pindata *pd)
14500 + if (pd->pinstate->detectfunc) {
14501 + cancel_rearming_delayed_work(&pd->pinstate->cd_work);
14502 + pd->pinstate->detectfunc = NULL;
14505 + /* We don't have to undo the pin allocations, being GPIO. */
14508 +/* Helper function for write-protect sense. */
14510 +static int crisv32_mmcspi_get_ro_helper(struct crisv32_mmc_spi_pinstate *ps)
14512 + return ps->write_protect_pin.port != NULL
14513 + && crisv32_io_rd(&ps->write_protect_pin) != 0;
14516 +/* The hardware-interface-specific SPI+MMC parts. */
14518 +#ifdef CONFIG_SPI_ETRAX_SSER
14519 +static const char crisv32_matching_spi_sser_driver_name[] __init_or_module
14520 + = "spi_crisv32_sser";
14523 + * Make up something we can use in tables and function without
14524 + * #ifdef-cluttering.
14526 +#ifdef CONFIG_ETRAX_SPI_SSER0_DMA
14527 +#define WITH_ETRAX_SPI_SSER0_DMA 1
14529 +#define WITH_ETRAX_SPI_SSER0_DMA 0
14531 +#ifdef CONFIG_ETRAX_SPI_SSER1_DMA
14532 +#define WITH_ETRAX_SPI_SSER1_DMA 1
14534 +#define WITH_ETRAX_SPI_SSER1_DMA 0
14537 +/* Write-protect sense for the SSER interface. */
14539 +static int crisv32_mmcspi_sser_get_ro(struct device *dev)
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);
14548 +/* Initialize the MMC-specific parts of the MMC+SPI interface, SSER. */
14550 +static int crisv32_mmcspi_sser_init(struct device *dev,
14551 + irqreturn_t (*intfunc)(int, void *),
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);
14563 + mmc_host->f_max = spidev->max_speed_hz;
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
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
14577 + if (mmc_host->f_min < 1526)
14578 + mmc_host->f_min = 1526;
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)");
14590 +/* Similarly, to undo crisv32_mmcspi_sser_init. */
14592 +static void crisv32_mmcspi_sser_exit(struct device *dev, void *xmmc_host)
14594 + struct spi_device *spidev = to_spi_device(dev);
14595 + struct crisv32_mmc_spi_sser_hwdata *sser_defs
14596 + = spidev->controller_data;
14598 + crisv32_mmcspi_deconfig_common(&sser_defs->mmc);
14602 + * Connect sser and DMA channels and return the proper numbers to use.
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. :-)
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,
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);
14619 + ret = crisv32_pinmux_alloc_fixed(sserno == 0
14620 + ? pinmux_sser0 : pinmux_sser1);
14624 + sserp->regi = regi_sser;
14625 + sserp->irq = sser_irq;
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);
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);
14666 +/* Undo whatever allocations et. al. that crisv32_allocate_sser did. */
14668 +static void crisv32_free_sser(u32 sserno, int 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);
14681 + ret = crisv32_pinmux_dealloc_fixed(sserno == 0
14682 + ? pinmux_sser0 : pinmux_sser1);
14685 + panic("%s: crisv32_pinmux_dealloc_fixed returned %d\n",
14686 + __FUNCTION__, ret);
14689 +/* Convenience-macro to avoid typos causing diffs between sser ports. */
14691 +#define SSER_CDATA(n) \
14694 + .using_dma = WITH_ETRAX_SPI_SSER##n##_DMA, \
14695 + .iface_allocate = crisv32_allocate_sser##n, \
14696 + .iface_free = crisv32_free_sser##n \
14700 + = CONFIG_ETRAX_SPI_MMC_CD_SSER##n##_PIN,\
14702 + = CONFIG_ETRAX_SPI_MMC_WP_SSER##n##_PIN,\
14704 + = &crisv32_mmcspi_sser##n##_pinstate \
14708 +#ifdef CONFIG_ETRAX_SPI_SSER0
14710 +/* Allocate hardware to go with sser0 and fill in the right numbers. */
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)
14716 + return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 0);
14719 +/* Undo those allocations. */
14721 +static void crisv32_free_sser0(void)
14723 + crisv32_free_sser(0, WITH_ETRAX_SPI_SSER0_DMA);
14726 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser0_pinstate;
14727 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser0_cdata
14729 +#endif /* CONFIG_ETRAX_SPI_SSER0 */
14731 +#ifdef CONFIG_ETRAX_SPI_SSER1
14733 +/* Allocate hardware to go with sser0 and fill in the right numbers. */
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)
14739 + return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 1);
14742 +/* Undo those allocations. */
14744 +static void crisv32_free_sser1(void)
14746 + crisv32_free_sser(1, WITH_ETRAX_SPI_SSER1_DMA);
14749 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser1_pinstate;
14750 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser1_cdata
14753 +#endif /* CONFIG_ETRAX_SPI_SSER1 */
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,
14764 +#endif /* CONFIG_SPI_ETRAX_SSER */
14766 +#ifdef CONFIG_SPI_ETRAX_GPIO
14768 +static const char crisv32_matching_spi_gpio_driver_name[] __init_or_module
14769 + = "spi_crisv32_gpio";
14771 +/* Write-protect sense for the GPIO interface. */
14773 +static int crisv32_mmcspi_gpio_get_ro(struct device *dev)
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;
14780 + return crisv32_mmcspi_get_ro_helper(pd->pinstate);
14783 +/* Initialize the MMC-specific parts of the MMC+SPI interface, GPIO. */
14785 +static int crisv32_mmcspi_gpio_init(struct device *dev,
14786 + irqreturn_t (*intfunc)(int, void *),
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);
14798 + mmc_host->f_max = spidev->max_speed_hz;
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.
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)");
14815 +/* Similarly, to undo crisv32_mmcspi_gpio_init. */
14817 +static void crisv32_mmcspi_gpio_exit(struct device *dev, void *xmmc_host)
14819 + struct spi_device *spidev = to_spi_device(dev);
14820 + struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14821 + = spidev->controller_data;
14823 + crisv32_mmcspi_deconfig_common(&gpio_defs->mmc);
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,
14835 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_gpio_pinstate;
14836 +static const struct crisv32_mmc_spi_gpio_hwdata crisv32_mmcspi_gpio_cdata = {
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
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
14849 +#endif /* CONFIG_SPI_ETRAX_GPIO */
14851 +struct crisv32_s_b_i_and_driver_info {
14852 + struct spi_board_info sbi;
14853 + const char *driver_name;
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.
14865 +/* Convenience-macro to avoid typos causing diffs between sser ports. */
14867 +#define SSER_CONFIG(n) \
14870 + * No meaningful values for .irq or .chip_select, \
14871 + * so we leave them out. \
14874 + .modalias = "mmc_spi", \
14876 + = &crisv32_mmcspi_sser_pdata, \
14878 + * Casting to avoid a compiler const-warning. \
14880 + .controller_data \
14882 + &crisv32_mmcspi_sser##n##_cdata), \
14883 + .max_speed_hz = 50 * 1000 * 1000, \
14886 + * We only provide one mode, so it must be \
14889 + .mode = SPI_MODE_3 \
14891 + crisv32_matching_spi_sser_driver_name, \
14892 + WITH_ETRAX_SPI_SSER##n##_DMA \
14895 +static const struct crisv32_s_b_i_and_driver_info
14896 +crisv32_mmcspi_devices[] __initdata = {
14897 +#ifdef CONFIG_ETRAX_SPI_SSER0
14900 +#ifdef CONFIG_ETRAX_SPI_SSER1
14903 +#ifdef CONFIG_SPI_ETRAX_GPIO
14906 + .modalias = "mmc_spi",
14907 + .platform_data = &crisv32_mmcspi_gpio_pdata,
14908 + /* Casting to avoid a compiler const-warning. */
14910 + = (void *) &crisv32_mmcspi_gpio_cdata,
14912 + /* No, we can't even reach this number with GPIO. */
14913 + .max_speed_hz = 5 * 1000 * 1000,
14916 + crisv32_matching_spi_gpio_driver_name,
14922 +/* Must not be __initdata. */
14923 +static const char controller_data_ptr_name[] = "controller_data_ptr";
14924 +static u64 allmem_mask = ~(u32) 0;
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.
14932 +static int __init crisv32_register_mmcspi(void)
14936 + const struct crisv32_s_b_i_and_driver_info *sbip;
14938 + for (sbip = crisv32_mmcspi_devices;
14939 + sbip < crisv32_mmcspi_devices
14940 + + ARRAY_SIZE(crisv32_mmcspi_devices);
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
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
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.
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);
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
14977 + if (sbip->dma_able) {
14978 + struct platform_device *pdev = retp;
14980 + pdev->dev.dma_mask = &allmem_mask;
14981 + pdev->dev.coherent_dma_mask = allmem_mask;
14984 + if ((ret = platform_device_add_resources(retp, &mmcspi_res, 1)) != 0
14985 + || (ret = platform_device_add(retp)) != 0) {
14986 + platform_device_put(retp);
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).
14996 + ret = spi_register_board_info(&sbip->sbi, 1);
15004 +#error "Non-module because spi_register_board_info is one-way; there's no unregister function"
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).
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
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 $
15021 * Stream co-processor driver for the ETRAX FS
15023 @@ -1718,7 +1718,7 @@
15029 * while (i < (Nb * (Nr + 1))) {
15031 * if ((i mod Nk) == 0) {
15032 @@ -1886,7 +1886,7 @@
15036 -dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs)
15037 +dma_done_interrupt(int irq, void *dev_id)
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)));
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));
15048 /* Start output DMA. */
15049 @@ -3459,7 +3460,7 @@
15052 static int initialized = 0;
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
15062 -/* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $
15065 * ETRAX CRISv32 general port I/O device
15067 - * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
15068 + * Copyright (c) 1999-2006 Axis Communications AB
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.
15075 - * $Log: gpio.c,v $
15076 - * Revision 1.16 2005/06/19 17:06:49 starvik
15077 - * Merge of Linux 2.6.12.
15079 - * Revision 1.15 2005/05/25 08:22:20 starvik
15080 - * Changed GPIO port order to fit packages/devices/axis-2.4.
15082 - * Revision 1.14 2005/04/24 18:35:08 starvik
15083 - * Updated with final register headers.
15085 - * Revision 1.13 2005/03/15 15:43:00 starvik
15086 - * dev_id needs to be supplied for shared IRQs.
15088 - * Revision 1.12 2005/03/10 17:12:00 starvik
15089 - * Protect alarm list with spinlock.
15091 - * Revision 1.11 2005/01/05 06:08:59 starvik
15092 - * No need to do local_irq_disable after local_irq_save.
15094 - * Revision 1.10 2004/11/19 08:38:31 starvik
15095 - * Removed old crap.
15097 - * Revision 1.9 2004/05/14 07:58:02 starvik
15098 - * Merge of changes from 2.4
15100 - * Revision 1.8 2003/09/11 07:29:50 starvik
15101 - * Merge of Linux 2.6.0-test5
15103 - * Revision 1.7 2003/07/10 13:25:46 starvik
15104 - * Compiles for 2.5.74
15105 - * Lindented ethernet.c
15107 - * Revision 1.6 2003/07/04 08:27:46 starvik
15108 - * Merge of Linux 2.5.74
15110 - * Revision 1.5 2003/06/10 08:26:37 johana
15111 - * Etrax -> ETRAX CRISv32
15113 - * Revision 1.4 2003/06/05 14:22:48 johana
15114 - * Initialise some_alarms.
15116 - * Revision 1.3 2003/06/05 10:15:46 johana
15117 - * New INTR_VECT macros.
15118 - * Enable interrupts in global config.
15120 - * Revision 1.2 2003/06/03 15:52:50 johana
15121 - * Initial CRIS v32 version.
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.
15129 #include <linux/module.h>
15130 #include <linux/sched.h>
15131 #include <linux/slab.h>
15133 #include <asm/system.h>
15134 #include <asm/irq.h>
15136 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15139 +#define VIRT_I2C_ADDR 0x40
15143 /* The following gio ports on ETRAX FS is available:
15144 * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
15146 @@ -111,6 +65,10 @@
15147 static wait_queue_head_t *gpio_wq;
15150 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15151 +static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
15152 + unsigned long arg);
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;
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),
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
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),
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
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,
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,
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,
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,
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),
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,
15247 -static unsigned int
15248 +static unsigned int
15249 gpio_poll(struct file *file,
15252 @@ -278,7 +256,7 @@
15255 if ((data & priv->highalarm) ||
15256 - (~data & priv->lowalarm)) {
15257 + (~data & priv->lowalarm)) {
15258 mask = POLLIN|POLLRDNORM;
15261 @@ -288,11 +266,26 @@
15263 int etrax_gpio_wake_up_check(void)
15265 - struct gpio_private *priv = alarmlist;
15266 + struct gpio_private *priv;
15267 unsigned long data = 0;
15268 + unsigned long flags;
15270 + spin_lock_irqsave(&alarm_lock, flags);
15271 + priv = alarmlist;
15273 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15274 + if (priv->minor == GPIO_MINOR_V) {
15275 + data = (unsigned long)cached_virtual_gpio_read;
15278 + data = *data_in[priv->minor];
15279 + if (priv->minor == GPIO_MINOR_A) {
15280 + priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15284 data = *data_in[priv->minor];
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 @@
15293 + spin_unlock_irqrestore(&alarm_lock, flags);
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)
15302 if (gpio_some_alarms) {
15303 return IRQ_RETVAL(etrax_gpio_wake_up_check());
15304 @@ -314,14 +308,17 @@
15308 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15309 +gpio_pa_interrupt(int irq, void *dev_id)
15311 reg_gio_rw_intr_mask intr_mask;
15312 reg_gio_r_masked_intr masked_intr;
15313 reg_gio_rw_ack_intr ack_intr;
15315 unsigned long tmp2;
15317 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15318 + unsigned char enable_gpiov_ack = 0;
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);
15328 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15329 + /* Something changed on virtual GPIO. Interrupt is acked by
15330 + * reading the device.
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;
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);
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.
15350 + if (enable_gpiov_ack) {
15351 + tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
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);
15357 if (gpio_some_alarms) {
15358 return IRQ_RETVAL(etrax_gpio_wake_up_check());
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) {
15377 if (priv->minor == GPIO_MINOR_LEDS) {
15380 @@ -416,25 +437,24 @@
15383 gpio_open(struct inode *inode, struct file *filp)
15386 struct gpio_private *priv;
15387 int p = iminor(inode);
15389 if (p > GPIO_MINOR_LAST)
15392 - priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
15393 + priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
15398 + memset(priv, 0, sizeof(*priv));
15402 - /* initialize the io/alarm struct and link it into our alarmlist */
15403 + /* initialize the io/alarm struct */
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 @@
15412 filp->private_data = (void *)priv;
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);
15424 gpio_release(struct inode *inode, struct file *filp)
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;
15434 /* unlink from alarmlist and free the private structure */
15436 + spin_lock_irq(&alarm_lock);
15438 + todel = (struct gpio_private *)filp->private_data;
15441 alarmlist = todel->next;
15443 @@ -473,6 +503,9 @@
15446 if (p->minor == GPIO_MINOR_A) {
15447 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15448 + p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15450 a_high |= p->highalarm;
15451 a_low |= p->lowalarm;
15453 @@ -483,23 +516,30 @@
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.
15463 + a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
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);
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().
15480 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
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
15487 unsigned long flags;
15488 unsigned long dir_shadow;
15489 @@ -512,6 +552,10 @@
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 */
15498 dir_shadow ^= 0x3FFFF; /* Only 18 bits */
15500 @@ -546,6 +590,11 @@
15504 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15505 + if (priv->minor == GPIO_MINOR_V)
15506 + return virtual_gpio_ioctl(file, cmd, arg);
15509 switch (_IOC_NR(cmd)) {
15510 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
15512 @@ -553,8 +602,6 @@
15515 local_irq_save(flags);
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 @@
15524 local_irq_save(flags);
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 @@
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;
15540 - spin_unlock(&alarm_lock);
15541 + spin_unlock_irqrestore(&alarm_lock, flags);
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;
15552 - spin_unlock(&alarm_lock);
15553 + spin_unlock_irqrestore(&alarm_lock, flags);
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 */
15568 - spin_unlock(&alarm_lock);
15569 + spin_unlock_irqrestore(&alarm_lock, flags);
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
15580 return setget_input(priv, arg);
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
15588 return setget_output(priv, arg);
15590 - case IO_CFG_WRITE_MODE:
15591 + case IO_CFG_WRITE_MODE:
15593 unsigned long dir_shadow;
15594 dir_shadow = *dir_oe[priv->minor];
15595 @@ -641,7 +686,7 @@
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)))
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.
15613 @@ -684,6 +729,132 @@
15617 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15619 +virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
15621 + unsigned long flags;
15622 + unsigned short val;
15623 + unsigned short shadow;
15624 + struct gpio_private *priv = (struct gpio_private *)file->private_data;
15626 + switch (_IOC_NR(cmd)) {
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);
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);
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);
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);
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);
15666 + case IO_CFG_WRITE_MODE:
15668 + unsigned long dir_shadow;
15669 + dir_shadow = *dir_oe[priv->minor];
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
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)))
15682 + priv->clk_mask = 0;
15683 + priv->data_mask = 0;
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)))
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)))
15703 + case IO_SETGET_INPUT:
15705 + /* bits set in *arg is set to input,
15706 + * *arg updated with current input pins.
15708 + unsigned short input_mask = ~*dir_oe[priv->minor];
15709 + if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15711 + val = setget_input(priv, val);
15712 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15714 + if ((input_mask & val) != input_mask) {
15715 + /* Input pins changed. All ports desired as input
15716 + * should be set to logic 1.
15718 + unsigned short change = input_mask ^ val;
15719 + i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15720 + shadow &= ~change;
15722 + i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15726 + case IO_SETGET_OUTPUT:
15727 + /* bits set in *arg is set to output,
15728 + * *arg updated with current output pins.
15730 + if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15732 + val = setget_output(priv, val);
15733 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15741 +#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
15744 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
15746 @@ -714,6 +885,66 @@
15747 .release = gpio_release,
15750 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15752 +virtual_gpio_init(void)
15754 + reg_gio_rw_intr_cfg intr_cfg;
15755 + reg_gio_rw_intr_mask intr_mask;
15756 + unsigned short shadow;
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));
15762 + /* Set interrupt mask and on what state the interrupt shall trigger.
15763 + * For virtual gpio the interrupt shall trigger on logic '0'.
15765 + intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
15766 + intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
15768 + switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
15770 + intr_cfg.pa0 = regk_gio_lo;
15771 + intr_mask.pa0 = regk_gio_yes;
15774 + intr_cfg.pa1 = regk_gio_lo;
15775 + intr_mask.pa1 = regk_gio_yes;
15778 + intr_cfg.pa2 = regk_gio_lo;
15779 + intr_mask.pa2 = regk_gio_yes;
15782 + intr_cfg.pa3 = regk_gio_lo;
15783 + intr_mask.pa3 = regk_gio_yes;
15786 + intr_cfg.pa4 = regk_gio_lo;
15787 + intr_mask.pa4 = regk_gio_yes;
15790 + intr_cfg.pa5 = regk_gio_lo;
15791 + intr_mask.pa5 = regk_gio_yes;
15794 + intr_cfg.pa6 = regk_gio_lo;
15795 + intr_mask.pa6 = regk_gio_yes;
15798 + intr_cfg.pa7 = regk_gio_lo;
15799 + intr_mask.pa7 = regk_gio_yes;
15803 + REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
15804 + REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
15806 + gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15807 + gpio_some_alarms = 1;
15811 /* main driver initialization routine, called from mem.c */
15813 @@ -732,17 +963,18 @@
15816 /* Clear all leds */
15817 - LED_NETWORK_SET(0);
15818 + LED_NETWORK_GRP0_SET(0);
15819 + LED_NETWORK_GRP1_SET(0);
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
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);
15839 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15840 + virtual_gpio_init();
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
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,
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,
15861 *| i2c_getack changed data level while clock
15862 *| was high, causing DS75 to see a stop condition
15864 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
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 ***********************************/
15871 #include <linux/module.h>
15873 #define I2C_DATA_HIGH 1
15874 #define I2C_DATA_LOW 0
15876 -#define i2c_enable()
15877 -#define i2c_disable()
15878 +#define i2c_enable()
15879 +#define i2c_disable()
15881 /* enable or disable output-enable, to select output or input on the i2c bus */
15885 #define i2c_delay(usecs) udelay(usecs)
15887 +static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
15889 /****************** VARIABLE SECTION ************************************/
15891 static struct crisv32_iopin cris_i2c_clk;
15892 @@ -154,7 +156,7 @@
15894 i2c_data(I2C_DATA_LOW);
15898 i2c_delay(CLOCK_LOW_TIME/2);
15899 i2c_clk(I2C_CLOCK_HIGH);
15900 i2c_delay(CLOCK_HIGH_TIME);
15901 @@ -213,7 +215,7 @@
15903 i2c_clk(I2C_CLOCK_HIGH);
15904 i2c_delay(CLOCK_HIGH_TIME);
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
15913 i2c_clk(I2C_CLOCK_HIGH);
15916 * Use PORT PB instead of I2C
15917 * for input. (I2C not working)
15918 @@ -264,6 +267,8 @@
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.
15932 i2c_data(I2C_DATA_LOW);
15941 i2c_clk(I2C_CLOCK_LOW);
15942 i2c_delay(CLOCK_HIGH_TIME/4);
15944 @@ -338,7 +345,7 @@
15946 i2c_data(I2C_DATA_HIGH);
15947 i2c_delay(CLOCK_LOW_TIME);
15953 @@ -369,24 +376,160 @@
15954 i2c_delay(CLOCK_HIGH_TIME);
15955 i2c_clk(I2C_CLOCK_LOW);
15956 i2c_delay(CLOCK_LOW_TIME);
15962 /*#---------------------------------------------------------------------------
15964 +*# FUNCTION NAME: i2c_write
15966 +*# DESCRIPTION : Writes a value to an I2C device
15968 +*#--------------------------------------------------------------------------*/
15970 +i2c_write(unsigned char theSlave, void *data, size_t nbytes)
15972 + int error, cntr = 3;
15973 + unsigned char bytes_wrote = 0;
15974 + unsigned char value;
15975 + unsigned long flags;
15977 + spin_lock(&i2c_lock);
15982 + * we don't like to be interrupted
15984 + local_irq_save(flags);
15988 + * send slave address
15990 + i2c_outbyte((theSlave & 0xfe));
15994 + if(!i2c_getack())
15999 + for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) {
16000 + memcpy(&value, data + bytes_wrote, sizeof value);
16001 + i2c_outbyte(value);
16003 + * now it's time to wait for ack
16005 + if (!i2c_getack())
16009 + * end byte stream
16013 + * enable interrupt again
16015 + local_irq_restore(flags);
16017 + } while(error && cntr--);
16019 + i2c_delay(CLOCK_LOW_TIME);
16021 + spin_unlock(&i2c_lock);
16026 +/*#---------------------------------------------------------------------------
16028 +*# FUNCTION NAME: i2c_read
16030 +*# DESCRIPTION : Reads a value from an I2C device
16032 +*#--------------------------------------------------------------------------*/
16034 +i2c_read(unsigned char theSlave, void *data, size_t nbytes)
16036 + unsigned char b = 0;
16037 + unsigned char bytes_read = 0;
16038 + int error, cntr = 3;
16039 + unsigned long flags;
16041 + spin_lock(&i2c_lock);
16045 + memset(data, 0, nbytes);
16047 + * we don't like to be interrupted
16049 + local_irq_save(flags);
16051 + * generate start condition
16056 + * send slave address
16058 + i2c_outbyte((theSlave | 0x01));
16062 + if(!i2c_getack())
16067 + for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
16068 + b = i2c_inbyte();
16069 + memcpy(data + bytes_read, &b, sizeof b);
16071 + if (bytes_read < (nbytes - 1)) {
16076 + * last received byte needs to be nacked
16077 + * instead of acked
16085 + * enable interrupt again
16087 + local_irq_restore(flags);
16089 + } while(error && cntr--);
16091 + spin_unlock(&i2c_lock);
16096 +/*#---------------------------------------------------------------------------
16098 *# FUNCTION NAME: i2c_writereg
16100 *# DESCRIPTION : Writes a value to an I2C device
16102 *#--------------------------------------------------------------------------*/
16104 -i2c_writereg(unsigned char theSlave, unsigned char theReg,
16105 +i2c_writereg(unsigned char theSlave, unsigned char theReg,
16106 unsigned char theValue)
16108 int error, cntr = 3;
16109 unsigned long flags;
16111 + spin_lock(&i2c_lock);
16116 @@ -431,10 +574,12 @@
16117 * enable interrupt again
16119 local_irq_restore(flags);
16122 } while(error && cntr--);
16124 i2c_delay(CLOCK_LOW_TIME);
16126 + spin_unlock(&i2c_lock);
16130 @@ -453,6 +598,8 @@
16131 int error, cntr = 3;
16132 unsigned long flags;
16134 + spin_lock(&i2c_lock);
16139 @@ -463,7 +610,7 @@
16140 * generate start condition
16146 * send slave address
16148 @@ -482,7 +629,7 @@
16149 * now it's time to wait for ack
16155 * repeat start condition
16157 @@ -496,7 +643,7 @@
16166 @@ -514,9 +661,11 @@
16167 * enable interrupt again
16169 local_irq_restore(flags);
16172 } while(error && cntr--);
16174 + spin_unlock(&i2c_lock);
16179 @@ -546,7 +695,7 @@
16180 switch (_IOC_NR(cmd)) {
16182 /* write to an i2c slave */
16183 - D(printk("i2cw %d %d %d\n",
16184 + D(printk("i2cw %d %d %d\n",
16187 I2C_ARGVALUE(arg)));
16188 @@ -558,18 +707,18 @@
16191 /* read from an i2c slave */
16192 - D(printk("i2cr %d %d ",
16193 + D(printk("i2cr %d %d ",
16196 val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
16197 D(printk("= %d\n", val));
16210 @@ -583,28 +732,53 @@
16215 + static int res = 0;
16216 + static int first = 1;
16223 - /* Setup and enable the Port B I2C interface */
16224 + /* Setup and enable the DATA and CLK pins */
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);
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);
16239 - /* register char device */
16242 +i2c_register(void)
16247 + res = i2c_init();
16252 + /* register char device */
16253 res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
16255 printk(KERN_ERR "i2c: couldn't get a major number.\n");
16259 - printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
16261 + printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");
16266 /* this makes sure that i2c_init is called during boot */
16268 -module_init(i2c_init);
16269 +module_init(i2c_register);
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
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);
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 @@
16291 - retval = request_firmware(&fw_entry,
16293 + retval = request_firmware(&fw_entry,
16295 &iop_spu_device[spu_inst]);
16300 "iop_load_spu: Failed to load firmware \"%s\"\n",
16303 @@ -123,7 +123,7 @@
16307 -int iop_fw_load_mpu(unsigned char *fw_name)
16308 +int iop_fw_load_mpu(unsigned char *fw_name)
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);
16318 "iop_load_spu: Failed to load firmware \"%s\"\n",
16322 data = (u32 *) fw_entry->data;
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
16333 * Derived from drivers/mtd/nand/spia.c
16334 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
16336 - * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $
16338 + * $Id: nandflash.c,v 1.8 2006/10/16 12:56:46 ricardw Exp $
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 @@
16346 +/* Bitmask for control pins */
16347 +#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
16349 +/* Bitmask for mtd nand control bits */
16350 +#define CTRL_BITMASK (NAND_NCE | NAND_CLE | NAND_ALE)
16353 static struct mtd_info *crisv32_mtd = NULL;
16356 * hardware specific access to control-lines
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)
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;
16367 local_irq_save(flags);
16369 - case NAND_CTL_SETCLE:
16370 - dout.data |= (1<<CLE_BIT);
16372 - case NAND_CTL_CLRCLE:
16373 - dout.data &= ~(1<<CLE_BIT);
16375 - case NAND_CTL_SETALE:
16376 - dout.data |= (1<<ALE_BIT);
16378 - case NAND_CTL_CLRALE:
16379 - dout.data &= ~(1<<ALE_BIT);
16381 - case NAND_CTL_SETNCE:
16382 - dout.data |= (1<<CE_BIT);
16384 - case NAND_CTL_CLRNCE:
16385 - dout.data &= ~(1<<CE_BIT);
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;
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;
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);
16408 + REG_WR(gio, regi_gio, rw_pa_dout, dout);
16410 - REG_WR(gio, regi_gio, rw_pa_dout, dout);
16412 + /* command to chip */
16413 + if (cmd != NAND_CMD_NONE)
16414 + writeb(cmd, this->IO_ADDR_W);
16416 local_irq_restore(flags);
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;
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; */
16436 /* Scan to find existance of the device */
16437 if (nand_scan (crisv32_mtd, 1)) {
16443 return crisv32_mtd;
16447 iounmap((void *)read_cs);
16448 - iounmap((void *)write_cs);
16449 + iounmap((void *)write_cs);
16451 kfree (crisv32_mtd);
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
16457 * 400 kbits/s. The built-in word address register is incremented
16458 * automatically after each written or read byte.
16460 - * Copyright (c) 2002-2003, Axis Communications AB
16461 + * Copyright (c) 2002-2006, Axis Communications AB
16462 * All rights reserved.
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 $"
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)
16476 +static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
16478 static const unsigned char days_in_month[] =
16479 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
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 *);
16485 +/* Cache VL bit value read at driver init since writing the RTC_SECOND
16486 + * register clears the VL status.
16488 +static int voltage_low = 0;
16490 static struct file_operations pcf8563_fops = {
16491 owner: THIS_MODULE,
16492 ioctl: pcf8563_ioctl,
16493 - open: pcf8563_open,
16494 - release: pcf8563_release,
16500 unsigned char res = rtc_read(reg);
16502 - /* The PCF8563 does not return 0 for unimplemented bits */
16503 + /* The PCF8563 does not return 0 for unimplemented bits. */
16509 pcf8563_writereg(int reg, unsigned char val)
16511 -#ifdef CONFIG_ETRAX_RTC_READONLY
16512 - if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
16516 rtc_write(reg, val);
16519 @@ -114,11 +112,13 @@
16520 tm->tm_mon = rtc_read(RTC_MONTH);
16521 tm->tm_year = rtc_read(RTC_YEAR);
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);
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 @@
16539 + static int res = 0;
16540 + static int first = 1;
16547 /* Initiate the i2c protocol. */
16549 + res = i2c_init();
16551 + printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
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)
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);
16565 + /* Check for low voltage, and warn about it. */
16566 + if (rtc_read(RTC_SECONDS) & 0x80) {
16568 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16569 + "date/time information is no longer guaranteed!\n",
16573 - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
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);
16584 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
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",
16600 @@ -203,7 +212,8 @@
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)
16608 /* Some sanity checks. */
16609 if (_IOC_TYPE(cmd) != RTC_MAGIC)
16610 @@ -217,31 +227,35 @@
16612 struct rtc_time tm;
16614 - memset(&tm, 0, sizeof (struct rtc_time));
16615 + spin_lock(&rtc_lock);
16616 + memset(&tm, 0, sizeof tm);
16619 - if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
16620 + if (copy_to_user((struct rtc_time *) arg, &tm,
16622 + spin_unlock(&rtc_lock);
16626 + spin_unlock(&rtc_lock);
16633 -#ifdef CONFIG_ETRAX_RTC_READONLY
16639 struct rtc_time tm;
16641 + memset(&tm, 0, sizeof tm);
16642 if (!capable(CAP_SYS_TIME))
16645 - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
16646 + if (copy_from_user(&tm, (struct rtc_time *) arg,
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.
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);
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)) {
16672 century = (tm.tm_year >= 2000) ? 0x80 : 0;
16673 tm.tm_year = tm.tm_year % 100;
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;
16683 + spin_lock(&rtc_lock);
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);
16692 + spin_unlock(&rtc_lock);
16695 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
16702 - if (rtc_read(RTC_SECONDS) & 0x80) {
16704 - printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16705 - "date/time information is no longer guaranteed!\n",
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);
16712 - if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
16715 + if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
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. */
16731 int ret = rtc_read(RTC_SECONDS);
16733 rtc_write(RTC_SECONDS, (ret & 0x7F));
16735 + /* Clear the cached value. */
16744 @@ -321,17 +344,32 @@
16749 -pcf8563_open(struct inode *inode, struct file *filp)
16751 +pcf8563_register(void)
16755 + if (pcf8563_init() < 0) {
16756 + printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
16757 + "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
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);
16767 + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
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);
16777 -pcf8563_release(struct inode *inode, struct file *filp)
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
16791 struct resource *r;
16794 pci_read_config_word(dev, PCI_COMMAND, &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
16802 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
16803 int order = get_order(size);
16806 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
16807 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
16809 @@ -120,7 +120,7 @@
16810 void dma_release_declared_memory(struct device *dev)
16812 struct dma_coherent_mem *mem = dev->dma_mem;
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
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 */
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
16836 #define DEFAULT_FRAME_RATE 0
16837 #define DEFAULT_WORD_RATE 7
16838 @@ -112,7 +113,7 @@
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 @@
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);
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);
16869 #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
16870 @@ -157,7 +158,7 @@
16871 #define SYNC_SER_MANUAL
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);
16879 @@ -201,8 +202,8 @@
16881 ports[0].enabled = 0;
16882 ports[1].enabled = 0;
16884 - if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
16886 + if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
16888 printk("unable to get major for synchronous serial port\n");
16890 @@ -243,13 +244,13 @@
16892 DEBUG(printk("Init sync serial port %d\n", portnbr));
16894 - port->port_nbr = portnbr;
16895 + port->port_nbr = portnbr;
16896 port->init_irqs = 1;
16898 port->outp = port->out_buffer;
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;
16911 tr_cfg.rate_ctrl = regk_sser_bulk;
16912 tr_cfg.data_pin_use = regk_sser_dout;
16914 + tr_cfg.rate_ctrl = regk_sser_iso;
16915 + tr_cfg.data_pin_use = regk_sser_dout;
16917 tr_cfg.bulk_wspace = 1;
16918 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
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 @@
16926 unsigned char *start;
16927 unsigned char *end;
16930 start = (unsigned char*)port->readp; /* cast away volatile */
16931 end = (unsigned char*)port->writep; /* cast away volatile */
16932 /* 0123456789 0123456789
16939 avail = end - start;
16942 avail = port->in_buffer_size - (start - end);
16945 @@ -323,17 +329,17 @@
16947 unsigned char *start;
16948 unsigned char *end;
16951 start = (unsigned char*)port->readp; /* cast away volatile */
16952 end = (unsigned char*)port->writep; /* cast away volatile */
16953 /* 0123456789 0123456789
16960 avail = end - start;
16963 avail = port->flip + port->in_buffer_size - start;
16966 @@ -343,10 +349,10 @@
16967 int dev = iminor(inode);
16969 reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
16970 - reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
16972 - DEBUG(printk("Open sync serial port %d\n", dev));
16973 + reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
16975 + DEBUG(printk("Open sync serial port %d\n", dev));
16977 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
16979 DEBUG(printk("Invalid minor %d\n", dev));
16980 @@ -354,7 +360,7 @@
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)
16987 DEBUG(printk("Device is busy.. \n"));
16989 @@ -422,8 +428,8 @@
16990 DMA_VERBOSE_ON_ERROR,
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");
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);
17009 @@ -497,7 +503,7 @@
17010 port = &ports[dev];
17018 @@ -508,17 +514,29 @@
17019 unsigned int mask = 0;
17021 DEBUGPOLL( static unsigned int prev_mask = 0; );
17024 port = &ports[dev];
17026 + if (!port->started)
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;
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;
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)
17055 int return_val = 0;
17056 + int dma_w_size = regk_dma_set_w_size1;
17057 int dev = iminor(file->f_dentry->d_inode);
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;
17067 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
17069 DEBUG(printk("Invalid minor %d\n", dev));
17070 @@ -558,9 +577,32 @@
17072 if (GET_SPEED(arg) == CODEC)
17074 + unsigned int freq;
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));
17080 + /* Clock divider will internally be
17081 + * gen_cfg.clk_div + 1.
17084 + freq = GET_FREQ(arg);
17089 + case FREQ_128kHz:
17090 + case FREQ_256kHz:
17091 + gen_cfg.clk_div = 125 * (1 << (freq - FREQ_256kHz)) - 1;
17093 + case FREQ_512kHz:
17094 + gen_cfg.clk_div = 62;
17099 + gen_cfg.clk_div = 8 * (1 << freq) - 1;
17105 @@ -625,87 +667,118 @@
17106 case MASTER_OUTPUT:
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;
17116 + frm_cfg.frame_pin_dir = regk_sser_in;
17117 gen_cfg.clk_dir = regk_sser_in;
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;
17129 + frm_cfg.frame_pin_dir = regk_sser_in;
17130 gen_cfg.clk_dir = regk_sser_in;
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;
17142 + frm_cfg.frame_pin_dir = regk_sser_in;
17143 gen_cfg.clk_dir = regk_sser_in;
17146 spin_unlock_irq(&port->lock);
17151 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT))
17152 intr_mask.rdav = regk_sser_yes;
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;
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;
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;
17182 frm_cfg.frame_pin_use = regk_sser_frm;
17183 else if (arg & SYNC_OFF)
17184 frm_cfg.frame_pin_use = regk_sser_gio0;
17186 - if (arg & WORD_SIZE_8)
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;
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;
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;
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;
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;
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;
17218 - if (arg & FLOW_CONTROL_ENABLE)
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)
17225 + else if (arg & FLOW_CONTROL_DISABLE) {
17226 + frm_cfg.status_pin_use = regk_sser_gio0;
17227 rec_cfg.fifo_thr = regk_sser_inf;
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;
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;
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;
17251 if (arg & STATUS_NORMAL)
17252 gen_cfg.hold_pol = regk_sser_pos;
17253 else if (arg & STATUS_INVERT)
17254 @@ -726,15 +799,15 @@
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;
17262 + else if (arg & CLOCK_INVERT)
17263 + gen_cfg.out_clk_pol = regk_sser_neg;
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;
17271 if (arg & STATUS_NORMAL)
17272 gen_cfg.hold_pol = regk_sser_pos;
17273 else if (arg & STATUS_INVERT)
17274 @@ -772,9 +845,10 @@
17278 - tr_cfg.tr_en = port->output;
17279 rec_cfg.rec_en = port->input;
17280 + gen_cfg.en = (port->output | port->input);
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);
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;
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);
17300 + REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17303 spin_unlock_irq(&port->lock);
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)
17311 int dev = iminor(file->f_dentry->d_inode);
17312 @@ -807,7 +894,7 @@
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 */
17318 * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE
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;
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;
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))
17339 @@ -854,13 +941,10 @@
17340 if (!port->started)
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);
17353 @@ -887,7 +971,7 @@
17356 /* Sleep until all sent */
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 @@
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)
17370 int dev = iminor(file->f_dentry->d_inode);
17373 - unsigned char* start;
17374 + unsigned char* start;
17375 unsigned char* end;
17376 unsigned long flags;
17378 @@ -949,7 +1033,7 @@
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 */
17391 + DEBUGREAD(printk("&"));
17392 if (file->f_flags & O_NONBLOCK)
17399 interruptible_sleep_on(&port->in_wait_q);
17400 if (signal_pending(current))
17402 @@ -979,9 +1064,9 @@
17403 avail = port->in_buffer_size;
17404 else if (end > start)
17405 avail = end - start;
17408 avail = port->flip + port->in_buffer_size - start;
17411 count = count > avail ? avail : count;
17412 if (copy_to_user(buf, start, count))
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;
17423 @@ -1032,7 +1117,7 @@
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);
17430 tr_data.data = *port->outp++;
17431 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17432 @@ -1042,10 +1127,10 @@
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);
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);
17443 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
17444 port->outp = port->out_buffer;
17445 @@ -1056,15 +1141,27 @@
17447 static void start_dma(struct sync_port* port, const char* data, int count)
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++)
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]);
17463 + port->out_descr[i-1].next = virt_to_phys(&port->out_descr[0]);
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;
17470 DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context));
17472 + tr_cfg.tr_en = regk_sser_yes;
17473 + REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17475 DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
17478 @@ -1073,7 +1170,7 @@
17481 port->writep = port->flip;
17484 if (port->writep > port->flip + port->in_buffer_size)
17486 panic("Offset too large in sync serial driver\n");
17487 @@ -1099,7 +1196,7 @@
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)
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;
17500 - for (i = 0; i < NUMBER_OF_PORTS; i++)
17501 + for (i = 0; i < NUMBER_OF_PORTS; i++)
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);
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);
17519 wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
17523 return IRQ_RETVAL(found);
17524 } /* tr_interrupt */
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)
17529 reg_dma_r_masked_intr masked;
17530 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
17531 @@ -1152,7 +1252,7 @@
17535 - for (i = 0; i < NUMBER_OF_PORTS; i++)
17536 + for (i = 0; i < NUMBER_OF_PORTS; i++)
17538 sync_port *port = &ports[i];
17540 @@ -1164,17 +1264,17 @@
17541 if (masked.data) /* Descriptor interrupt */
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)) {
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;
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),
17560 port->writep += port->inbufchunk;
17561 if (port->writep >= port->flip + port->in_buffer_size)
17562 @@ -1184,11 +1284,13 @@
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);
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 */
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)
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
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 $
17596 # Makefile for the linux kernel.
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 \
17603 + arbiter.o io.o cache.o cacheflush.o
17605 obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
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
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
17619 * bandwidth (e.g. ethernet) and then the remaining slots are divided
17620 * on all the active clients.
17622 - * Copyright (c) 2004, 2005 Axis Communications AB.
17623 + * Copyright (c) 2004, 2005, 2006 Axis Communications AB.
17626 #include <asm/arch/hwregs/reg_map.h>
17627 @@ -44,35 +44,88 @@
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};
17637 DEFINE_SPINLOCK(arbiter_lock);
17639 -static irqreturn_t
17640 +static irqreturn_t
17641 crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs);
17643 -static void crisv32_arbiter_config(int region)
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)
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.
17657 +static void crisv32_arbiter_config(int region, int unused_slots)
17662 - int val[NBR_OF_SLOTS];
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.
17671 + s8 val[NBR_OF_SLOTS];
17673 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17674 - val[slot] = NBR_OF_CLIENTS + 1;
17677 for (client = 0; client < NBR_OF_CLIENTS; client++)
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.
17697 if (!requested_slots[region][client])
17699 - interval = NBR_OF_SLOTS / requested_slots[region][client];
17702 + * Skip inactive clients. Also skip zero-slot
17703 + * allocations in this pass when there are no known
17706 + if (!active_clients[region][client] || unused_slots <= 0)
17711 + /* Only allocate one slot for this client. */
17712 + interval = NBR_OF_SLOTS;
17715 + interval = NBR_OF_SLOTS / requested_slots[region][client];
17718 while (pos < NBR_OF_SLOTS)
17720 - if (val[pos] != NBR_OF_CLIENTS + 1)
17721 + if (val[pos] >= 0)
17725 @@ -85,7 +138,13 @@
17727 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17729 - if (val[slot] == NBR_OF_CLIENTS + 1)
17731 + * Allocate remaining slots in round-robin
17732 + * client-number order for active clients. For this
17733 + * pass, we ignore requested bandwidth and previous
17736 + if (val[slot] < 0)
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]);
17748 extern char _stext, _etext;
17749 @@ -111,18 +170,28 @@
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);
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.
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);
17776 if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
17778 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
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 @@
17788 +/* Main entry for bandwidth allocation. */
17791 int crisv32_arbiter_allocate_bandwidth(int client, int region,
17792 @@ -141,39 +211,76 @@
17795 crisv32_arbiter_init();
17798 for (i = 0; i < NBR_OF_CLIENTS; i++)
17800 total_assigned += requested_slots[region][i];
17801 total_clients += active_clients[region][i];
17803 - req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
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);
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.
17818 + if (total_assigned + req > NBR_OF_SLOTS)
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);
17830 + * Main entry for bandwidth deallocation.
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.
17841 +void crisv32_arbiter_deallocate_bandwidth(int client, int region)
17844 + int total_assigned = 0;
17846 + requested_slots[region][client] = 0;
17847 + active_clients[region][client] = 0;
17849 + for (i = 0; i < NBR_OF_CLIENTS; i++)
17850 + total_assigned += requested_slots[region][i];
17852 + crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
17855 int crisv32_arbiter_watch(unsigned long start, unsigned long size,
17856 unsigned long clients, unsigned long accesses,
17857 watch_callback* cb)
17862 crisv32_arbiter_init();
17865 if (start > 0x80000000) {
17866 printk("Arbiter: %lX doesn't look like a physical address", start);
17870 spin_lock(&arbiter_lock);
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();
17879 spin_lock(&arbiter_lock);
17882 if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
17883 spin_unlock(&arbiter_lock);
17885 @@ -239,7 +346,7 @@
17887 extern void show_registers(struct pt_regs *regs);
17889 -static irqreturn_t
17890 +static irqreturn_t
17891 crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs)
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;
17904 if (masked_intr.bp0) {
17905 watch = &watches[0];
17906 ack_intr.bp0 = regk_marb_yes;
17907 @@ -291,6 +398,6 @@
17913 return IRQ_HANDLED;
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
17920 #define ENTRY(entry) DEFINE(PT_ ## entry, offsetof(struct pt_regs, entry))
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
17933 +#include <linux/module.h>
17934 +#include <asm/io.h>
17935 +#include <asm/arch/cache.h>
17936 +#include <asm/arch/hwregs/dma.h>
17938 +// This file is used to workaround a cache bug, Guinness TR 106
17940 +inline void flush_dma_descr(dma_descr_data* descr, int flush_buf)
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
17946 + cris_flush_cache_range(phys_to_virt((unsigned)descr->buf), (unsigned)(descr->after - descr->buf));
17949 +void flush_dma_list(dma_descr_data* descr)
17953 + flush_dma_descr(descr, 1);
17956 + descr = phys_to_virt((unsigned)descr->next);
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
17968 + .global cris_flush_cache_range
17969 +cris_flush_cache_range:
17970 + move.d 1024, $r12
17972 + bhi cris_flush_1KB
17978 + blt cris_flush_last
18047 + ba cris_flush_cache_range
18050 + .global cris_flush_cache
18054 + move.d 16*1024, $r11
18057 + blt cris_flush_line
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
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>
18074 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
18076 +static struct notifier_block cris_sdram_freq_notifier_block = {
18077 + .notifier_call = cris_sdram_freq_notifier
18080 +static struct cpufreq_frequency_table cris_freq_table[] = {
18083 + {0, CPUFREQ_TABLE_END},
18086 +static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
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;
18093 +static void cris_freq_set_cpu_state (unsigned int state)
18096 + struct cpufreq_freqs freqs;
18097 + reg_config_rw_clk_ctrl clk_ctrl;
18098 + clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
18100 + for_each_cpu(i) {
18101 + freqs.old = cris_freq_get_cpu_frequency(i);
18102 + freqs.new = cris_freq_table[state].frequency;
18106 + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
18108 + local_irq_disable();
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;
18115 + clk_ctrl.pll = 0;
18116 + REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
18118 + local_irq_enable();
18120 + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
18123 +static int cris_freq_verify (struct cpufreq_policy *policy)
18125 + return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
18128 +static int cris_freq_target (struct cpufreq_policy *policy,
18129 + unsigned int target_freq,
18130 + unsigned int relation)
18132 + unsigned int newstate = 0;
18134 + if (cpufreq_frequency_table_target(policy, cris_freq_table, target_freq, relation, &newstate))
18137 + cris_freq_set_cpu_state(newstate);
18142 +static int cris_freq_cpu_init(struct cpufreq_policy *policy)
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);
18151 + result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
18155 + cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
18161 +static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
18163 + cpufreq_frequency_table_put_attr(policy->cpu);
18168 +static struct freq_attr* cris_freq_attr[] = {
18169 + &cpufreq_freq_attr_scaling_available_freqs,
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,
18184 +static int __init cris_freq_init(void)
18187 + ret = cpufreq_register_driver(&cris_freq_driver);
18188 + cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
18189 + CPUFREQ_TRANSITION_NOTIFIER);
18194 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
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);
18203 + if (freqs->new == 200000)
18204 + for (i = 0; i < 50000; i++);
18205 + REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
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
18216 #include <asm/arch/dma.h>
18217 #include <asm/arch/intmem.h>
18218 #include <asm/arch/pinmux.h>
18219 +#include <asm/arch/io.h>
18221 /* Functions for allocating DMA channels */
18222 EXPORT_SYMBOL(crisv32_request_dma);
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);
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
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>
18253 -#include <asm/irq.h>
18254 -#include <asm/arch/hwregs/intr_vect_defs.h>
18263 -struct dbg_port ports[] =
18264 +struct dbg_port ports[] =
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;
18279 -extern struct tty_driver *serial_driver;
18282 start_port(struct dbg_port* p)
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};
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;
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);
18306 -#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
18309 -console_write(struct console *co, const char *buf, unsigned int len)
18314 -/* Target debug */
18315 -#elif !defined(CONFIG_ETRAXFS_SIM)
18318 -console_write_direct(struct console *co, const char *buf, unsigned int len)
18321 - reg_ser_r_stat_din stat;
18322 - reg_ser_rw_tr_dma_en tr_dma_en, old;
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);
18332 - for (i = 0; i < len; i++) {
18334 - if (buf[i] == '\n') {
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');
18340 - /* Wait until transmitter is ready and send.*/
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]);
18347 - /* Restore mode */
18348 - if (tr_dma_en.en != old.en)
18349 - REG_WR(ser, port->instance, rw_tr_dma_en, old);
18353 -console_write(struct console *co, const char *buf, unsigned int len)
18357 - console_write_direct(co, buf, len);
18367 -console_write(struct console *co, const char *buf, unsigned int len)
18370 - pos = memchr(buf, '\n', len);
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;
18383 - memcpy(buffer + buffer_pos, buf, len);
18384 - buffer_pos += len;
18390 -int raw_printk(const char *fmt, ...)
18392 - static char buf[1024];
18395 - va_start(args, fmt);
18396 - printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
18398 - console_write(NULL, buf, strlen(buf));
18399 - return printed_len;
18403 -stupid_debug(char* buf)
18405 - console_write(NULL, buf, strlen(buf));
18408 #ifdef CONFIG_ETRAX_KGDB
18409 /* Use polling to get a single character from the kernel debug port */
18413 - reg_ser_rs_status_data stat;
18414 + reg_ser_rs_stat_din stat;
18415 reg_ser_rw_ack_intr ack_intr = { 0 };
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);
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);
18431 @@ -282,173 +166,18 @@
18433 putDebugChar(int val)
18435 - reg_ser_r_status_data stat;
18436 + reg_ser_r_stat_din stat;
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);
18445 #endif /* CONFIG_ETRAX_KGDB */
18448 -console_setup(struct console *co, char *options)
18453 - port = &ports[co->index];
18454 - port->baudrate = 115200;
18455 - port->parity = 'N';
18457 - port->baudrate = simple_strtoul(options, NULL, 10);
18459 - while(*s >= '0' && *s <= '9')
18461 - if (*s) port->parity = *s++;
18462 - if (*s) port->bits = *s++ - '0';
18463 - port->started = 0;
18464 - start_port(port);
18469 -/* This is a dummy serial device that throws away anything written to it.
18470 - * This is used when no debug output is wanted.
18472 -static struct tty_driver dummy_driver;
18474 -static int dummy_open(struct tty_struct *tty, struct file * filp)
18479 -static void dummy_close(struct tty_struct *tty, struct file * filp)
18483 -static int dummy_write(struct tty_struct * tty,
18484 - const unsigned char *buf, int count)
18490 -dummy_write_room(struct tty_struct *tty)
18496 -init_dummy_console(void)
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;
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");
18519 -static struct tty_driver*
18520 -crisv32_console_device(struct console* co, int *index)
18523 - *index = port->nbr;
18524 - return port ? serial_driver : &dummy_driver;
18527 -static struct console sercons = {
18529 - write: console_write,
18531 - device : crisv32_console_device,
18533 - setup : console_setup,
18534 - flags : CON_PRINTBUFFER,
18539 -static struct console sercons0 = {
18541 - write: console_write,
18543 - device : crisv32_console_device,
18545 - setup : console_setup,
18546 - flags : CON_PRINTBUFFER,
18552 -static struct console sercons1 = {
18554 - write: console_write,
18556 - device : crisv32_console_device,
18558 - setup : console_setup,
18559 - flags : CON_PRINTBUFFER,
18564 -static struct console sercons2 = {
18566 - write: console_write,
18568 - device : crisv32_console_device,
18570 - setup : console_setup,
18571 - flags : CON_PRINTBUFFER,
18576 -static struct console sercons3 = {
18578 - write: console_write,
18580 - device : crisv32_console_device,
18582 - setup : console_setup,
18583 - flags : CON_PRINTBUFFER,
18589 /* Register console for printk's, etc. */
18591 init_etrax_debug(void)
18593 - static int first = 1;
18596 - unregister_console(&sercons);
18597 - register_console(&sercons0);
18598 - register_console(&sercons1);
18599 - register_console(&sercons2);
18600 - register_console(&sercons3);
18601 - init_dummy_console();
18605 - register_console(&sercons);
18608 #ifdef CONFIG_ETRAX_KGDB
18609 @@ -456,5 +185,3 @@
18610 #endif /* CONFIG_ETRAX_KGDB */
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
18619 #include <asm/system.h>
18620 #include <asm/arch/arbiter.h>
18623 + * The memory region we allocated bandwidth for is stored in
18624 + * used_dma_channels as an in-use flag.
18626 +enum dma_region_allocated_marker {
18627 + DMA_NO_REGION_ALLOCATED = 0,
18628 + DMA_INT_REGION_ALLOCATED = 1,
18629 + DMA_EXT_REGION_ALLOCATED = 2
18632 static char used_dma_channels[MAX_DMA_CHANNELS];
18633 static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
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);
18641 if (options & DMA_PANIC_ON_ERROR)
18642 panic("request_dma error!");
18644 @@ -202,13 +212,14 @@
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;
18651 - panic("Invalid DMA channel for ext2\n");
18652 + panic("Invalid DMA channel for ext3\n");
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 @@
18664 void crisv32_free_dma(unsigned int dmanr)
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);
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
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
18688 .globl sys_call_table
18690 ; Check if preemptive kernel scheduling should be done.
18691 -#ifdef CONFIG_PREEMPT
18692 +#ifdef CONFIG_PREEMPT
18695 ; Load current task struct.
18698 ba ret_from_sys_call
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
18708 ; Note that di below is in delay slot.
18712 di ; So need_resched and sigpending don't change.
18714 @@ -107,19 +107,19 @@
18720 ;; The system_call is called by a BREAK instruction, which looks pretty
18721 ;; much like any other exception.
18723 ;; System calls can't be made from interrupts but we still stack ERP
18724 ;; to have a complete stack frame.
18727 ;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,
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
18738 @@ -151,7 +151,7 @@
18744 movs.w -ENOSYS, $r0
18745 addoq +PT_r10, $sp, $acr
18747 @@ -166,9 +166,9 @@
18748 bmi _syscall_trace_entry
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.
18759 @@ -177,7 +177,7 @@
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 @@
18774 ;; Actually to the system call.
18775 addo.d +sys_call_table, $r9, $acr
18776 move.d [$acr], $acr
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.
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.
18790 ;; Fall through into ret_from_sys_call to return.
18794 ;; R9 is a parameter:
18795 ;; >= 1 from syscall
18799 ;; Get the current task-struct pointer.
18800 - movs.w -8192, $r0 ; THREAD_SIZE == 8192
18801 + movs.w -8192, $r0 ; THREAD_SIZE == 8192
18804 di ; Make sure need_resched and sigpending don't change.
18807 addoq +TI_flags, $r0, $acr
18809 and.d _TIF_ALLWORK_MASK, $r1
18810 @@ -253,14 +253,14 @@
18812 ba _resume_userspace
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.
18825 move.d $r9, $r1 ; Preserve R9.
18827 @@ -281,28 +281,26 @@
18828 ;; Deal with pending signals and notify-resume requests.
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
18840 + move.d $r9, $r10 ; do_notify_resume syscall/irq param.
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
18850 _syscall_trace_entry:
18851 ;; PT_r10 in the frame contains -ENOSYS as required, at this point.
18854 jsr do_syscall_trace
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
18863 @@ -318,10 +316,10 @@
18865 addoq +PT_srp, $sp, $acr
18873 ;; Resume performs the actual task-switching, by switching stack
18874 ;; pointers. Input arguments are:
18876 @@ -331,7 +329,7 @@
18878 ;; Returns old current in R10.
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 @@
18887 addoq +THREAD_usp, $r10, $acr
18888 move $usp, [$acr] ; Save user-mode stackpointer.
18891 ;; See copy_thread for the reason why register R9 is saved.
18893 movem $r9, [$sp] ; Save non-scratch registers and R9.
18896 addoq +THREAD_ksp, $r10, $acr
18897 move.d $sp, [$acr] ; Save kernel SP for old task.
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 @@
18905 addoq +THREAD_usp, $r11, $acr
18906 move [$acr], $usp ; Restore user-mode stackpointer.
18909 addoq +THREAD_ccs, $r11, $acr
18910 move [$acr], $ccs ; Restore IRQ enable status.
18911 move.d [$sp+], $acr
18912 @@ -407,7 +405,7 @@
18914 move.d [$sp+], $acr
18921 @@ -419,7 +417,7 @@
18923 .comm cause_of_death, 4 ;; Don't declare this anywhere.
18925 -spurious_interrupt:
18926 +spurious_interrupt:
18928 jump hard_reset_now
18930 @@ -494,31 +492,38 @@
18931 ;; thread_info as first parameter
18933 moveq 5, $r11 ; SIGTRAP as second argument.
18934 - jsr ugdb_trap_user
18935 + jsr ugdb_trap_user
18937 jump ret_from_intr ; Use the return routine for interrupts.
18940 -gdb_handle_exception:
18942 +gdb_handle_exception:
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.
18958 _ugdb_handle_exception:
18959 ba do_sigtrap ; SIGTRAP the offending process.
18960 move.d [$sp+], $r0 ; Restore R0 in delay slot.
18962 + .global kernel_execve
18964 + move.d __NR_execve, $r9
18971 .section .rodata,"a"
18974 .long sys_restart_syscall ; 0 - old "setup()" system call, used
18977 @@ -647,7 +652,7 @@
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
18990 - .long sys_fstatfs64
18991 + .long sys_fstatfs64
18992 .long sys_tgkill /* 270 */
18994 .long sys_fadvise64_64
18995 @@ -805,7 +810,43 @@
18996 .long sys_mq_getsetattr
18997 .long sys_ni_syscall /* reserved for kexec */
19000 + .long sys_ni_syscall /* 285 */ /* available */
19001 + .long sys_add_key
19002 + .long sys_request_key
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
19019 + .long sys_symlinkat
19020 + .long sys_readlinkat /* 305 */
19021 + .long sys_fchmodat
19022 + .long sys_faccessat
19023 + .long sys_pselect6
19025 + .long sys_unshare /* 310 */
19026 + .long sys_set_robust_list
19027 + .long sys_set_robust_list
19028 + .long sys_get_robust_list
19030 + .long sys_sync_file_range
19031 + .long sys_tee /* 315 */
19032 + .long sys_vmsplice
19033 + .long sys_move_pages
19035 + .long sys_epoll_pwait
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
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
19050 -/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $
19052 * linux/arch/cris/kernel/fasttimer.c
19054 * Fast timers for ETRAX FS
19055 * This may be useful in other OS than Linux so use 2 space indentation...
19057 - * $Log: fasttimer.c,v $
19058 - * Revision 1.11 2005/01/04 11:15:46 starvik
19059 - * Don't share timer IRQ.
19061 - * Revision 1.10 2004/12/07 09:19:38 starvik
19062 - * Corrected includes.
19063 - * Use correct interrupt macros.
19065 - * Revision 1.9 2004/05/14 10:18:58 starvik
19066 - * Export fast_timer_list
19068 - * Revision 1.8 2004/05/14 07:58:03 starvik
19069 - * Merge of changes from 2.4
19071 - * Revision 1.7 2003/07/10 12:06:14 starvik
19072 - * Return IRQ_NONE if irq wasn't handled
19074 - * Revision 1.6 2003/07/04 08:27:49 starvik
19075 - * Merge of Linux 2.5.74
19077 - * Revision 1.5 2003/06/05 10:16:22 johana
19078 - * New INTR_VECT macros.
19080 - * Revision 1.4 2003/06/03 08:49:45 johana
19083 - * Revision 1.3 2003/06/02 12:51:27 johana
19085 - * Commented some include files that probably can be removed.
19087 - * Revision 1.2 2003/06/02 12:09:41 johana
19088 - * Ported to ETRAX FS using the trig interrupt instead of timer1.
19090 - * Revision 1.3 2002/12/12 08:26:32 starvik
19091 - * Don't use C-comments inside CVS comments
19093 - * Revision 1.2 2002/12/11 15:42:02 starvik
19094 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
19096 - * Revision 1.1 2002/11/18 07:58:06 starvik
19097 - * Fast timers (from Linux 2.4)
19099 - * Revision 1.5 2002/10/15 06:21:39 starvik
19100 - * Added call to init_waitqueue_head
19102 - * Revision 1.4 2002/05/28 17:47:59 johana
19103 - * Added del_fast_timer()
19105 - * Revision 1.3 2002/05/28 16:16:07 johana
19106 - * Handle empty fast_timer_list
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)
19112 - * Revision 1.1 2002/05/27 15:32:25 johana
19113 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
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
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.
19131 - * Revision 1.6 2000/12/13 14:02:08 johana
19132 - * Removed volatile for fast_timer_list
19134 - * Revision 1.5 2000/12/13 13:55:35 johana
19135 - * Added DEBUG_LOG, added som cli() and cleanup
19137 - * Revision 1.4 2000/12/05 13:48:50 johana
19138 - * Added range check when writing proc file, modified timer int handling
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
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.
19154 - * Revision 1.1 2000/10/26 15:49:16 johana
19155 - * Added fasttimer, highresolution timers.
19157 - * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
19158 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
19161 #include <linux/errno.h>
19162 @@ -128,13 +28,13 @@
19163 #include <asm/fasttimer.h>
19164 #include <linux/proc_fs.h>
19167 - * timer0 is running at 100MHz and generating jiffies timer ticks
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.
19179 @@ -151,19 +51,19 @@
19180 #define SANITYCHECK(x)
19190 #define __INLINE__ inline
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;
19207 struct fast_timer *fast_timer_list = NULL;
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;
19218 #define DEBUG_LOG(string, value) \
19220 @@ -202,48 +102,33 @@
19221 int timer_div_settings[NUM_TIMER_STATS];
19222 int timer_delay_settings[NUM_TIMER_STATS];
19224 +struct work_struct fast_work;
19227 -timer_trig_handler(void);
19228 +timer_trig_handler(void* dummy);
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)
19236 - unsigned long sec = jiffies;
19237 - unsigned long usec = GET_JIFFIES_USEC();
19239 - usec += (sec % HZ) * (1000000 / HZ);
19242 - if (usec > 1000000)
19247 - tv->tv_sec = sec;
19248 - tv->tv_usec = usec;
19249 + tv->tv_jiff = jiffies;
19250 + tv->tv_usec = GET_JIFFIES_USEC();
19253 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
19254 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
19256 - if (t0->tv_sec < t1->tv_sec)
19258 + /* Compare jiffies. Takes care of wrapping */
19259 + if (time_before(t0->tv_jiff, t1->tv_jiff))
19262 - else if (t0->tv_sec > t1->tv_sec)
19264 + else if (time_after(t0->tv_jiff, t1->tv_jiff))
19269 if (t0->tv_usec < t1->tv_usec)
19273 else if (t0->tv_usec > t1->tv_usec)
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;
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;
19292 + r_time0 = REG_RD(timer, regi_timer, r_time);
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);
19301 - /* Set timer values */
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;
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 */
19313 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
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);
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;
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;
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);
19352 /* In version 1.4 this function takes 27 - 50 us */
19353 @@ -327,7 +218,7 @@
19355 printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
19362 @@ -343,11 +234,11 @@
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)
19370 t->tv_expires.tv_usec -= 1000000;
19371 - t->tv_expires.tv_sec++;
19372 + t->tv_expires.tv_jiff += HZ;
19374 #ifdef FAST_TIMER_LOG
19375 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
19376 @@ -388,6 +279,7 @@
19378 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
19381 local_irq_restore(flags);
19382 } /* start_one_shot_timer */
19384 @@ -431,26 +323,32 @@
19385 /* Timer interrupt handler for trig interrupts */
19388 -timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
19389 +timer_trig_interrupt(int irq, void *dev_id)
19391 reg_timer_r_masked_intr masked_intr;
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)
19397 - timer_trig_handler();
19398 + timer_trig_handler(NULL);
19399 return IRQ_HANDLED;
19402 -static void timer_trig_handler(void)
19403 +static void timer_trig_handler(void* dummy)
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;
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.
19419 local_irq_save(flags);
19421 /* Clear timer trig interrupt */
19422 @@ -470,16 +368,17 @@
19423 fast_timer_running = 0;
19426 - local_irq_restore(flags);
19427 + fast_timer_function_type *f;
19430 t = fast_timer_list;
19433 - struct timeval tv;
19434 + struct fasttime_t tv;
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));
19441 if (timeval_cmp(&t->tv_expires, &tv) <= 0)
19443 @@ -490,7 +389,6 @@
19444 fast_timers_expired++;
19446 /* Remove this timer before call, since it may reuse the timer */
19447 - local_irq_save(flags);
19450 t->prev->next = t->next;
19451 @@ -505,11 +403,21 @@
19455 - local_irq_restore(flags);
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).
19468 - t->function(t->data);
19469 + /* Run the callback function with interrupts enabled. */
19470 + local_irq_restore(flags);
19472 + local_irq_save(flags);
19476 @@ -522,16 +430,19 @@
19480 - local_irq_save(flags);
19481 if ((t = fast_timer_list) != NULL)
19483 /* Start next timer.. */
19485 - struct timeval tv;
19487 + struct fasttime_t tv;
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);
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);
19500 if (!fast_timer_running)
19501 @@ -541,7 +452,6 @@
19503 start_timer_trig(us);
19505 - local_irq_restore(flags);
19509 @@ -552,9 +462,10 @@
19510 D1(printk("e! %d\n", us));
19513 - local_irq_restore(flags);
19516 + local_irq_restore(flags);
19520 D1(printk("ttrig stop!\n"));
19521 @@ -577,28 +488,17 @@
19522 void schedule_usleep(unsigned long us)
19524 struct fast_timer t;
19525 -#ifdef DECLARE_WAITQUEUE
19526 wait_queue_head_t sleep_wait;
19527 init_waitqueue_head(&sleep_wait);
19529 - DECLARE_WAITQUEUE(wait, current);
19531 - struct wait_queue *sleep_wait = NULL;
19532 - struct wait_queue wait = { current, NULL };
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,
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));
19547 D1(printk("done schedule_usleep(%d)\n", us));
19548 -#ifdef DECLARE_WAITQUEUE
19553 #ifdef CONFIG_PROC_FS
19554 @@ -638,7 +538,7 @@
19555 unsigned long flags;
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)))
19567 - bigbuf[0] = '\0';
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"
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,
19594 @@ -739,9 +640,9 @@
19595 "d: %6li us data: 0x%08lX"
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,
19606 @@ -759,9 +660,9 @@
19607 "d: %6li us data: 0x%08lX"
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,
19618 @@ -772,7 +673,6 @@
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))
19626 @@ -783,15 +683,15 @@
19627 /* " func: 0x%08lX" */
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,
19638 /* , t->function */
19640 - local_irq_disable();
19641 + local_irq_save(flags);
19642 if (t->next != nextt)
19644 printk("timer removed!\n");
19645 @@ -822,7 +722,7 @@
19646 static struct fast_timer tr[10];
19647 static int exp_num[10];
19649 -static struct timeval tv_exp[100];
19650 +static struct fasttime_t tv_exp[100];
19652 static void test_timeout(unsigned long data)
19654 @@ -860,7 +760,7 @@
19658 - struct timeval tv, tv0, tv1, tv2;
19659 + struct fasttime_t tv, tv0, tv1, tv2;
19661 printk("fast_timer_test() start\n");
19662 do_gettimeofday_fast(&tv);
19663 @@ -873,7 +773,7 @@
19665 do_gettimeofday_fast(&tv_exp[j]);
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);
19670 for (j = 0; j < 1000; j++)
19672 @@ -883,11 +783,11 @@
19673 for (j = 0; j < 100; j++)
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);
19688 do_gettimeofday_fast(&tv0);
19689 @@ -919,9 +819,9 @@
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");
19702 @@ -943,9 +843,9 @@
19703 printk("%-10s set: %6is %06ius exp: %6is %06ius "
19704 "data: 0x%08X func: 0x%08X\n",
19706 - t->tv_set.tv_sec,
19707 + t->tv_set.tv_jiff,
19709 - t->tv_expires.tv_sec,
19710 + t->tv_expires.tv_jiff,
19711 t->tv_expires.tv_usec,
19714 @@ -953,10 +853,10 @@
19716 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
19718 - tv_exp[j].tv_sec,
19719 + tv_exp[j].tv_jiff,
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);
19725 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
19726 printk("buf5 after all done:\n");
19727 @@ -966,7 +866,7 @@
19731 -void fast_timer_init(void)
19732 +int fast_timer_init(void)
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);
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))
19745 - printk("err: timer1 irq\n");
19746 + printk("err: fasttimer irq\n");
19748 fast_timer_is_init = 1;
19749 #ifdef FAST_TIMER_TEST
19750 @@ -992,4 +892,6 @@
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
19761 * Copyright (C) 2003, Axis Communications AB
19765 #define ASSEMBLER_MACROS_ONLY
19768 @@ -12,14 +11,21 @@
19769 * -traditional must not be used when assembling this file.
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>
19779 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
19780 +#include <asm/arch/hwregs/asm/gio_defs_asm.h>
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
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
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"
19806 @@ -42,13 +47,13 @@
19812 ;; This is the entry point of the kernel. The CPU is currently in
19813 ;; supervisor mode.
19816 ;; 0x00000000 if flash.
19817 ;; 0x40004000 if DRAM.
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
19828 -#ifdef CONFIG_ETRAXFS_SIM
19830 +#ifdef CONFIG_ETRAXFS_SIM
19831 ;; Set up minimal flash waitstates
19833 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
19834 move.d $r10, [$r11]
19839 +secondary_cpu_entry: /* Entry point for secondary CPUs */
19843 ;; Setup and enable the MMU. Use same configuration for both the data
19844 ;; and the instruction MMU.
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
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
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
19870 ;; Update instruction MMU.
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.
19879 ;; Enable data and instruction MMU.
19881 moveq 0xf, $r0 ; IMMU, DMMU, DCache, Icache on
19882 @@ -183,17 +193,11 @@
19892 - ; A slave waits for cpu_now_booting to be equal to CPU ID.
19893 - move.d cpu_now_booting, $r1
19898 ; Time to boot-up. Get stack location provided by master CPU.
19899 move.d smp_init_current_idle_thread, $r1
19901 @@ -203,9 +207,16 @@
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]
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.
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 @@
19932 - ;; Keep CRAMFS in flash.
19933 + ;; Check for cramfs.
19935 move.d romfs_length, $r1
19937 @@ -257,7 +269,8 @@
19938 cmp.d CRAMFS_MAGIC, $r0
19943 + ;; Set length and start of cramfs, set romfs_in_flash flag
19944 addoq +4, $r4, $acr
19946 move.d romfs_length, $r1
19947 @@ -273,35 +286,32 @@
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
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
19965 + cmp.d NAND_BOOT_MAGIC, $r12
19966 + bne move_cramfs ; not nand, jump
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
19975 + jump _start_it ; continue with boot
19979 - ;; Move the cramfs after BSS.
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.
19985 move.d romfs_length, $r1
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 @@
20002 ba _no_romfs_in_flash
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
20012 + ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
20013 addoq +4, $r9, $acr
20015 move.d romfs_length, $r1
20016 @@ -330,29 +342,45 @@
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
20030 - move.d __end, $r0
20032 + move.d __end, $r0
20035 - cmp.d CRAMFS_MAGIC, $r1
20037 + cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
20038 + beq 2f ; yes, jump
20040 + cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
20041 + bne 4f ; no, skip copy
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
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
20053 + ;; Now, move the root fs to after kernel's BSS
20055 - addoq +4, $r0, $acr
20056 - move.d [$acr], $r2
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
20066 -#ifndef CONFIG_ETRAXFS_SIM
20068 +#ifndef CONFIG_ETRAXFS_SIM
20069 + add.d $r2, $r0 ; copy from end and downwards
20073 lsrq 1, $r2 ; Size is in bytes, we copy words.
20076 @@ -364,17 +392,24 @@
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.
20089 move.d romfs_in_flash, $r1
20092 + move.d nand_boot, $r1
20093 + move.d $r0, [$r1]
20095 jump _start_it ; Jump to cached code.
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 @@
20107 move.d cris_command_line, $r10
20108 or.d 0x80000000, $r11 ; Make it virtual
20110 - move.b [$r11+], $r12
20111 - move.b $r12, [$r10+]
20113 + move.b [$r11+], $r1
20114 + move.b $r1, [$r10+]
20118 @@ -401,7 +436,7 @@
20119 move.d etrax_irv, $r1 ; Set the exception base register and pointer.
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
20127 @@ -429,17 +464,31 @@
20132 +; Variables for communication with the Axis flash map driver (axisflashmap),
20133 +; and for setting up memory in arch/cris/kernel/setup.c .
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)
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.
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.
20151 -crisv32_nand_boot:
20153 -crisv32_nand_cramfs_offset:
20156 +; nand_boot is set to 1 when the kernel has been booted from NAND flash
20160 swapper_pg_dir = 0xc0002000
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
20169 * Helper functions for I/O pins.
20171 - * Copyright (c) 2004 Axis Communications AB.
20172 + * Copyright (c) 2004, 2006 Axis Communications AB.
20175 #include <linux/types.h>
20177 #include <asm/arch/pinmux.h>
20178 #include <asm/arch/hwregs/gio_defs.h>
20184 struct crisv32_ioport crisv32_ioports[] =
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),
20195 #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
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)
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);
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);
20228 + crisv32_led_net0_red = dummy_led;
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);
20238 + crisv32_led_net1_red = dummy_led;
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);
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);
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;
20261 __initcall(crisv32_io_init);
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)
20267 - if (port > NBR_OF_PORTS)
20268 + if (port > NBR_OF_PORTS)
20270 if (port > crisv32_ioports[port].pin_count)
20272 @@ -111,14 +137,17 @@
20273 iopin->bit = 1 << pin;
20274 iopin->port = &crisv32_ioports[port];
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))
20282 + DEBUG(printk("crisv32_io_get: Allocated pin %d on port %d\n", pin, port ));
20287 int crisv32_io_get_name(struct crisv32_iopin* iopin,
20289 + const char* name)
20293 @@ -128,7 +157,7 @@
20295 if (toupper(*name) < 'A' || toupper(*name) > 'E')
20299 port = toupper(*name) - 'A';
20301 pin = simple_strtoul(name, NULL, 10);
20302 @@ -139,9 +168,12 @@
20303 iopin->bit = 1 << pin;
20304 iopin->port = &crisv32_ioports[port];
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))
20312 + DEBUG(printk("crisv32_io_get_name: Allocated pin %d on port %d\n", pin, port));
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. */
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}};
20327 -static unsigned long irq_regs[NR_CPUS] =
20328 +static unsigned long irq_regs[NR_CPUS] =
20333 extern void kgdb_init(void);
20334 extern void breakpoint(void);
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
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.
20344 BUILD_IRQ(0x31, (1 << 0)) /* memarb */
20345 @@ -139,7 +139,7 @@
20347 spin_lock_irqsave(&irq_lock, flags);
20348 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20351 /* Remember; 1 let thru, 0 block. */
20352 intr_mask &= ~(1 << (irq - FIRST_IRQ));
20354 @@ -152,10 +152,10 @@
20357 unsigned long flags;
20360 spin_lock_irqsave(&irq_lock, flags);
20361 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20364 /* Remember; 1 let thru, 0 block. */
20365 intr_mask |= (1 << (irq - FIRST_IRQ));
20367 @@ -168,7 +168,7 @@
20370 unsigned long flags;
20373 spin_lock_irqsave(&irq_lock, flags);
20374 cpu = irq_allocations[irq - FIRST_IRQ].cpu;
20376 @@ -178,12 +178,12 @@
20377 spin_unlock_irqrestore(&irq_lock, flags);
20378 return smp_processor_id();
20383 /* Let the interrupt stay if possible */
20384 if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
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:
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();
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.
20409 /* Get which IRQs that happend. */
20410 masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
20413 /* Calculate new IRQ mask with these IRQs disabled. */
20414 mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20417 /* Timer IRQ is never masked */
20418 if (masked & TIMER_MASK)
20419 - mask |= TIMER_MASK;
20420 + mask |= TIMER_MASK;
20422 /* Block all the IRQs */
20423 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask);
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);
20434 /* Remove IRQs that can't be handled as multiple. */
20435 - masked &= ~IGNORE_MASK;
20436 + masked &= ~IGNORE_MASK;
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;
20446 set_exception_vector(0x00, nmi_interrupt);
20447 set_exception_vector(0x30, multiple_interrupt);
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
20453 * kgdb usage notes:
20454 * -----------------
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().
20468 * The following gdb commands are supported:
20470 @@ -382,8 +382,8 @@
20471 int getDebugChar(void);
20473 #ifdef CONFIG_ETRAXFS_SIM
20474 -int getDebugChar(void)
20476 +int getDebugChar(void)
20478 return socketread();
20481 @@ -490,7 +490,7 @@
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)
20496 for (s = s1; (*s++ = *s2++) != '\0'; )
20499 @@ -522,7 +522,7 @@
20500 gdb_cris_strlen(const char *s)
20505 for (sc = s; *sc != '\0'; sc++)
20508 @@ -534,7 +534,7 @@
20510 const unsigned char uc = c;
20511 const unsigned char *su;
20514 for (su = s; 0 < n; ++su, --n)
20517 @@ -549,15 +549,15 @@
20523 for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)
20524 x = x * base + (sd - hexchars);
20528 /* Unconverted suffix is stored in endptr unless endptr is NULL. */
20536 @@ -629,7 +629,7 @@
20537 } else if (regno == PID) {
20538 /* 32-bit register. */
20539 *valptr = *(unsigned int *)((char *)®.pid);
20542 } else if (regno == SRS) {
20543 /* 8-bit register. */
20544 *valptr = (unsigned int)(*(unsigned char *)((char *)®.srs));
20545 @@ -726,7 +726,7 @@
20546 *buf++ = highhex (ch);
20547 *buf++ = lowhex (ch);
20551 /* Terminate properly. */
20554 @@ -804,7 +804,7 @@
20561 xmitcsum = hex(getDebugChar()) << 4;
20562 xmitcsum += hex(getDebugChar());
20563 @@ -836,7 +836,7 @@
20570 char *src = buffer;
20572 @@ -905,42 +905,42 @@
20574 char *ptr = output_buffer;
20575 unsigned int reg_cont;
20578 /* Send trap type (converted to signal) */
20582 *ptr++ = highhex(sigval);
20583 *ptr++ = lowhex(sigval);
20585 if (((reg.exs & 0xff00) >> 8) == 0xc) {
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;
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;
20603 /* Instruction watchpoint. */
20604 /* FIXME: Check against, and possibly adjust reported EDA. */
20606 /* Data watchpoint. Find the one that triggered. */
20607 for (bp = 0; bp < 6; bp++) {
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;
20616 /* Get read/write trig bits for this BP. */
20617 trig_bits = (S & (3 << bitpos_trig)) >> bitpos_trig;
20620 /* Read/write config bits for this BP. */
20621 rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
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");
20629 /* Mark this BP as trigged for future reference. */
20630 trig_mask |= (1 << bp);
20632 - if (reg.eda >= bp_d_regs[bp * 2] &&
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 @@
20640 /* Read/write config bits for this BP (needed later). */
20641 rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
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 @@
20653 /* No match yet? */
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) {
20662 @@ -1110,12 +1110,12 @@
20664 if (sigval == SIGTRAP) {
20665 /* Break 8, single step or hardware breakpoint exception. */
20668 /* Check IDX field of EXS. */
20669 if (((reg.exs & 0xff00) >> 8) == 0x18) {
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 @@
20683 } else if (((reg.exs & 0xff00) >> 8) == 0x3) {
20685 /* Don't fiddle with S1. */
20686 @@ -1190,10 +1190,10 @@
20687 unsigned int *bp_d_regs = &sreg.s3_3;
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. */
20698 /* First, find a free data watchpoint. */
20699 @@ -1205,13 +1205,13 @@
20706 /* We're out of watchpoints. */
20707 gdb_cris_strcpy(output_buffer, error_message[E04]);
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));
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);
20727 /* Set the S1 flag to enable watchpoints. */
20728 reg.ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
20729 @@ -1258,7 +1258,7 @@
20731 gdb_cris_strcpy(output_buffer, error_message[E04]);
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. */
20743 - /* Ugly pointer arithmetic, since I cannot rely on a
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. */
20749 @@ -1279,7 +1279,7 @@
20750 /* Matching range. */
20751 int bitpos = 2 + bp * 4;
20755 /* Read/write bits for this BP. */
20756 rw_bits = (sreg.s0_3 & (0x3 << bitpos)) >> bitpos;
20758 @@ -1347,7 +1347,7 @@
20759 (char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
20760 16 * sizeof(unsigned int));
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 *)®, &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");
20779 /* Write register. Pn...=r...
20780 Write register n..., hex value without 0x, with value r...,
20781 @@ -1393,7 +1393,7 @@
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);
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 @@
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));
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. */
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 @@
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];
20842 remove_watchpoint(type, addr, len);
20845 @@ -1537,14 +1537,14 @@
20846 output_buffer[2] = lowhex(sigval);
20847 output_buffer[3] = 0;
20852 /* Detach from host. D
20853 Success: OK, and return to the executing thread.
20854 Failure: will never know */
20861 /* kill request or reset request.
20862 @@ -1552,7 +1552,7 @@
20863 Failure: will never know. */
20871 @@ -1570,7 +1570,7 @@
20872 and ignored (below)? */
20873 gdb_cris_strcpy(output_buffer, error_message[E04]);
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 @@
20882 reg_intr_vect_rw_mask intr_mask;
20883 reg_ser_rw_intr_mask ser_intr_mask;
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);
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);
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);
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);
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);
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
20938 .globl kgdb_handle_exception
20940 kgdb_handle_exception:
20943 ;; Create a register image of the caller.
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
20952 ;; Check what got us here: get IDX field of EXS.
20955 @@ -307,7 +307,7 @@
20957 move.d internal_stack+1020, $sp ; Use the internal stack which grows upwards
20958 jsr handle_exception ; Interactive routine
20963 ;; Return to the caller
20964 @@ -345,7 +345,7 @@
20965 ;; Nothing in S6 - S7, bank 0.
20973 @@ -507,7 +507,7 @@
20980 move [$acr], $pid ; Restore PID
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
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.
20993 * Copyright (c) 2004 Axis Communications AB.
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);
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 @@
21013 -crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21015 + * must be called with the pinmux_lock held.
21017 +static int __crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
21018 + enum pin_mode mode)
21021 - unsigned long flags;
21023 - crisv32_pinmux_init();
21025 - if (port > PORTS)
21026 + if (port >= PORTS ||
21027 + first_pin < 0 || last_pin >= PORT_PINS || last_pin < first_pin)
21030 - spin_lock_irqsave(&pinmux_lock, flags);
21032 - for (i = first_pin; i <= last_pin; i++)
21034 + for (i = first_pin; i <= last_pin; i++)
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))
21042 - spin_unlock_irqrestore(&pinmux_lock, flags);
21044 panic("Pinmux alloc failed!\n");
21051 for (i = first_pin; i <= last_pin; i++)
21052 pins[port][i] = mode;
21054 crisv32_pinmux_set(port);
21056 - spin_unlock_irqrestore(&pinmux_lock, flags);
21062 +crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21065 + unsigned long flags;
21067 + crisv32_pinmux_init();
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);
21076 crisv32_pinmux_alloc_fixed(enum fixed_function function)
21079 char saved[sizeof pins];
21080 unsigned long flags;
21082 + reg_pinmux_rw_hwprot hwprot;
21084 + crisv32_pinmux_init();
21086 spin_lock_irqsave(&pinmux_lock, flags);
21088 /* Save internal data for recovery */
21089 memcpy(saved, pins, sizeof pins);
21091 - reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21094 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
21176 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21178 memcpy(pins, saved, sizeof pins);
21180 - spin_unlock_irqrestore(&pinmux_lock, flags);
21184 + spin_unlock_irqrestore(&pinmux_lock, flags);
21190 @@ -189,33 +203,126 @@
21195 -crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21197 + * must be called with the pinmux_lock held.
21199 +static int __crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21203 + if (port > PORTS)
21206 + for (i = first_pin; i <= last_pin; i++)
21207 + pins[port][i] = pinmux_none;
21209 + crisv32_pinmux_set(port);
21214 +int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21217 unsigned long flags;
21219 crisv32_pinmux_init();
21221 + spin_lock_irqsave(&pinmux_lock, flags);
21222 + r = __crisv32_pinmux_dealloc(port, first_pin, last_pin);
21223 + spin_unlock_irqrestore(&pinmux_lock, flags);
21227 - if (port > PORTS)
21230 +crisv32_pinmux_dealloc_fixed(enum fixed_function function)
21232 + int ret = -EINVAL;
21233 + char saved[sizeof pins];
21234 + unsigned long flags;
21236 spin_lock_irqsave(&pinmux_lock, flags);
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);
21243 + reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21247 + case pinmux_ser1:
21248 + ret = __crisv32_pinmux_dealloc(PORT_C, 4, 7);
21249 + hwprot.ser1 = regk_pinmux_no;
21251 + case pinmux_ser2:
21252 + ret = __crisv32_pinmux_dealloc(PORT_C, 8, 11);
21253 + hwprot.ser2 = regk_pinmux_no;
21255 + case pinmux_ser3:
21256 + ret = __crisv32_pinmux_dealloc(PORT_C, 12, 15);
21257 + hwprot.ser3 = regk_pinmux_no;
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;
21264 + case pinmux_sser1:
21265 + ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
21266 + hwprot.sser1 = regk_pinmux_no;
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;
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;
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;
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;
21289 + ret = __crisv32_pinmux_dealloc(PORT_B, 0, 15);
21290 + ret |= __crisv32_pinmux_dealloc(PORT_D, 8, 15);
21291 + hwprot.ata = regk_pinmux_no;
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;
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);
21306 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21308 + memcpy(pins, saved, sizeof pins);
21310 - crisv32_pinmux_set(port);
21311 spin_unlock_irqrestore(&pinmux_lock, flags);
21319 crisv32_pinmux_dump(void)
21324 crisv32_pinmux_init();
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
21333 reg_timer_rw_wd_ctrl wd_ctrl = {0};
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 @@
21344 struct pt_regs *childregs;
21345 struct switch_stack *swstack;
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. */
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.
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. */
21366 * We want to return into ret_from_sys_call after the _resume.
21367 * ret_from_fork will call ret_from_sys_call.
21369 swstack->return_ip = (unsigned long) ret_from_fork;
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;
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 @@
21387 /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
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)
21394 @@ -209,11 +209,11 @@
21395 return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
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.
21405 sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
21406 struct pt_regs *regs)
21408 @@ -222,7 +222,7 @@
21410 /* sys_execve() executes a new program. */
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)
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);
21423 printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
21424 regs->r0, regs->r1, regs->r2, regs->r3);
21427 printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
21428 regs->r4, regs->r5, regs->r6, regs->r7);
21431 printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
21432 regs->r8, regs->r9, regs->r10, regs->r11);
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
21438 #include <asm/processor.h>
21439 #include <asm/arch/hwregs/supp_reg.h>
21443 * Determines which bits in CCS the user has access to.
21444 * 1 = access, 0 = no access.
21448 * Make sure the single step bit is not set.
21452 ptrace_disable(struct task_struct *child)
21455 @@ -105,7 +105,7 @@
21456 unsigned long __user *datap = (unsigned long __user *)data;
21459 - /* Read word at location address. */
21460 + /* Read word at location address. */
21461 case PTRACE_PEEKTEXT:
21462 case PTRACE_PEEKDATA: {
21464 @@ -122,11 +122,11 @@
21465 tmp = *(unsigned long*)addr;
21467 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21470 if (copied != sizeof(tmp))
21475 ret = put_user(tmp,datap);
21478 @@ -143,18 +143,18 @@
21479 ret = put_user(tmp, datap);
21484 /* Write the word at location address. */
21485 case PTRACE_POKETEXT:
21486 case PTRACE_POKEDATA:
21490 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
21498 /* Write the word at location address in the USER area. */
21499 case PTRACE_POKEUSR:
21501 @@ -178,10 +178,10 @@
21502 case PTRACE_SYSCALL:
21507 if (!valid_signal(data))
21511 /* Continue means no single-step. */
21512 put_reg(child, PT_SPC, 0);
21514 @@ -198,27 +198,27 @@
21516 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21520 child->exit_code = data;
21523 /* TODO: make sure any pending breakpoint is killed */
21524 wake_up_process(child);
21531 /* Make the child exit by sending it a sigkill. */
21536 if (child->exit_state == EXIT_ZOMBIE)
21540 child->exit_code = SIGKILL;
21543 /* Deconfigure single-step and h/w bp. */
21544 ptrace_disable(child);
21547 /* TODO: make sure any pending breakpoint is killed */
21548 wake_up_process(child);
21550 @@ -227,7 +227,7 @@
21551 case PTRACE_SINGLESTEP: {
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 @@
21561 if (!valid_signal(data))
21565 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21567 /* TODO: set some clever breakpoint mechanism... */
21568 @@ -259,15 +259,15 @@
21569 case PTRACE_GETREGS: {
21574 for (i = 0; i <= PT_MAX; i++) {
21575 tmp = get_reg(child, i);
21578 if (put_user(tmp, datap)) {
21587 @@ -279,22 +279,22 @@
21588 case PTRACE_SETREGS: {
21593 for (i = 0; i <= PT_MAX; i++) {
21594 if (get_user(tmp, datap)) {
21602 tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
21606 put_reg(child, i, tmp);
21614 @@ -304,6 +304,7 @@
21622 @@ -311,15 +312,15 @@
21624 if (!test_thread_flag(TIF_SYSCALL_TRACE))
21628 if (!(current->ptrace & PT_PTRACED))
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)
21639 * This isn't the same as continuing with a signal, but it will do for
21641 @@ -338,7 +339,7 @@
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))
21650 @@ -361,7 +362,7 @@
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",
21659 @@ -378,7 +379,7 @@
21660 /* Delay slot bit set. Report as stopped on proper
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
21668 @@ -422,7 +423,7 @@
21669 register int old_srs;
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;
21677 @@ -431,7 +432,7 @@
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;
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);
21692 switch (regno - PT_BP) {
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 @@
21700 {"ETRAX 100LX", 10, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21701 | HAS_MMU | HAS_MMU_BUG},
21704 {"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21708 {"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
21711 {"Unknown", 0, 0, 0}
21720 for (i = 0; i < entries; i++) {
21721 if (cpinfo[i].rev == revision) {
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
21727 unsigned char retcode[8]; /* Trampoline code. */
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);
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)
21739 - sigset_t saveset;
21741 mask &= _BLOCKABLE;
21743 spin_lock_irq(¤t->sighand->siglock);
21745 - saveset = current->blocked;
21747 + current->saved_sigmask = current->blocked;
21748 siginitset(¤t->blocked, mask);
21750 recalc_sigpending();
21751 spin_unlock_irq(¤t->sighand->siglock);
21753 - regs->r10 = -EINTR;
21756 - current->state = TASK_INTERRUPTIBLE;
21759 - if (do_signal(0, &saveset, regs)) {
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.
21769 - return regs->r10;
21774 -/* Define some dummy arguments to be able to reach the regs argument. */
21776 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
21777 - long mof, long srp, struct pt_regs *regs)
21779 - sigset_t saveset;
21782 - if (sigsetsize != sizeof(sigset_t))
21785 - if (copy_from_user(&newset, unewset, sizeof(newset)))
21788 - sigdelsetmask(&newset, ~_BLOCKABLE);
21789 - spin_lock_irq(¤t->sighand->siglock);
21791 - saveset = current->blocked;
21792 - current->blocked = newset;
21794 - recalc_sigpending();
21795 - spin_unlock_irq(¤t->sighand->siglock);
21797 - regs->r10 = -EINTR;
21800 - current->state = TASK_INTERRUPTIBLE;
21803 - if (do_signal(0, &saveset, regs)) {
21804 - /* See comment in function above. */
21805 - return regs->r10;
21808 + current->state = TASK_INTERRUPTIBLE;
21810 + set_thread_flag(TIF_RESTORE_SIGMASK);
21811 + return -ERESTARTNOHAND;
21815 @@ -263,7 +205,7 @@
21816 unsigned long oldccs = regs->ccs;
21818 frame = (struct rt_signal_frame *) rdusp();
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 @@
21826 recalc_sigpending();
21827 spin_unlock_irq(¤t->sighand->siglock);
21830 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
21833 @@ -311,7 +253,7 @@
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
21848 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
21849 struct pt_regs * regs)
21851 @@ -388,7 +330,7 @@
21852 /* Trampoline - the desired return ip is in the signal return page. */
21853 return_ip = cris_signal_return_page;
21857 * This is movu.w __NR_sigreturn, r9; break 13;
21859 * WE DO NOT USE IT ANY MORE! It's only left here for historical
21860 @@ -402,7 +344,7 @@
21867 * Set up registers for signal handler.
21869 @@ -417,16 +359,17 @@
21870 /* Actually move the USP to reflect the stacked frame. */
21871 wrusp((unsigned long)frame);
21877 if (sig == SIGSEGV)
21878 ka->sa.sa_handler = SIG_DFL;
21881 force_sig(SIGSEGV, current);
21887 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
21888 sigset_t *set, struct pt_regs * regs)
21890 @@ -441,11 +384,11 @@
21893 /* TODO: what is the current->exec_domain stuff and invmap ? */
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);
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;
21910 * This is movu.w __NR_rt_sigreturn, r9; break 13;
21912 * WE DO NOT USE IT ANY MORE! It's only left here for historical
21913 @@ -478,7 +421,7 @@
21915 err |= __put_user(__NR_rt_sigreturn,
21916 (short __user*)(frame->retcode+2));
21919 err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
21922 @@ -503,21 +446,24 @@
21923 /* Actually move the usp to reflect the stacked frame. */
21924 wrusp((unsigned long)frame);
21930 if (sig == SIGSEGV)
21931 ka->sa.sa_handler = SIG_DFL;
21934 force_sig(SIGSEGV, current);
21938 /* Invoke a singal handler to, well, handle the signal. */
21939 -static inline void
21941 handle_signal(int canrestart, unsigned long sig,
21942 siginfo_t *info, struct k_sigaction *ka,
21943 sigset_t *oldset, struct pt_regs * regs)
21947 /* Check if this got called from a system call. */
21949 /* If so, check system call restarting. */
21950 @@ -561,19 +507,23 @@
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);
21957 - setup_frame(sig, ka, oldset, regs);
21958 + ret = setup_frame(sig, ka, oldset, regs);
21960 if (ka->sa.sa_flags & SA_ONESHOT)
21961 ka->sa.sa_handler = SIG_DFL;
21963 - spin_lock_irq(¤t->sighand->siglock);
21964 - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
21965 - if (!(ka->sa.sa_flags & SA_NODEFER))
21966 - sigaddset(¤t->blocked,sig);
21967 - recalc_sigpending();
21968 - spin_unlock_irq(¤t->sighand->siglock);
21970 + spin_lock_irq(¤t->sighand->siglock);
21971 + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
21972 + if (!(ka->sa.sa_flags & SA_NODEFER))
21973 + sigaddset(¤t->blocked,sig);
21974 + recalc_sigpending();
21975 + spin_unlock_irq(¤t->sighand->siglock);
21982 @@ -587,12 +537,13 @@
21983 * we can use user_mode(regs) to see if we came directly from kernel or user
21987 -do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
21989 +do_signal(int canrestart, struct pt_regs *regs)
21993 struct k_sigaction ka;
21994 + sigset_t *oldset;
21997 * The common case should go fast, which is why this point is
21998 @@ -600,17 +551,27 @@
21999 * without doing anything.
22001 if (!user_mode(regs))
22006 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
22007 + oldset = ¤t->saved_sigmask;
22009 oldset = ¤t->blocked;
22011 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
22015 - /* Deliver the signal. */
22016 - handle_signal(canrestart, signr, &info, &ka, oldset, regs);
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);
22031 /* Got here from a system call? */
22032 @@ -621,14 +582,19 @@
22033 regs->r10 == -ERESTARTNOINTR) {
22034 RESTART_CRIS_SYS(regs);
22038 if (regs->r10 == -ERESTART_RESTARTBLOCK){
22039 regs->r10 = __NR_restart_syscall;
22046 + /* if there's no signal to deliver, we just put the saved sigmask
22048 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
22049 + clear_thread_flag(TIF_RESTORE_SIGMASK);
22050 + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
22055 @@ -651,7 +617,7 @@
22056 sys_kill(ti->task->pid, sig);
22061 keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
22062 struct pt_regs *regs)
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;
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. */
22076 regs->ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
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
22086 #define IPI_SCHEDULE 1
22088 #define IPI_FLUSH_TLB 4
22089 +#define IPI_BOOT 8
22091 #define FLUSH_ALL (void*)0xffffffff
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);
22101 /* Variables used during SMP boot */
22103 extern int setup_irq(int, struct irqaction *);
22105 /* Mode registers */
22106 -static unsigned long irq_regs[NR_CPUS] =
22107 +static unsigned long irq_regs[NR_CPUS] =
22113 cpu_set(0, cpu_online_map);
22114 cpu_set(0, phys_cpu_present_map);
22115 + cpu_set(0, cpu_possible_map);
22118 void __init smp_cpus_done(unsigned int max_cpus)
22119 @@ -109,6 +113,7 @@
22122 struct task_struct *idle;
22123 + cpumask_t cpu_mask = CPU_MASK_NONE;
22125 idle = fork_idle(cpuid);
22127 @@ -120,6 +125,12 @@
22128 smp_init_current_idle_thread = task_thread_info(idle);
22129 cpu_now_booting = cpuid;
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);
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)
22144 - extern void cpu_idle(void);
22145 + extern void cpu_idle(void);
22147 int cpu = cpu_now_booting;
22148 reg_intr_vect_rw_mask vect_mask = {0};
22149 @@ -190,8 +201,8 @@
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
22155 + * a process to another CPU. Our cache is rather small so we report
22158 unsigned long cache_decay_ticks = 1;
22160 @@ -205,14 +216,14 @@
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);
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.
22175 void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned long addr)
22177 @@ -244,7 +255,7 @@
22178 cpu_set(smp_processor_id(), mm->cpu_vm_mask);
22181 -void flush_tlb_page(struct vm_area_struct *vma,
22182 +void flush_tlb_page(struct vm_area_struct *vma,
22183 unsigned long addr)
22185 __flush_tlb_page(vma, addr);
22186 @@ -252,8 +263,8 @@
22189 /* Inter processor interrupts
22191 - * The IPIs are used for:
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);
22201 - __flush_tlb_page(flush_vma, flush_addr);
22202 + __flush_tlb_page(flush_vma, flush_addr);
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
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 $
22213 * linux/arch/cris/arch-v32/kernel/time.c
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>
22228 #include <asm/arch/hwregs/reg_map.h>
22229 #include <asm/arch/hwregs/reg_rdwr.h>
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 */
22234 -unsigned long timer_regs[NR_CPUS] =
22235 +unsigned long timer_regs[NR_CPUS] =
22240 extern int setup_irq(int, struct irqaction *);
22241 extern int have_rtc;
22243 +#ifdef CONFIG_CPU_FREQ
22245 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
22247 +static struct notifier_block cris_time_freq_notifier_block = {
22248 + .notifier_call = cris_time_freq_notifier
22252 unsigned long get_ns_in_jiffie(void)
22254 reg_timer_r_tmr0_data data;
22256 static unsigned long jiffies_p = 0;
22259 - * cache volatile jiffies temporarily; we have IRQs turned off.
22260 + * cache volatile jiffies temporarily; we have IRQs turned off.
22262 unsigned long jiffies_t;
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
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
22281 /* This gives us 1.3 ms to do something useful when the NMI comes */
22282 @@ -124,7 +135,7 @@
22284 #if defined(CONFIG_ETRAX_WATCHDOG)
22285 reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
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 @@
22293 /* stop the watchdog - we still need the correct key */
22297 stop_watchdog(void)
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);
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;
22313 - raw_printk("Watchdog bite\n");
22314 + oops_in_progress = 1;
22315 + printk("Watchdog bite\n");
22317 /* Check if forced restart or unexpected watchdog */
22318 if (cause_of_death == 0xbedead) {
22319 @@ -169,8 +181,9 @@
22321 /* Unexpected watchdog, stop the watchdog and dump registers*/
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
22331 @@ -191,8 +204,9 @@
22332 extern void cris_do_profile(struct pt_regs *regs);
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)
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.
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
22350 if ((time_status & STA_UNSYNC) == 0 &&
22351 @@ -246,7 +260,7 @@
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,
22360 @@ -262,7 +276,7 @@
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.
22369 @@ -284,11 +298,11 @@
22371 reg_intr_vect_rw_mask intr_mask;
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.
22384 loops_per_usec = 50;
22386 @@ -297,7 +311,7 @@
22392 /* get the current time */
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);
22401 /* now actually register the timer irq handler that calls timer_interrupt() */
22404 setup_irq(TIMER_INTR_VECT, &irq_timer);
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).
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). */
22417 unsigned long flags;
22418 local_save_flags(flags);
22419 @@ -341,4 +352,27 @@
22420 local_irq_restore(flags);
22424 +#ifdef CONFIG_CPU_FREQ
22425 + cpufreq_register_notifier(&cris_time_freq_notifier_block,
22426 + CPUFREQ_TRANSITION_NOTIFIER);
22430 +#ifdef CONFIG_CPU_FREQ
22432 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
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;
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);
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
22452 - * Copyright (C) 2003, Axis Communications AB.
22453 + * Copyright (C) 2003-2006, Axis Communications AB.
22456 #include <linux/ptrace.h>
22457 #include <asm/uaccess.h>
22459 #include <asm/arch/hwregs/supp_reg.h>
22461 -extern void reset_watchdog(void);
22462 -extern void stop_watchdog(void);
22464 -extern int raw_printk(const char *fmt, ...);
22465 +#include <asm/arch/hwregs/intr_vect_defs.h>
22468 show_registers(struct pt_regs *regs)
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.
22478 - unsigned long usp;
22479 + unsigned long usp = rdusp();
22480 unsigned long d_mmu_cause;
22481 unsigned long i_mmu_cause;
22484 + printk("CPU: %d\n", smp_processor_id());
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);
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);
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);
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);
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);
22510 - raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
22511 - regs->r12, regs->r13, regs->orig_r10, regs->acr);
22513 - raw_printk("sp: %08lx\n", regs);
22514 + printk(" sp: %08lx\n", (unsigned long)regs);
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);
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);
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);
22532 - /* Show additional info if in kernel-mode. */
22534 + * When in-kernel, we also print out the stack and code at the
22535 + * time of the fault..
22537 if (!user_mode(regs)) {
22541 - show_stack(NULL, (unsigned long *) usp);
22542 + show_stack(NULL, (unsigned long *)usp);
22545 * If the previous stack-dump wasn't a kernel one, dump the
22548 show_stack(NULL, NULL);
22550 - raw_printk("\nCode: ");
22551 + printk("\nCode: ");
22553 if (regs->erp < PAGE_OFFSET)
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.
22562 for (i = -12; i < 12; i++) {
22563 - if (__get_user(c, &((unsigned char *) regs->erp)[i])) {
22566 + if (__get_user(c, &((unsigned char *)regs->erp)[i])) {
22568 - raw_printk(" Bad IP value.");
22569 + printk(" Bad IP value.");
22574 - raw_printk("(%02x) ", c);
22575 + printk("(%02x) ", c);
22577 - raw_printk("%02x ", c);
22578 + printk("%02x ", c);
22581 - raw_printk("\n");
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.
22592 -watchdog_bite_hook(struct pt_regs *regs)
22593 +arch_enable_nmi(void)
22595 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22596 - local_irq_disable();
22598 - show_registers(regs);
22601 - ; /* Do nothing. */
22603 - show_registers(regs);
22605 + unsigned long flags;
22607 + local_save_flags(flags);
22608 + flags |= (1 << 30); /* NMI M flag is at bit 30 */
22609 + local_irq_restore(flags);
22612 -/* This is normally the Oops function. */
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)
22618 - if (user_mode(regs))
22620 + reg_intr_vect_r_nmi r;
22622 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
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.
22631 - raw_printk("%s: %04lx\n", str, err & 0xffff);
22633 + nmi_handler(regs);
22635 - show_registers(regs);
22637 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22638 - reset_watchdog();
22641 - do_exit(SIGSEGV);
22642 + /* Wait until nmi is no longer active. */
22644 + r = REG_RD(intr_vect, regi_irq, r_nmi);
22645 + } while (r.ext == regk_intr_vect_on);
22648 -void arch_enable_nmi(void)
22649 +#ifdef CONFIG_DEBUG_BUGVERBOSE
22651 +handle_BUG(struct pt_regs *regs)
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;
22659 + unsigned long erp = regs->erp;
22661 + if (__copy_from_user(&f, (const void __user *)(erp - 8), sizeof f))
22663 + if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
22665 + if (__get_user(c, f.filename))
22666 + f.filename = "<bad filename>";
22668 + printk("kernel BUG at %s:%d!\n", f.filename, f.line);
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
22675 -// $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $
22677 -// Call simulator hook. This is the part running in the
22678 -// simulated program.
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>
22686 -#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
22687 -#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
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]
22695 -// ------------------------------------------------------------------ hook_call
22696 -int hook_call( unsigned id, unsigned pcnt, ...) {
22701 - PREEMPT_OFF_SAVE();
22704 - // pass parameters
22705 - HOOK_DATA(0) = id;
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
22711 - if (id == hook_print_str) {
22715 - HOOK_DATA(1) = pcnt;
22717 - va_start(ap, pcnt);
22718 - str = (char*)va_arg(ap,unsigned);
22720 - for (i=0; i!=pcnt; i++) {
22721 - HOOK_DATA_BYTE(8+i) = str[i];
22723 - HOOK_DATA_BYTE(8+i) = 0; /* null byte */
22726 - va_start(ap, pcnt);
22727 - for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned);
22731 - // read from mem to make sure data has propagated to memory before trigging
22732 - *((volatile unsigned*) HOOK_MEM_BASE_ADDR);
22737 - // wait for call to finish
22738 - while( VHOOK_DATA(0) > 0 ) {}
22740 - // extract return value
22742 - ret = VHOOK_DATA(1);
22745 - PREEMPT_RESTORE();
22751 -hook_buf(unsigned i)
22753 - return (HOOK_DATA(i));
22756 -void print_str( const char *str ) {
22758 - for (i=1; str[i]; i++); /* find null at end of string */
22759 - hook_call(hook_print_str, i, str);
22762 -// --------------------------------------------------------------- CPU_KICK_DOG
22763 -void CPU_KICK_DOG(void) {
22764 - (void) hook_call( hook_kick_dog, 0 );
22767 -// ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT
22768 -void CPU_WATCHDOG_TIMEOUT( unsigned t ) {
22769 - (void) hook_call( hook_dog_timeout, 1, t );
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
22775 -// $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $
22777 -// Call simulator hook functions
22782 -int hook_call( unsigned id, unsigned pcnt, ...);
22785 - hook_debug_on = 1,
22787 - hook_stop_sim_ok,
22788 - hook_stop_sim_fail,
22789 - hook_alloc_shared,
22791 - hook_free_shared,
22792 - hook_file2shared,
22794 - hook_print_params,
22798 - hook_dog_timeout,
22804 - hook_cmp_offset_shared,
22805 - hook_fill_random_shared,
22806 - hook_alloc_random_data,
22807 - hook_calloc_random_data,
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
22821 # Makefile for Etrax-specific library files..
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
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
22832 .globl csum_partial
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
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
22856 subq 10*4,$r11 ; update length for the first loop
22860 ;; do a movem checksum
22862 _mloop: movem [$r10+],$r9 ; read 10 longwords
22864 ;; perform dword checksumming on the 10 longwords
22872 ;; fold the carry into the checksum, to avoid having to loop the carry
22873 ;; back into the top
22877 - addc 0,$r12 ; do it again, since we might have generated a carry
22881 @@ -68,34 +67,30 @@
22883 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
22884 ;; r9 and r13 can be used as temporaries.
22887 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
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
22906 ;; checksum the rest of the words
22912 _wloop: subq 2,$r11
22914 addu.w [$r10+],$r12
22921 ;; see if we have one odd byte more
22929 ;; copy and checksum the last byte
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
22936 * Copyright (c) 1998, 2001, 2003 Axis Communications AB
22938 * Authors: Bjorn Wesen
22941 * csum_partial_copy_nocheck(const char *src, char *dst,
22942 * int len, unsigned int sum)
22945 .globl csum_partial_copy_nocheck
22946 -csum_partial_copy_nocheck:
22948 +csum_partial_copy_nocheck:
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
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
22971 subq 10*4,$r12 ; update length for the first loop
22975 ;; do a movem copy and checksum
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
22982 ;; perform dword checksumming on the 10 longwords
22990 ;; fold the carry into the checksum, to avoid having to loop the carry
22991 ;; back into the top
22995 - addc 0,$r13 ; do it again, since we might have generated a carry
22999 @@ -74,34 +73,30 @@
23001 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
23002 ;; r9 can be used as temporary.
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
23011 - and.d 0xffff,$r13
23021 ;; copy and checksum the rest of the words
23027 2: ;; A failing userspace access for the read below will have this as PC.
23028 _wloop: move.w [$r10+],$r9
23039 ;; see if we have one odd byte more
23041 @@ -110,7 +105,7 @@
23047 ;; copy and checksum the last byte
23048 3: ;; A failing userspace access for the read below will have this as PC.
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
23055 + * Precise Delay Loops for ETRAX FS
23057 + * Copyright (C) 2006 Axis Communications AB.
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>
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
23075 +void cris_delay10ns(u32 n10ns)
23077 + u32 t0 = REG_RD(timer, regi_timer, r_time);
23078 + while (REG_RD(timer, regi_timer, r_time) - t0 < n10ns)
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
23086 -/* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $
23088 +/* $Id: dram_init.S,v 1.9 2006/11/28 10:06:19 ricardw Exp $
23090 * DRAM/SDRAM initialization - alter with care
23091 * This file is intended to be included from other assembler files
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
23098 * Copyright (C) 2000-2003 Axis Communications AB
23100 - * Authors: Mikael Starvik (starvik@axis.com)
23101 + * Authors: Mikael Starvik (starvik@axis.com)
23104 /* Just to be certain the config file is included, we include it here
23105 @@ -18,13 +18,13 @@
23107 #include <asm/arch/hwregs/asm/reg_map_asm.h>
23108 #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
23110 - ;; WARNING! The registers r8 and r9 are used as parameters carrying
23111 - ;; information from the decompressor (if the kernel was compressed).
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.
23117 ; Refer to BIF MDS for a description of SDRAM initialization
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
23124 move.d CONFIG_ETRAX_SDRAM_GRP1_CONFIG, $r1
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
23133 move.d CONFIG_ETRAX_SDRAM_COMMAND, $r2
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
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]
23158 + move.d 10000, $r2
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
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
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
23191 ; Initialization finished
23192 ba _sdram_commands_end
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
23205 - * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $
23207 + * $Id: hw_settings.S,v 1.5 2006/10/13 12:43:15 starvik Exp $
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.
23213 * Copyright (C) 2001 Axis Communications AB
23215 - * Authors: Mikael Starvik (starvik@axis.com)
23216 + * Authors: Mikael Starvik (starvik@axis.com)
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>
23224 .ascii "HW_PARAM_MAGIC" ; Magic number
23225 .dword 0xc0004000 ; Kernel start address
23228 #ifdef CONFIG_ETRAX_DEBUG_PORT0
23231 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
23233 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
23237 .dword 4 ; No debug
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
23252 register char *dst __asm__ ("r13") = pdst;
23255 /* This is NONPORTABLE, but since this whole routine is */
23256 /* grossly nonportable that doesn't matter. */
23258 @@ -156,7 +156,7 @@
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. */
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
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.
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.
23292 @@ -29,14 +31,16 @@
23293 #include <asm/arch/hwregs/asm/config_defs_asm.h>
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
23304 -#define PAGE_SIZE 512
23305 +#define PAGE_SIZE_ADDRESSES 512
23308 +;; Block size for erase
23309 #define ERASE_BLOCK 16384
23310 +#define PAGE_SIZE_BYTES 512
23312 ;; GPIO pins connected to NAND flash
23315 #define NAND_WR_ADDR 0x94000000
23317 #define READ_CMD 0x00
23318 +#define RESET_CMD 0xFF
23320 ;; Readability macros
23323 REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
23324 REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
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)
23330 ;;----------------------------------------------------------------------------
23331 ;; Macros to set/clear GPIO bits
23333 @@ -71,16 +80,41 @@
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
23344 +;; move.d [$r2], $r9 ; read back to flush pipeline
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
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
23365 +;;----------------------------------------------------------------------------
23367 +;; x = delay = 10*x + 20 ns, e.g. DELAY 25 => 270ns delay, max 63 (650 ns)
23369 +;; r is temp reg used
23370 +;; Macro currently not used, save for a rainy day.
23374 + addq (\x),\r ; addq zero-extends its argument
23379 +;;----------------------------------------------------------------------------
23382 ;; copy_nand_to_ram
23384 ;; r10 - destination
23385 ;; r11 - source offset
23387 - ;; r13 - Address to jump to after completion
23388 ;; Note : r10-r12 are clobbered on return
23390 ;; r0 - NAND_RD_ADDR
23391 @@ -96,83 +129,99 @@
23392 ;; r2 - reg_gio_rw_pa_dout
23393 ;; r3 - reg_gio_r_pa_din
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
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
23414 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23415 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23419 +#if INTERFACE_SETUP
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]
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]
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
23443 - move.d $r4, [$r8]
23444 + move.d $r4, [$r5]
23446 + move.d [$r2], $r9 ; fetch PA DOUT to shadow register
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)
23453 1: ;; Copy one page
23457 moveq READ_CMD, $r4
23465 - clear.w [$r1] ; Column address = 0
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
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)
23481 - move.b $r4, [$r1] ; Row adddress
23486 + move.b $r4, [$r1] ; Row address byte #3 (5 cyc) or #2 (4 cyc)
23492 2: move.d [$r3], $r4
23495 - movu.w PAGE_SIZE, $r5
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
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
23512 move.b $r4, [$r10+]
23513 - subu.w PAGE_SIZE, $r12
23516 - addu.w PAGE_SIZE, $r11
23517 + subu.w PAGE_SIZE_BYTES, $r12
23519 + addu.w PAGE_SIZE_ADDRESSES, $r11
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.
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
23537 ;; Core of the spinlock implementation
23539 -;; Copyright (C) 2004 Axis Communications AB.
23540 +;; Copyright (C) 2004 Axis Communications AB.
23542 -;; Author: Mikael Starvik
23544 +;; Author: Mikael Starvik
23547 .global cris_spin_lock
23548 .global cris_spin_trylock
23565 @@ -24,10 +24,10 @@
23569 -1: move.d [$r10], $r11
23570 +1: move.b [$r10], $r11
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
23583 register char *dst __asm__ ("r13") = pdst;
23584 register const char *src __asm__ ("r11") = psrc;
23585 register int n __asm__ ("r12") = pn;
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\
23597 - /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
23598 + /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
23599 /* Inputs */ : "0" (dst), "1" (src), "2" (n));
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. */
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;
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.
23624 - per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
23625 + per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
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) |
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);
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 @@
23649 SPEC_REG_WR(SPEC_REG_PID, 0);
23653 * The MMU has been enabled ever since head.S but just to make it
23654 * totally obvious enable it here as well.
23656 @@ -133,7 +133,7 @@
23657 SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
23665 @@ -160,13 +160,13 @@
23666 for (i = 1; i < MAX_NR_ZONES; i++)
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.
23677 free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
23680 mem_map = contig_page_data.node_mem_map;
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
23687 static int initiated = 0;
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);
23695 struct intmem_allocation* allocation;
23696 struct intmem_allocation* tmp;
23701 crisv32_intmem_init();
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);
23718 allocation->status = STATUS_ALLOCATED;
23719 allocation->size = size;
23720 ret = (void*)((int)intmem_virtual + allocation->offset);
23723 - preempt_enable();
23724 + preempt_enable();
23728 @@ -96,22 +96,22 @@
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);
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);
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);
23757 @@ -125,13 +125,13 @@
23759 void* crisv32_intmem_phys_to_virt(unsigned long addr)
23761 - return (void*)(addr - MEM_INTMEM_START+
23762 + return (void*)(addr - MEM_INTMEM_START+
23763 (unsigned long)intmem_virtual);
23766 unsigned long crisv32_intmem_virt_to_phys(void* addr)
23768 - return (unsigned long)((unsigned long )addr -
23769 + return (unsigned long)((unsigned long )addr -
23770 (unsigned long)intmem_virtual + MEM_INTMEM_START);
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
23777 +; WARNING : The refill handler has been modified, see below !!!
23780 * Copyright (C) 2003 Axis Communications AB
23784 #include <asm/page.h>
23785 #include <asm/pgtable.h>
23788 ; Save all register. Must save in same order as struct pt_regs.
23791 @@ -29,11 +31,11 @@
23795 - move.d $r10, [$sp]
23796 + move.d $r10, [$sp]
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
23806 orq \ex << 1, $r13 ; execute?
23807 move $s3, $r10 ; rw_mm_cause
23808 and.d ~8191, $r10 ; Get faulting page start address
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
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.
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
23837 .macro MMU_REFILL_HANDLER handler, mmu
23839 +1: .dword 0 ; refill_count
23840 + ; == 0 <=> last_refill_cause is invalid
23841 +2: .dword 0 ; last_refill_cause
23846 @@ -76,40 +91,88 @@
23848 move \mmu, $srs ; Select MMU support register bank
23851 - move.d $r0, [$sp]
23854 + move.d 1b, $acr ; Point to refill_count
23857 + test.d [$acr] ; refill_count == 0 ?
23858 + beq 5f ; yes, last_refill_cause is invalid
23861 + ; last_refill_cause is valid, investigate cause
23862 + addq 4, $r1 ; Point to last_refill_cause
23863 + move $s3, $r0 ; Get rw_mm_cause
23864 + move.d [$r1], $r2 ; Get last_refill_cause
23865 + cmp.d $r0, $r2 ; rw_mm_cause == last_refill_cause ?
23866 + beq 6f ; yes, increment count
23869 + ; rw_mm_cause != last_refill_cause
23870 + move.d $r2, [$acr] ; refill_count = 1
23871 + move.d $r0, [$r1] ; last_refill_cause = rw_mm_cause
23873 +3: ; Probably not in a loop, continue normal processing
23875 move $s7, $acr ; PGD
23877 move.d per_cpu__current_pgd, $acr ; PGD
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
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
23895 - move.d [$sp+], $r0 ; Pop r0 in delayslot
23897 + movem [$sp], $r2 ; Restore r0-r2 in delay slot
23903 move.d [$sp+], $acr
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.
23912 +5: ; last_refill_cause is invalid
23914 + addq 4, $r1 ; Point to last_refill_cause
23915 + move.d $r2, [$acr] ; refill_count = 1
23916 + move $s3, $r0 ; Get rw_mm_cause
23917 + ba 3b ; Continue normal processing
23918 + move.d $r0,[$r1] ; last_refill_cause = rw_mm_cause
23920 +6: ; rw_mm_cause == last_refill_cause
23921 + move.d [$acr], $r2 ; Get refill_count
23922 + cmpq 4, $r2 ; refill_count > 4 ?
23924 + addq 1, $r2 ; refill_count++
23925 + ba 3b ; Continue normal processing
23926 + move.d $r2, [$acr]
23928 +7: ; refill_count > 4, error
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
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.
23943 move.d [$sp+], $acr
23946 @@ -128,7 +191,7 @@
23952 ; This is the MMU bus fault handlers.
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
23959 * Low level TLB handling.
23961 * Copyright (C) 2000-2003, Axis Communications AB.
23964 * Authors: Bjorn Wesen <bjornw@axis.com>
23965 * Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
23969 __flush_tlb_mm(struct mm_struct *mm)
23974 unsigned long flags;
23975 unsigned long page_id;
23978 if (page_id == NO_CONTEXT)
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);
23991 /* Get the page_id */
23992 SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
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,
23998 - | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
24000 + | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
24003 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24004 @@ -135,7 +135,7 @@
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);
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;
24024 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24027 @@ -178,33 +178,35 @@
24028 static DEFINE_SPINLOCK(mmu_context_lock);
24030 /* Called in schedule() just before actually doing the switch_to. */
24033 switch_mm(struct mm_struct *prev, struct mm_struct *next,
24034 struct task_struct *tsk)
24036 - int cpu = smp_processor_id();
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);
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.
24049 - per_cpu(current_pgd, cpu) = next->pgd;
24051 - /* Switch context in the MMU. */
24052 - if (tsk && task_thread_info(tsk))
24054 - SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24058 - SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
24061 + if (prev != next) {
24062 + int cpu = smp_processor_id();
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);
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.
24075 + per_cpu(current_pgd, cpu) = next->pgd;
24077 + /* Switch context in the MMU. */
24078 + if (tsk && task_thread_info(tsk))
24080 + SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24084 + SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
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
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.
24098 + * the kernel has booted.
24101 #include <asm-generic/vmlinux.lds.h>
24104 jiffies = jiffies_64;
24108 /* The boot section is only necessary until the VCS top level testbench */
24109 /* includes both flash and DRAM. */
24110 .boot : { *(.boot) }
24113 . = DRAM_VIRTUAL_BASE + 0x4000; /* See head.S and pages reserved at the start. */
24115 _text = .; /* Text and read-only data. */
24120 - _etext = . ; /* End of text section. */
24121 + _etext = . ; /* End of text section. */
24124 . = ALIGN(4); /* Exception table. */
24127 . = ALIGN(8192); /* Init code and data. */
24135 *(.initcall5.init);
24136 *(.initcall6.init);
24137 *(.initcall7.init);
24138 - __initcall_end = .;
24139 + __initcall_end = .;
24142 .con_initcall.init : {
24143 @@ -94,20 +94,20 @@
24144 __per_cpu_start = .;
24145 .data.percpu : { *(.data.percpu) }
24150 __initramfs_start = .;
24152 __initramfs_end = .;
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.
24165 __vmlinux_end = .; /* Last address of the physical file. */
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
24172 #include <linux/kernel.h>
24173 #include <linux/string.h>
24174 #include <linux/tty.h>
24177 #include <asm/semaphore.h>
24178 #include <asm/processor.h>
24179 #include <asm/uaccess.h>
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);
24187 /* Platform dependent support */
24189 EXPORT_SYMBOL(get_cmos_time);
24190 EXPORT_SYMBOL(loops_per_usec);
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);
24206 /* Math functions */
24207 EXPORT_SYMBOL(__Udiv);
24209 EXPORT_SYMBOL(__ashldi3);
24210 EXPORT_SYMBOL(__ashrdi3);
24211 EXPORT_SYMBOL(__lshrdi3);
24212 +EXPORT_SYMBOL(__negdi2);
24214 /* Memory functions */
24215 EXPORT_SYMBOL(__ioremap);
24217 EXPORT_SYMBOL(del_fast_timer);
24218 EXPORT_SYMBOL(schedule_usleep);
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)
24229 + struct pt_regs *old_regs = set_irq_regs(regs);
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);
24236 - __do_IRQ(irq, regs);
24239 + set_irq_regs(old_regs);
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
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 $
24250 * linux/arch/cris/kernel/process.c
24253 * Authors: Bjorn Wesen (bjornw@axis.com)
24255 * $Log: process.c,v $
24256 + * Revision 1.26 2006/06/25 15:00:10 starvik
24257 + * Merge of Linux 2.6.17
24259 + * Revision 1.25 2006/03/22 09:56:56 starvik
24260 + * Merge of Linux 2.6.16
24262 + * Revision 1.24 2006/01/04 06:09:48 starvik
24263 + * Merge of Linux 2.6.15
24265 + * Revision 1.23 2005/08/29 07:32:19 starvik
24266 + * Merge of 2.6.13
24268 + * Revision 1.22 2005/08/18 08:33:18 starvik
24269 + * Corrected signature of machine_restart
24271 * Revision 1.21 2005/03/04 08:16:17 starvik
24272 * Merge of Linux 2.6.11.
24274 @@ -195,12 +210,18 @@
24276 void (*pm_idle)(void);
24278 +extern void default_idle(void);
24280 +void (*pm_power_off)(void);
24281 +EXPORT_SYMBOL(pm_power_off);
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)
24290 void cpu_idle (void)
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
24302 write_cris_profile(struct file *file, const char __user *buf,
24303 size_t count, loff_t *ppos)
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
24309 * Authors: Bjorn Wesen
24311 * $Log: ptrace.c,v $
24312 + * Revision 1.11 2006/03/23 14:54:02 starvik
24313 + * Corrected signal handling.
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
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);
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 )
24330 /* deal with pending signal delivery */
24331 if (thread_info_flags & _TIF_SIGPENDING)
24332 - do_signal(canrestart,oldset,regs);
24333 + do_signal(canrestart,regs);
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
24341 #include <linux/sched.h>
24342 -#include <linux/init.h>
24343 +#include <asm/semaphore.h>
24344 #include <asm/semaphore-helper.h>
24348 tsk->state = TASK_RUNNING; \
24349 remove_wait_queue(&sem->wait, &wait);
24352 void __sched __down(struct semaphore * sem)
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
24359 #include <linux/screen_info.h>
24360 #include <linux/utsname.h>
24361 #include <linux/pfn.h>
24363 +#include <linux/cpu.h>
24364 #include <asm/setup.h>
24369 extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */
24371 +static struct cpu cpu_devices[NR_CPUS];
24373 extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */
24375 /* This mainly sets up the memory area, and can be really confusing.
24376 @@ -187,4 +189,14 @@
24377 .show = show_cpuinfo,
24380 +static int __init topology_init(void)
24384 + for_each_possible_cpu(i) {
24385 + return register_cpu(&cpu_devices[i], i);
24389 +subsys_initcall(topology_init);
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
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 $
24398 * linux/arch/cris/kernel/sys_cris.c
24400 @@ -172,3 +172,4 @@
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
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 $
24412 * linux/arch/cris/kernel/time.c
24414 @@ -172,10 +172,6 @@
24415 mon = CMOS_READ(RTC_MONTH);
24416 year = CMOS_READ(RTC_YEAR);
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);
24425 @@ -208,11 +204,11 @@
24426 cris_do_profile(struct pt_regs* regs)
24429 -#if CONFIG_SYSTEM_PROFILER
24430 +#ifdef CONFIG_SYSTEM_PROFILER
24431 cris_profile_sample(regs);
24434 -#if CONFIG_PROFILING
24435 +#ifdef CONFIG_PROFILING
24436 profile_tick(CPU_PROFILING, regs);
24439 @@ -222,10 +218,15 @@
24441 unsigned long long sched_clock(void)
24443 - return (unsigned long long)jiffies * (1000000000 / HZ);
24444 + unsigned long long ns;
24447 + ns *= 1000000000 / HZ;
24448 + ns += get_ns_in_jiffie();
24454 __init init_udelay(void)
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
24461 -/* $Id: traps.c,v 1.11 2005/01/24 16:03:19 orjanf Exp $
24464 * linux/arch/cris/traps.c
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
24472 - * Copyright (C) 2000-2002 Axis Communications AB
24474 + * Copyright (C) 2000-2006 Axis Communications AB
24476 * Authors: Bjorn Wesen
24477 - * Hans-Peter Nilsson
24478 + * Hans-Peter Nilsson
24482 #include <linux/init.h>
24483 #include <linux/module.h>
24485 #include <asm/pgtable.h>
24486 #include <asm/uaccess.h>
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);
24493 +#ifdef CONFIG_DEBUG_BUGVERBOSE
24494 +extern void handle_BUG(struct pt_regs *regs);
24496 +#define handle_BUG(regs)
24499 static int kstack_depth_to_print = 24;
24501 -extern int raw_printk(const char *fmt, ...);
24502 +void (*nmi_handler)(struct pt_regs*);
24504 -void show_trace(unsigned long * stack)
24506 +show_trace(unsigned long *stack)
24508 unsigned long addr, module_start, module_end;
24509 extern char _stext, _etext;
24512 - raw_printk("\nCall Trace: ");
24513 + printk("\nCall Trace: ");
24516 - module_start = VMALLOC_START;
24517 - module_end = VMALLOC_END;
24519 + module_start = VMALLOC_START;
24520 + module_end = VMALLOC_END;
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);
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.
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);
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.
24560 + if (((addr >= (unsigned long)&_stext) &&
24561 + (addr <= (unsigned long)&_etext)) ||
24562 + ((addr >= module_start) && (addr <= module_end))) {
24563 + if (i && ((i % 8) == 0))
24565 + printk("[<%08lx>] ", addr);
24572 @@ -78,109 +90,150 @@
24573 * with the ksymoops maintainer.
24578 show_stack(struct task_struct *task, unsigned long *sp)
24580 - unsigned long *stack, addr;
24582 + unsigned long *stack, addr;
24586 * debugging aid: "show_stack(NULL);" prints a
24591 + if (sp == NULL) {
24593 sp = (unsigned long*)task->thread.ksp;
24595 sp = (unsigned long*)rdsp();
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)
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)
24612 + if (i && ((i % 8) == 0))
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);
24623 - raw_printk("%08lx ", addr);
24625 + printk("%08lx ", addr);
24630 -static void (*nmi_handler)(struct pt_regs*);
24631 -extern void arch_enable_nmi(void);
24633 +/* displays a short stack trace */
24635 -void set_nmi_handler(void (*handler)(struct pt_regs*))
24639 - nmi_handler = handler;
24640 - arch_enable_nmi();
24641 + unsigned long *sp = (unsigned long *)rdusp();
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]);
24651 -void handle_nmi(struct pt_regs* regs)
24656 - nmi_handler(regs);
24657 + show_stack(NULL, NULL);
24660 +EXPORT_SYMBOL(dump_stack);
24663 +set_nmi_handler(void (*handler)(struct pt_regs*))
24665 + nmi_handler = handler;
24666 + arch_enable_nmi();
24669 #ifdef CONFIG_DEBUG_NMI_OOPS
24670 -void oops_nmi_handler(struct pt_regs* regs)
24672 +oops_nmi_handler(struct pt_regs* regs)
24675 - raw_printk("NMI!\n");
24676 - show_registers(regs);
24678 + oops_in_progress = 1;
24679 + printk("NMI!\n");
24680 + show_registers(regs);
24681 + oops_in_progress = 0;
24685 -__init oops_nmi_register(void)
24687 +oops_nmi_register(void)
24689 - set_nmi_handler(oops_nmi_handler);
24691 + set_nmi_handler(oops_nmi_handler);
24695 __initcall(oops_nmi_register);
24700 -/* displays a short stack trace */
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.
24710 +watchdog_bite_hook(struct pt_regs *regs)
24712 - unsigned long *sp = (unsigned long *)rdusp();
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]);
24719 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24720 + local_irq_disable();
24722 + show_registers(regs);
24725 + ; /* Do nothing. */
24727 + show_registers(regs);
24731 -void dump_stack(void)
24732 +/* This is normally the Oops function. */
24734 +die_if_kernel(const char *str, struct pt_regs *regs, long err)
24736 - show_stack(NULL, NULL);
24738 + if (user_mode(regs))
24741 -EXPORT_SYMBOL(dump_stack);
24742 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
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.
24754 - /* Nothing needs to be done */
24755 + handle_BUG(regs);
24757 + printk("%s: %04lx\n", str, err & 0xffff);
24759 + show_registers(regs);
24761 + oops_in_progress = 0;
24763 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24764 + reset_watchdog();
24766 + do_exit(SIGSEGV);
24769 -void spinning_cpu(void* addr)
24773 - raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr);
24775 + /* Nothing needs to be done */
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
24782 * linux/arch/cris/mm/fault.c
24784 - * Copyright (C) 2000, 2001 Axis Communications AB
24785 + * Copyright (C) 2000-2006 Axis Communications AB
24787 + * Authors: Bjorn Wesen
24789 - * Authors: Bjorn Wesen
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.
24795 + * Revision 1.24 2006/09/29 10:58:09 orjanf
24796 + * * Added user mode SIGSEGV printk.
24798 + * Revision 1.23 2006/06/20 07:42:56 pkj
24799 + * Removed an unnecessary reference to raw_printk().
24801 + * Revision 1.22 2005/08/29 07:32:20 starvik
24802 + * Merge of 2.6.13
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.
24808 * Revision 1.20 2005/03/04 08:16:18 starvik
24809 * Merge of Linux 2.6.11.
24811 @@ -135,7 +151,6 @@
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, ...);
24817 /* debug of low-level TLB reload */
24819 @@ -164,8 +179,8 @@
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
24828 * If this routine detects a bad access, it returns 1, otherwise it
24830 @@ -180,9 +195,9 @@
24831 struct vm_area_struct * vma;
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));
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));
24852 @@ -325,7 +342,7 @@
24854 /* Are we prepared to handle this kernel fault?
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.
24865 - if ((unsigned long) (address) < PAGE_SIZE)
24866 - raw_printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
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");
24875 + printk(KERN_ALERT "Unable to handle kernel access");
24876 + printk(" at virtual address %08lx\n",address);
24878 - die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24879 + die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24880 + oops_in_progress = 0;
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.
24891 + * with pgd_present and set_pgd here.
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
24900 * Authors: Bjorn Wesen (bjornw@axis.com)
24903 + * Revision 1.14 2006/06/25 15:00:10 starvik
24904 + * Merge of Linux 2.6.17
24906 + * Revision 1.13 2005/06/20 05:30:00 starvik
24907 + * Remove unnecessary diff to kernel.org tree
24909 + * Revision 1.12 2004/08/16 12:37:24 starvik
24910 + * Merge of Linux 2.6.8
24912 * Revision 1.11 2004/05/28 09:28:56 starvik
24913 * Calculation of loops_per_usec moved because initalization order has changed